diff --git a/docs/config.json b/docs/config.json index cc9f0c9a03b83..7aff183fc0dcf 100644 --- a/docs/config.json +++ b/docs/config.json @@ -1550,6 +1550,10 @@ "title": "Linux Server", "slug": "/machine-id/deployment/linux/" }, + { + "title": "Linux Server (TPM)", + "slug": "/machine-id/deployment/linux-tpm/" + }, { "title": "Kubernetes", "slug": "/machine-id/deployment/kubernetes/" diff --git a/docs/cspell.json b/docs/cspell.json index 5d40a1c279a33..ebafcffeef288 100644 --- a/docs/cspell.json +++ b/docs/cspell.json @@ -37,6 +37,7 @@ "CTAP", "CXXXXXXXXX", "Callouts", + "cryptoprocessor", "Cgajq", "DBSIZE", "DEBU", @@ -682,6 +683,7 @@ "pidof", "pkill", "pkinit", + "PKIX", "plugindata", "portforward", "postgresqlselfhosted", diff --git a/docs/pages/includes/provision-token/tpm-spec.mdx b/docs/pages/includes/provision-token/tpm-spec.mdx new file mode 100644 index 0000000000000..5ba8a6b021061 --- /dev/null +++ b/docs/pages/includes/provision-token/tpm-spec.mdx @@ -0,0 +1,51 @@ +```yaml +kind: token +version: v2 +metadata: + # name identifies the token. When configuring a bot or node to join using this + # token, this name should be specified. + name: tpm-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: tpm-demo + + # 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. + # + # When unspecified, TPMs will be allowed to join with either an EKCert or an + # EKPubHash. + 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-build-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: "d4b4example6fabfc568d74f2example6c35a05337d7af9a6example6c891aa6" + # ek_certificate_serial is the serial number of the EKCert in hexadecimal + # with colon separated nibbles. This value will not be checked when a TPM + # does not have an EKCert configured. + ek_certificate_serial: "01:23:45:67:89:ex:am:pl:e0:23:45:67:89:ab:cd:ef" +``` \ No newline at end of file diff --git a/docs/pages/includes/tpm-joining-background.mdx b/docs/pages/includes/tpm-joining-background.mdx new file mode 100644 index 0000000000000..1291a403b3b94 --- /dev/null +++ b/docs/pages/includes/tpm-joining-background.mdx @@ -0,0 +1,30 @@ +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. + + +The `tpm` join method is currently not compatible with FIPS 140-2. + \ No newline at end of file diff --git a/docs/pages/machine-id/deployment.mdx b/docs/pages/machine-id/deployment.mdx index a9acf98671cf2..f1724bd92970e 100644 --- a/docs/pages/machine-id/deployment.mdx +++ b/docs/pages/machine-id/deployment.mdx @@ -52,23 +52,24 @@ and [Architecture](./architecture.mdx) to plan your deployment. Read the following guides for how to deploy Machine ID on your cloud platform or on-prem infrastructure. -|Platform|Installation method|Join method| -|---|---|---| -|[Linux](./deployment/linux.mdx)|Package manager or TAR archive|Static join token| -|[GCP](./deployment/gcp.mdx)|Package manager, TAR archive, or Kubernetes pod|Identity document signed by GCP| -|[AWS](./deployment/aws.mdx)|Package manager, TAR archive, or Kubernetes pod|Identity document signed by AWS| -|[Azure](./deployment/azure.mdx)|Package manager or TAR archive|Identity document signed by Azure| -|[Kubernetes](./deployment/kubernetes.mdx)|Kubernetes pod|Identity document signed by your Kubernetes cluster| +| Platform | Installation method | Join method | +|-------------------------------------------|-------------------------------------------------|-----------------------------------------------------| +| [Linux](./deployment/linux.mdx) | Package manager or TAR archive | Static join token | +| [Linux (TPM)](./deployment/linux-tpm.mdx) | Package manager or TAR archive | Attestation from TPM 2.0 | +| [GCP](./deployment/gcp.mdx) | Package manager, TAR archive, or Kubernetes pod | Identity document signed by GCP | +| [AWS](./deployment/aws.mdx) | Package manager, TAR archive, or Kubernetes pod | Identity document signed by AWS | +| [Azure](./deployment/azure.mdx) | Package manager or TAR archive | Identity document signed by Azure | +| [Kubernetes](./deployment/kubernetes.mdx) | Kubernetes pod | Identity document signed by your Kubernetes cluster | ### CI/CD Read the following guides for how to deploy Machine ID on a continuous integration and continuous deployment platform -|Platform|Installation method|Join method| -|---|---|---| -|[CircleCI](./deployment/circleci.mdx)|TAR archive|CircleCI-signed identity document| -|[GitLab](./deployment/gitlab.mdx)|TAR archive|GitLab-signed identity document| -|[GitHub Actions](./deployment/github-actions.mdx)|Teleport job available through the GitHub Actions marketplace|GitHub-signed identity document.| -|[Jenkins](./deployment/jenkins.mdx)|Package manager or TAR archive|Static join token| -|[Spacelift](./deployment/spacelift.mdx)|Docker Image|Spacelift-signed identity document| +| Platform | Installation method | Join method | +|---------------------------------------------------|---------------------------------------------------------------|------------------------------------| +| [CircleCI](./deployment/circleci.mdx) | TAR archive | CircleCI-signed identity document | +| [GitLab](./deployment/gitlab.mdx) | TAR archive | GitLab-signed identity document | +| [GitHub Actions](./deployment/github-actions.mdx) | Teleport job available through the GitHub Actions marketplace | GitHub-signed identity document. | +| [Jenkins](./deployment/jenkins.mdx) | Package manager or TAR archive | Static join token | +| [Spacelift](./deployment/spacelift.mdx) | Docker Image | Spacelift-signed identity document | diff --git a/docs/pages/machine-id/deployment/linux-tpm.mdx b/docs/pages/machine-id/deployment/linux-tpm.mdx new file mode 100644 index 0000000000000..82db23016d99b --- /dev/null +++ b/docs/pages/machine-id/deployment/linux-tpm.mdx @@ -0,0 +1,208 @@ +--- +title: Deploying Machine ID on Linux (TPM) +description: How to install and configure Machine ID on a Linux host and use a TPM 2.0 for authentication +--- + +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 + +(!docs/pages/includes/tpm-joining-background.mdx!) + +## Prerequisites + +(!docs/pages/includes/edition-prereqs-tabs.mdx!) + +- (!docs/pages/includes/tctl.mdx!) +- 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: + +(!docs/pages/includes/install-linux.mdx!) + +### 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]( +https://github.com/tpm2-software/tpm2-tss/blob/ede63dd1ac1f0a46029d457304edcac2162bfab8/dist/tpm-udev.rules#L4). + +## Step 2/5. Create a Bot + +(!docs/pages/includes/machine-id/create-a-bot.mdx!) + +## 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`: + +```code +$ tbot tpm identify +TPM Information +EKPub Hash: 6c5aada1c5abee6d869369a0example2fd2beb41c850d3f0227f029c4fffc4ba +EKCert Detected: true +EKCert Serial: 5e:cd:5f:8e +``` + +Take the long hexadecimal string after `EKPub Hash` and assign it to +. 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`: + +```yaml +kind: token +version: v2 +metadata: + # name identifies the token. Try to ensure that this is descriptive. + name: +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: + + # 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: "" +``` + +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`: + +```code +$ tctl create -f bot-token.yaml +``` + +## Step 4/5. Configure `tbot` + +Create `/etc/tbot.yaml`: + +```yaml +version: v2 +proxy_server: example.teleport.sh:443 +onboarding: + join_method: tpm + 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: + +```code +# 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 + +(!docs/pages/includes/machine-id/daemon.mdx!) + +## Step 5/5. Configure outputs + +(!docs/pages/includes/machine-id/configure-outputs.mdx!) + +## Next steps + +- Follow the [access guides](../access-guides.mdx) to finish configuring `tbot` for +your environment. +- Read the [TPM joining reference](../../reference/join-methods.mdx#trusted-platform-module-tpm) +to learn more about `tpm`joining. +- Read the [configuration reference](../reference/configuration.mdx) to explore +all the available configuration options. +- [More information about `TELEPORT_ANONYMOUS_TELEMETRY`.](../reference/telemetry.mdx) \ No newline at end of file diff --git a/docs/pages/reference/cli/tbot.mdx b/docs/pages/reference/cli/tbot.mdx index 3c0314a32fc8b..104b60e460b2e 100644 --- a/docs/pages/reference/cli/tbot.mdx +++ b/docs/pages/reference/cli/tbot.mdx @@ -17,6 +17,7 @@ The primary commands for `tbot` are as follows: | `tbot init` | Initialize a certificate destination directory for writes from a separate bot user, configuring either file or POSIX ACL permissions. | | `tbot db` | Connects to databases using native clients and queries database information. Functions as a wrapper for `tsh`, and requires `tsh` installation. | | `tbot proxy` | Allows for access to Teleport resources on a cluster using TLS Routing. Functions as a wrapper for `tsh`, and requires `tsh` installation. | +| `tbot tpm identify` | Output identifying information related to the TPM (Trusted Platform Module) detected on the system. | ## tbot db @@ -189,6 +190,7 @@ using database proxies. | `--renewal-interval` | Interval at which short-lived certificates are renewed; must be less than the certificate TTL. | | `--join-method` | Method to use to join the cluster. Can be `token` or `iam`. | | `--oneshot` | If set, quit after the first renewal. | + ## tbot start Starts the Machine ID client `tbot`, fetching and writing certificates to disk at a set interval. @@ -241,3 +243,13 @@ $ tbot start \ +## tbot tpm identify + +Output identifying information related to the TPM (Trusted Platform Module) +detected on the system. + +### Flags + +| Flag | Description | +|----------------------|------------------------------------| +| `-d/--debug` | Enable verbose logging to stderr. | \ No newline at end of file diff --git a/docs/pages/reference/join-methods.mdx b/docs/pages/reference/join-methods.mdx index 5399b05d814a7..003c5ca065d28 100644 --- a/docs/pages/reference/join-methods.mdx +++ b/docs/pages/reference/join-methods.mdx @@ -121,6 +121,7 @@ Delegated join methods are: - [`circleci`](#circleci-circleci) - [`gitlab`](#gitlab-gitlab) - [`kubernetes`](#kubernetes-kubernetes) +- [`tpm`](#trusted-platform-module-tpm) ### Renewable vs non-renewable @@ -152,6 +153,7 @@ Non-renewable join methods are: - [`circleci`](#circleci-circleci) - [`gitlab`](#gitlab-gitlab) - [`kubernetes`](#kubernetes-kubernetes) +- [`tpm`](#trusted-platform-module-tpm) ## Token resource reference @@ -413,3 +415,13 @@ to contain the new Kubernetes singing keys (update the - [Deploying Machine ID on Kubernetes](../machine-id/deployment/kubernetes.mdx) + +### Trusted Platform Module: `tpm` + +(!docs/pages/includes/tpm-joining-background.mdx!) + +(!docs/pages/includes/provision-token/tpm-spec.mdx!) + + +- [Deploying Machine ID on Linux: TPM](../machine-id/deployment/linux-tpm.mdx) + \ No newline at end of file