mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
375 lines
14 KiB
Plaintext
375 lines
14 KiB
Plaintext
---
|
|
title: Using Teleport with OpenSSH in agentless mode
|
|
description: This guide shows you how to set up Teleport in agentless mode to enable secure access to OpenSSH servers so you can protect systems that do not run a Teleport binary.
|
|
keywords: [openssh, teleport, agentless]
|
|
videoBanner: x0eYFUEIOrM
|
|
tags:
|
|
- how-to
|
|
- zero-trust
|
|
- infrastructure-identity
|
|
page_type: how-to
|
|
---
|
|
|
|
In this guide, you will 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:
|
|
|
|
- RBAC and resource filtering based on [dynamically updated labels](../../../zero-trust-access/rbac-get-started/labels.mdx)
|
|
- [Session recording without SSH connection termination](../../../reference/architecture/session-recording.mdx#record-at-the-proxy-service)
|
|
- [Session sharing](../../../zero-trust-access/authentication/joining-sessions.mdx)
|
|
- [Advanced session recording](../guides/bpf-session-recording.mdx)
|
|
|
|
## How it works
|
|
|
|
At a high level, Teleport supports OpenSSH servers by proxying SSH connections through the Proxy Service.
|
|
The OpenSSH server will be set up to trust connections from the Proxy Service rather than trusting direct
|
|
connections from users. This ensures that all connections to OpenSSH servers go through the
|
|
Proxy Service, where session IO and audit events can be recorded and RBAC can be enforced.
|
|
|
|
For deeper details as to how this works, you may be interested in the [Registered OpenSSH Nodes RFD](https://github.com/gravitational/teleport/blob/8ff3d34581424302182c217e4d8d3be45bf2b0b7/rfd/0098-registered-openssh-nodes.md)
|
|
Below are some key details from the RFD:
|
|
- The Proxy Service is uniquely able to request certificates signed by the Auth Service with the Teleport OpenSSH CA on behalf of users, and the OpenSSH server is set up to only trust certificates signed by this CA. Therefore, in order to connect to an OpenSSH server, a user must connect through the Proxy Service to request and use an OpenSSH certificate.
|
|
- Before connecting the user to the OpenSSH server, the Proxy Service performs RBAC checks to see if the user should be allowed to access it.
|
|
- In order to record the session and its audit events, the Proxy Service terminates (decrypts) the client SSH connection, and establishes its own connection to the OpenSSH server. It then acts as a pipe between the two connections, recording events and IO as it proceeds.
|
|
- See [Recording Proxy Mode](../../../reference/architecture/session-recording.mdx#record-at-the-proxy-service) for more details.
|
|
|
|
<Admonition
|
|
type="tip"
|
|
title="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](openssh-manual-install.mdx).
|
|
|
|
</Admonition>
|
|
|
|
## Prerequisites
|
|
|
|
- OpenSSH version 6.9 or above on your local machine. View your OpenSSH version
|
|
with the command:
|
|
|
|
```code
|
|
$ ssh -V
|
|
```
|
|
|
|
(!docs/pages/includes/edition-prereqs-tabs.mdx!)
|
|
|
|
- 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.
|
|
- (!docs/pages/includes/tctl.mdx!)
|
|
|
|
## Step 1/3. Configure `sshd`
|
|
|
|
Teleport only allows access to resources in your infrastructure via Teleport
|
|
processes 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:
|
|
|
|
```code
|
|
$ tctl tokens add --type=node --format=text
|
|
(=presets.tokens.first=)
|
|
```
|
|
|
|
Copy the `teleport` binary to your `sshd` host. Configure `sshd` and create a node
|
|
resource on your cluster with the following command:
|
|
|
|
```code
|
|
$ sudo teleport join openssh \
|
|
--address <Var name="server1.example.com:22" /> \
|
|
--proxy-server <Var name="teleport.example.com:443" /> \
|
|
--join-method token \
|
|
--token <Var name="(=presets.tokens.first=)" /> \
|
|
--labels env=dev
|
|
```
|
|
|
|
Change the command-line options to assign the following values:
|
|
- <Var name="server1.example.com:22" /> Set to the address and port of the node that will join your Teleport cluster.
|
|
- <Var name="teleport.example.com:443" /> Set to the address and port of your Teleport Proxy Service.
|
|
- <Var name="(=presets.tokens.first=)" /> 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 node with `tctl edit nodes/<hostname>` or
|
|
`tctl edit nodes/<UUID>`. The node's UUID can be found in the output of
|
|
`tctl nodes ls -v`. Be careful when changing the node's hostname, as the
|
|
hostname is a principal embedded in the host certificate that was generated
|
|
with `teleport join openssh`. If you want to modify the node's hostname,
|
|
you should either change the hostname of the instance and re-run
|
|
`teleport join openssh`, or manually issue a new host certificate with
|
|
`tctl auth sign --format=openssh`.
|
|
|
|
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:
|
|
|
|
<Tabs>
|
|
<TabItem scope={["oss"]} label="Teleport Community Edition">
|
|
|
|
```code
|
|
$ 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
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem scope={["enterprise"]} label="Teleport Enterprise">
|
|
|
|
```code
|
|
$ tsh status
|
|
> Profile URL: https://teleport.example.com:443
|
|
Logged in as: myuser
|
|
Cluster: teleport.example.com
|
|
Roles: access, auditor, editor, reviewer, 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
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem scope={["cloud"]} label="Teleport Enterprise Cloud">
|
|
|
|
```code
|
|
$ tsh status
|
|
> Profile URL: https://mytenant.teleport.sh:443
|
|
Logged in as: myuser
|
|
Cluster: mytenant.teleport.sh
|
|
Roles: access, auditor, editor, reviewer, 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
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
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.
|
|
|
|
```code
|
|
$ 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.
|
|
|
|
|
|
<details>
|
|
<summary>How does the config work?</summary>
|
|
|
|
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 `ssh`ing 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 `ssh`ing 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`:
|
|
|
|
```code
|
|
$ /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.
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Using PowerShell on Windows?</summary>
|
|
|
|
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:
|
|
|
|
```code
|
|
$ tsh.exe config | out-file .ssh\config -encoding utf8 -append
|
|
```
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Dialing uppercase hostnames with OpenSSH</summary>
|
|
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.
|
|
</details>
|
|
|
|
<Admonition
|
|
type="tip"
|
|
title="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.
|
|
|
|
</Admonition>
|
|
|
|
## 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:
|
|
|
|
<Tabs>
|
|
<TabItem scope={["oss", "enterprise"]} label="Self-Hosted">
|
|
|
|
```code
|
|
# 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
|
|
```
|
|
|
|
</TabItem>
|
|
<TabItem scope={["cloud"]} label="Teleport Enterprise Cloud">
|
|
|
|
```code
|
|
# See the available logins you can use to access your sshd host
|
|
$ tsh status | grep Logins
|
|
Logins: ubuntu, root
|
|
$ USER=ubuntu
|
|
$ CLUSTER=mytenant.teleport.sh
|
|
$ PORT=22
|
|
```
|
|
|
|
</TabItem>
|
|
</Tabs>
|
|
|
|
Next, SSH in to your remote host:
|
|
|
|
```code
|
|
$ 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.
|
|
|
|
<details>
|
|
<summary>Why are we overriding the port here?</summary>
|
|
|
|
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.
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary>Using trusted clusters?</summary>
|
|
|
|
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:
|
|
|
|
```code
|
|
$ ssh -F ssh_config_teleport ${USER?}@node2.leafcluster.${CLUSTER}
|
|
```
|
|
|
|
</details>
|
|
|
|
<Admonition
|
|
type="tip"
|
|
title="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.
|
|
|
|
</Admonition>
|
|
|
|
### OpenSSH rate limiting
|
|
|
|
Be aware of OpenSSH's built-in rate-limiting. On large numbers of Proxy Service connections, you may encounter errors like:
|
|
|
|
```txt
|
|
channel 0: open failed: connect failed: ssh: handshake failed: EOF
|
|
```
|
|
|
|
See the `MaxStartups` setting in `man sshd_config`. This setting means that by
|
|
default, OpenSSH only allows 10 unauthenticated connections at a time and starts
|
|
dropping connections 30% of the time when the number of connections goes over 10.
|
|
When it hits 100 authentication connections, all new connections are
|
|
dropped.
|
|
|
|
To increase the concurrency level, increase the value to something like
|
|
`MaxStartups 50:30:100`. This allows 50 concurrent connections and a max of 100.
|
|
|