Skip to main content
Using Teleport with OpenSSH
Using Teleport with OpenSSH

Length: 16:04

Using Teleport with OpenSSH in agentless mode

In this guide, we will show you how to configure Teleport in agentless mode and have the OpenSSH server sshd join a Teleport cluster. Existing fleets of OpenSSH servers can be configured to accept SSH certificates dynamically issued by a Teleport CA.

Using Teleport and OpenSSH has the advantage of getting you up and running, but in the long run, we would recommend replacing sshd with teleport. teleport SSH servers have support for multiple features that are incompatible with OpenSSH:

Teleport supports OpenSSH by proxying SSH connections through the Proxy Service. When a Teleport user requests to connect to an OpenSSH node, the Proxy Service checks the user's Teleport roles.

If the RBAC checks succeed, the Proxy Service authenticates to the OpenSSH node with a dynamically generated certificate signed by a Teleport CA. This allows the Proxy Service to record and audit connections to OpenSSH nodes.

The Proxy Service prevents Teleport users from bypassing auditing by requiring a certificate signed by a Teleport CA that only the Auth Service possesses.

In this setup, the Teleport SSH Service performs RBAC checks as well as audits and records sessions on its host, which eliminates the need for connection termination when recording SSH sessions.

Note

Registering an OpenSSH node with Teleport involves copying the teleport binary onto your sshd host. The teleport binary will handle registering the node with your cluster, generating certificates, modifying your OpenSSH sshd config, and more. If copying the teleport binary onto your sshd and running it isn't an option, you can register your node manually instead.

Prerequisites

  • OpenSSH version 6.9 or above on your local machine. View your OpenSSH version with the command:

    $ ssh -V
  • A running Teleport cluster version 17.0.0-dev 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.

    Visit Installation for instructions on downloading tctl and tsh.

  • A Linux host with the OpenSSH server sshd version 7.4 or above installed, but not Teleport. The SSH port on this host must be open to traffic from the Teleport Proxy Service host.
  • 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. For example:
    $ tsh login --proxy=teleport.example.com [email protected]
    $ tctl status
    # Cluster teleport.example.com
    # Version 17.0.0-dev
    # 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.

Upgrading to v14 from legacy OpenSSH nodes

If you have previously configured OpenSSH nodes to trust a Teleport CA without registering them and you upgrade your Teleport cluster to Teleport 14, you won't be able to connect to them anymore by default. This is because open dialing to OpenSSH servers not registered with the cluster is no longer allowed in Teleport 14. To ensure that you will retain access to your OpenSSH nodes you will need to follow this guide to register every OpenSSH node with Teleport that you previously configured. This must be done before your Teleport cluster is upgraded to Teleport 14.

If you are having issues registering OpenSSH nodes or need to upgrade your Teleport cluster to Teleport 14 before registering all of your OpenSSH nodes, you can pass the TELEPORT_UNSTABLE_UNLISTED_AGENT_DIALING environment variable to your Proxy Service and set it to yes. This will allow connections to unregistered OpenSSH nodes but will be removed in Teleport v15.

Step 1/3. Configure sshd

Teleport only allows access to resources in your infrastructure via Teleport processes that that have joined the cluster.

To register the OpenSSH node, you must have a valid auth token to connect to the cluster. You can generate the token by running the following command against your Teleport Auth Service:

$ tctl tokens add --type=node --format=text
abcd123-insecure-do-not-use-this

Copy the teleport binary to your sshd host. Configure sshd and create a node resource on your cluster with the following command:

$ sudo teleport join openssh \
--address server1.example.com:22 \
--proxy-server teleport.example.com:443 \
--join-method token \
--token abcd123-insecure-do-not-use-this \
--labels env=dev

Change the command-line options to assign the following values:

  • server1.example.com:22 Set to the address and port of the node that will join your Teleport cluster.
  • teleport.example.com:443 Set to the address and port of your Teleport Proxy Service.
  • abcd123-insecure-do-not-use-this Set to the join token value.

Check that your new node is listed with tsh ls or in the Web UI. You can edit the hostname and labels with tctl edit nodes/<hostname>. If the hostname isn't unique, get the UUID from tctl nodes ls -v and edit with tctl edit nodes/<uuid>. After you've confirmed the node was registered successfully you can delete the copied teleport binary.

Step 2/3. Generate an SSH client configuration

The next step is to configure your OpenSSH client to connect to your sshd host using credentials managed by Teleport. This configuration will use your user's Teleport-issued certificate to authenticate to the sshd host. It will also authenticate the sshd host using the host certificate you generated earlier.

First, make sure you have logged in to your Teleport cluster:

$ tsh status
> Profile URL: https://teleport.example.com:443
Logged in as: myuser
Cluster: teleport.example.com
Roles: access, auditor, editor, host-certifier
Logins: ubuntu, root
Kubernetes: enabled
Valid until: 2022-05-06 22:54:01 -0400 EDT [valid for 11h53m0s]
Extensions: permit-agent-forwarding, permit-port-forwarding, permit-pty

On your local machine, run the following tsh command. This will print a configuration block that tells your SSH client to use credentials managed by Teleport to connect to hosts in your cluster.

$ tsh config > ssh_config_teleport

This command creates an SSH configuration file at a nonstandard location in order to make it easier to clean up, but you can append the output of tsh config to the default SSH config file (~/.ssh/config) if you wish.

How does the config work?

Teleport implements an SSH server that includes several subsystems, or predefined commands that are run when the server handles a connection. The Proxy Service implements a proxy subsystem that forwards SSH traffic to remote hosts and trusted clusters.

Here is a brief explanation of the configuration that tsh config generates:

# Common flags for all {{ .ClusterName }} hosts
Host *.{{ .ClusterName }} {{ .ProxyHost }}
UserKnownHostsFile "{{ .KnownHostsPath }}"
IdentityFile "{{ .IdentityFilePath }}"
CertificateFile "{{ .CertificateFilePath }}"

If the host you are sshing into belongs to your Teleport cluster (i.e., its address is a subdomain of your cluster's domain), use a Teleport-managed known hosts file, private key, and certificate that are stored in the .tsh directory.

# Flags for all {{ .ClusterName }} hosts except the proxy
Host *.{{ .ClusterName }} !{{ .ProxyHost }}
Port 3022
ProxyCommand "{{ .TSHPath }}" proxy ssh --cluster={{ .ClusterName }} --proxy={{ .ProxyHost }} %r@%h:%p

If the host that you are sshing into belongs to your Teleport cluster, the OpenSSH client will first execute a command, the ProxyCommand, that establishes an SSH connection to the Proxy Service. This command, tsh proxy ssh, requests the proxy subsystem in order to forward SSH traffic through the Proxy Service to your chosen host (including a host in a Trusted Cluster).

The tsh proxy ssh command requests the proxy subsystem through a command similar to the following, which assumes you are logging in to a node called mynode as root with a cluster called teleport.example.com:

$ /usr/bin/ssh -l root -A -o UserKnownHostsFile=/root/.tsh/known_hosts -p 11105 teleport.example.com -s proxy:mynode:[email protected]

Notice that the known_hosts file used by the command is managed by tsh. Since the sshd host's information is listed in this file, your SSH client can authenticate the host via the certificate we generated earlier.

Using PowerShell on Windows?

If using PowerShell on Windows, note that normal shell redirection may write the file with the incorrect encoding. To ensure it's written properly, try the following:

$ tsh.exe config | out-file .ssh\config -encoding utf8 -append
Dialing uppercase hostnames with OpenSSH

Routing in Teleport clusters is case-sensitive by default, but OpenSSH always lowercases hostnames. If you are using an OpenSSH client and have hosts with uppercase letters in their hostnames, you may need to set case_insensitive_routing: true in either the auth_service block of your Teleport config, or in the cluster_networking_config resource.

Multiple Clusters

If you switch between multiple Teleport Proxy Servers, you'll need to re-run tsh config for each to generate the cluster-specific configuration.

Similarly, if trusted clusters are added or removed, be sure to re-run tsh config and replace the previous configuration.

Step 3/3. Connect to your sshd host

Once you have appended the new text to your OpenSSH client configuration file, you can log in to your sshd host using the configuration we generated earlier.

First, define environment variables for the address of your Teleport cluster, the username you will use to log in to your sshd host, and the port on your sshd host you are using for SSH traffic:

# See the available logins you can use to access your sshd host
$ tsh status | grep Logins
Logins: ubuntu, root
$ USER=ubuntu
$ CLUSTER=teleport.example.com
$ PORT=22

Next, SSH in to your remote host:

$ ssh -p ${PORT?} -F ssh_config_teleport "${USER?}@${ADDR?}.${CLUSTER?}"

This name does not need to be resolvable via DNS as the connection will be routed through your Teleport Proxy Service.

Why are we overriding the port here?

By default, the OpenSSH client configuration generated by tsh config directs the Teleport Proxy Service to dial port 3022 of a node in your Teleport cluster. This works if the node's SSH Service is listening on port 3022, and means that you can connect to the Teleport SSH Service via your OpenSSH client.

When you join a Teleport node to a cluster, the node creates a reverse tunnel to the cluster's Proxy Service. When you run an ssh command to access a host in your Teleport cluster using the configuration we generated, the Teleport Proxy Service will attempt to connect to the host via this reverse tunnel and, if that fails, try directly dialing the address.

In our case, the sshd host is not running Teleport, so no reverse tunnel will exist. Instead, the Proxy Service will establish a direct connection on the host's SSH port.

Using trusted clusters?

You can log in to a host in a trusted leaf cluster by placing the name of the leaf cluster between the name of the node and the name of the root cluster:

$ ssh -F ssh_config_teleport ${USER?}@node2.leafcluster.${CLUSTER}
Note

Teleport uses OpenSSH certificates instead of keys. When you connect to a remote host, OpenSSH verifies that the address of the host is listed under the Principals section of the OpenSSH certificate. Usually, this is a fully qualified domain name, rather than an IP address.