Teleport Workload Identity with SPIFFE: Achieving Zero Trust in Modern Infrastructure
May 23
Virtual
Register Today
Teleport logoTry For Free
Fork me on GitHub

Teleport

Deploying Machine ID on Linux (TPM)

This page explains how to deploy Machine ID on a Linux host, and use the secure identify of the onboard TPM 2.0 chip for authenticating with the Teleport cluster.

The tpm join method requires a valid Teleport Enterprise license to be installed on the cluster's Auth Service.

How it works

The tpm join method is a secure way for Bots and Agents to authenticate with the Teleport Auth Service without using any shared secrets. Instead of using a hared secret, the unique identity of the host's Trusted Platform Module (TPM) and public key cryptography is used to authenticate the host.

In environments where there is no other form of identity available to machines, e.g on-prem, this is the most secure method for joining. It avoids the need to distribute a shared secret as is needed for the token join method.

A Trusted Platform Module (TPM) is a secure, physical cryptoprocessor that is installed on a host. TPMs can store cryptographic material and perform a number of cryptographic operations, without exposing the cryptographic material to the operating system. Each TPM has a unique key pair burned-in known as the Endorsement Key (EK).

Some TPMs also contain an X.509 certificate for this key pair that is signed by the manufacturer's CA. This is known as the EK Certificate (EKCert). This certificate can be used by the TPM to prove to a third-party (who trusts the manufacturer's CA) that the TPM is genuine and abides by the TPM specification.

When using the tpm join method, you must first query the TPM's public key and then create a join token that explicitly allows this public key. Even if the host operating system is reinstalled, the EK public key will not change, meaning that the TPM will still be usable to join your Teleport cluster. If you have a large number of hosts, it may make sense to use automation tooling such as ansible to query the TPMs across your fleet and then generate join tokens.

Warning

The tpm join method is currently not compatible with FIPS 140-2.

Prerequisites

  • A running Teleport cluster version 15.3.1 or above. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl admin tool and tsh client tool.

    On Teleport Enterprise, you must use the Enterprise version of tctl, which you can download from your Teleport account workspace. Otherwise, visit Installation for instructions on downloading tctl and tsh for Teleport Community Edition.

  • To check that you can connect to your Teleport cluster, sign in with tsh login, then verify that you can run tctl commands using your current credentials. tctl is supported on macOS and Linux machines. For example:
    tsh login --proxy=teleport.example.com --user=[email protected]
    tctl status

    Cluster teleport.example.com

    Version 15.3.1

    CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.
  • A Linux host that you wish to install Machine ID onto, with a TPM2.0 installed.
  • A Linux user on that host that you wish Machine ID to run as. In the guide, we will use teleport for this.

Step 1/5. Install tbot

This step is completed on the Linux host.

First, tbot needs to be installed on the VM that you wish to use Machine ID on.

Download the appropriate Teleport package for your platform:

Install Teleport on your Linux server:

  1. Assign edition to one of the following, depending on your Teleport edition:

    EditionValue
    Teleport Enterprise Cloudcloud
    Teleport Enterprise (Self-Hosted)enterprise
    Teleport Community Editionoss
  2. Get the version of Teleport to install. If you have automatic agent updates enabled in your cluster, query the latest Teleport version that is compatible with the updater:

    TELEPORT_DOMAIN=example.teleport.com
    TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

    Otherwise, get the version of your Teleport cluster:

    TELEPORT_DOMAIN=example.teleport.com
    TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/ping | jq -r '.server_version')"
  3. Install Teleport on your Linux server:

    curl https://goteleport.com/static/install.sh | bash -s ${TELEPORT_VERSION} edition

    The installation script detects the package manager on your Linux server and uses it to install Teleport binaries. To customize your installation, learn about the Teleport package repositories in the installation guide.

Granting tbot access to the TPM device

If the user that will run tbot is not root, you will also need to configure Linux to allow the user to access the TPM device.

The simplest way to solve this is to check if your distro ships with the tss group and assign it the user. If that is not possible, or you are looking for a different solution, we recommend creating udev rules similar to the ones shipped by the TPM2 Software Stack.

Step 2/5. Create a Bot

Next, you need to create a Bot. A Bot is a Teleport identity for a machine or group of machines. Like users, bots have a set of roles and traits which define what they can access.

Create bot.yaml:

kind: bot
version: v1
metadata:
  # name is a unique identifier for the Bot in the cluster.
  name: example
spec:
  # roles is a list of roles to grant to the Bot. Don't worry if you don't know
  # what roles you need to specify here, the Access Guides will walk you through
  # creating and assigning roles to the already created Bot.
  roles: []

Make sure you replace example with a unique, descriptive name for your Bot.

Use tctl to apply this file:

tctl create bot.yaml

Step 3/5. Create a tpm join token

With the Bot created, we now need to create a token. The token will be used by tbot to authenticate as the Bot to the Teleport cluster.

Determining the EKPub Hash or EKCert Serial for your TPM

First, you need to determine the characteristics of the TPM on the host that you wish to use Machine ID on. These characteristics will then be used within the allow rules of the join token to grant access to this specific host.

On the machine, run tbot tpm identify:

tbot tpm identify
TPM InformationEKPub Hash: 6c5aada1c5abee6d869369a0example2fd2beb41c850d3f0227f029c4fffc4baEKCert Detected: trueEKCert Serial: 5e:cd:5f:8e

Take the long hexadecimal string after EKPub Hash and assign it to ek-public-hash. This uniquely identifies this TPM and will be used in the join token.

Obtaining the manufacturer CA

If in the previous step, EKCert Detected was false, then you can disregard this section.

If in the previous step, EKCert Detected was true, then it is recommended to obtain the manufacturer's CA certificate. This will allow the TPM to be validated as legitimately manufactured as part of the join process.

Instructions for obtaining the EKCert CA will vary from TPM to TPM. Consult your TPM's documentation for more information or contact your supplier.

Creating the join token

Create a file named bot-token.yaml:

kind: token
version: v2
metadata:
  # name identifies the token. Try to ensure that this is descriptive.
  name: my-bot-token
spec:
  # For Machine ID and TPM joining, roles will always be "Bot" and
  # join_method will always be "tpm".
  roles: [Bot]
  join_method: tpm

  # bot_name specifies the name of the bot that this token will grant access to
  # when it is used.
  bot_name: my-bot

  # tpm specifies the TPM join method specific configuration for this token.
  tpm:
    # ekcert_allowed_cas is a list of CA certificates that will be used to
    # validate TPM EKCerts. These should be PEM wrapped.
    #
    # When specified, joining TPMs must present an EKCert signed by one of the
    # specified CAs. TPMs that do not present an EKCert will be not permitted to
    # join.
    ekcert_allowed_cas:
      - |
        -----BEGIN CERTIFICATE-----
        ... CA Certificate Data ...
        -----END CERTIFICATE-----
    # allow is a list of Rules, the presented TPM must match one allow rule to
    # be permitted to join using this token.
    allow:
        # description is a human-readable description of the rule. It has no
        # bearing on whether a TPM is allowed to join, but can be used to
        # associate a rule with a specific host (e.g the asset tag of the server
        # in which the TPM resides).
      - description: "example-server-100"
        # ek_public_hash is the SHA256 hash of the EKPub marshaled in PKIX format
        # and encoded in hexadecimal. This value will also be checked when a TPM
        # has submitted an EKCert, and the public key in the EKCert will be used
        # for this check.
        ek_public_hash: "ek-public-hash"

If your TPM includes an EKCert and you have obtained the manufacturer's CA, replace the ekcert_allowed_cas section with the PEM wrapped CA certificate. Otherwise, remove this section.

If you have multiple hosts that you wish to authenticate as the same Bot, you can add additional rules the allow list, one for each host.

Apply this to your Teleport cluster using tctl:

tctl create -f bot-token.yaml

Step 4/5. Configure tbot

Create /etc/tbot.yaml:

version: v2
proxy_server: example.teleport.sh:443
onboarding:
  join_method: tpm
  token: my-bot-token
storage:
  type: directory
  path: /var/lib/teleport/bot
# outputs will be filled in during the completion of an access guide.
outputs: []

Replace:

  • example.teleport.sh:443 with the address of your Teleport Proxy.

Prepare the storage directory

The tbot service requires a way to store its state, such as internal credentials, across restarts. This is known as the storage destination.

For this example, we will use the directory /var/lib/teleport/bot.

As this directory will store the bots sensitive credentials, it is important to protect it. To do this, you will configure the directory to only be accessible to the Linux user which tbot will run as.

Execute the following, replacing teleport with the Linux user that you will run tbot as:

Make the bot directory and assign ownership to teleport user

sudo mkdir -p /var/lib/teleport/bot
sudo chown teleport:teleport /var/lib/teleport/bot

Create a systemd service

By default, tbot will run in daemon mode. However, this must then be configured as a service within the service manager on the Linux host. The service manager will start tbot on boot and ensure it is restarted if it fails. For this guide, systemd will be demonstrated but tbot should be compatible with all common alternatives.

Create a systemd unit file /etc/systemd/system/tbot.service:

[Unit]
Description=Teleport Machine ID Service
After=network.target

[Service]
Type=simple
User=teleport
Group=teleport
Restart=on-failure
Environment="TELEPORT_ANONYMOUS_TELEMETRY=1"
ExecStart=/usr/local/bin/tbot start -c /etc/tbot.yaml
ExecReload=/bin/kill -HUP $MAINPID
PIDFile=/run/tbot.pid
LimitNOFILE=524288

[Install]
WantedBy=multi-user.target

Ensure that you replace:

  • teleport with the name of Linux user you wish to run tbot as.
  • /etc/tbot.yaml with the path to the configuration file you have created

TELEPORT_ANONYMOUS_TELEMETRY enables the submission of anonymous usage telemetry. This helps us shape the future development of tbot. You can disable this by omitting this.

Next, enable the service so that it will start on boot and then start the service:

sudo systemctl daemon-reload
sudo systemctl enable tbot
sudo systemctl start tbot

Check the service has started successfully:

sudo systemctl status tbot

Step 5/5. Configure outputs

You have now prepared the base configuration for tbot. At this point, it identifies itself to the Teleport cluster and renews its own credentials but does not output any credentials for other applications to use.

Follow one of the access guides to configure an output that meets your access needs.

Next steps