Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v9] Add OpenSSH Proxy Jump docs #13851

Merged
merged 5 commits into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 92 additions & 3 deletions docs/pages/server-access/guides/openssh.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,6 @@ 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.

If you are using Trusted Clusters, this will print an OpenSSH client
configuration block for the root cluster and all currently known leaf clusters.

<Details title="How does the config work?">

Teleport implements an SSH server that includes several **subsystems**, or
Expand Down Expand Up @@ -340,6 +337,98 @@ authenticate the host via the certificate we generated earlier.

</Details>

<Details title="Experiencing latency in leaf cluster Nodes?">

### Proxy Jump

In the generated OpenSSH client configuration, the `ProxyCommand` for each leaf
cluster connects through the root cluster's Proxy Service. In scenarios where
leaf cluster Proxy Services are reachable by SSH client, you might prefer to
connect directly through the leaf proxies for lower latency.

To enable direct connections to a Proxy Service in a leaf cluster, open the
SSH configuration file you generated earlier and update the `ProxyCommand`
of the leaf cluster's configuration block to use the leaf Proxy Service as
a jumphost, using the `-J` flag.

```txt
Host *.{{ .NodeName }}.leaf1.example.com
Port 3022
ProxyCommand tsh proxy ssh -J proxy.leaf1.example.com:443 %r@%h:%p
```

### Proxy Templates

With Proxy Templates, `tsh` will dynamically determine the address of the
Proxy Service to connect to based on the address of the destination
host in your `ssh` command.

To use Proxy Templates, add `-J {{proxy}}` to the `ProxyCommand` line in
your `~/.ssh/config`.

```txt
Host *.example.com
Port 3022
ProxyCommand tsh proxy ssh -J {{proxy}} %r@%h:%p
```

Then, add `proxy_templates` to your `tsh` configuration file (`~/.tsh/config/config.yaml`
or a global `/etc/tsh.yaml`).

```yaml
proxy_templates:
- template: '^(\w+)\.(leaf1\.example\.com):([0-9]+)$'
proxy: "$2:443"
```

`tsh proxy ssh -J {{proxy}}` will attempt to match the host server address `%h:%p` with the
configured templates. If there is a match, then the jump proxy address `{{proxy}}` will
be replaced using the template's `proxy` field and the host server address `%h:%p` will be
replaced using the template's `host` field if set.

| Field | Description |
| ---------- | ----------- |
| `template` | (Required) Regular expression that the host server address `%h:%p` is matched against. |
| `proxy` | (Required) Proxy Service address to use for proxy jump. Can reference capturing groups from the regular expression in `template` (e.g., `$1` or `$2`). |
| `host` | (Optional) Host Server address to connect to. Can reference capturing groups from the regular expression in `template` (e.g., `$1` or `$2`). Defaults to full host spec `%h:%p`. |

### Example configuration

```yaml
proxy_templates:
- template: '^(\w+)\.(leaf1\.example\.com):([0-9]+)$'
proxy: "$2:443"
- template: '^(\w+)\.(leaf2\.example\.com):([0-9]+)$'
proxy: "$2:3080"
host: "$1:$3"
- template: '(\w+(\.\w+)*)\.(example\.com):([0-9]+)$'
proxy: "leaf1.example.com:443"
host: "$1:22"

Given the configuration above, the following command will connect to the Node
`node-1.leaf1.example.com:3022` through the Proxy Service `leaf1.example.com:443`:

```code
$ ssh root@node-1.leaf1.example.com
```

The following command will connect to the Node `node-1:3022` through the Proxy Service
`leaf2.example.com:3080`:

```code
$ ssh root@node-1.leaf2.example.com
```

The last template can be used to connect to openssh hosts with their own FQDN.
For example, you can connect to the host `openssh.external.com:22` through the
Proxy Service `leaf1.example.com:443` with the following command:

```code
$ ssh root@openssh.external.com.example.com
```

</Details>

<Admonition
type="tip"
title="Multiple Clusters"
Expand Down
18 changes: 9 additions & 9 deletions rfd/0062-tsh-proxy-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ determine which host/proxy/cluster user is connecting to.
## UX

The proposal is to extend the existing `tsh proxy ssh` command with support for
parsing out the node name and proxy address from the full hostname token `%h` in
parsing out the node name and proxy address from the full hostname `%h:%p` in
SSH config.

Specifically, the syntax for the `<some proxy command>` would look like:
Expand All @@ -77,7 +77,7 @@ instead of the default behavior of connecting to the proxy of the current
client profile. This usage of the `-J` flag is consistent with the existing
proxy jump functionality (`tsh ssh -J`) and [Cluster Routing](https://github.com/gravitational/teleport/blob/master/rfd/0021-cluster-routing.md).

When a template variable `{{proxy}}` is used, the host name and proxy address
When a template variable `{{proxy}}` is used, the desired hostname and proxy address
are extracted from the full hostname in the `%r@%h:%p` spec. Users define the
rules of how to parse node/proxy from the full hostname in the tsh config file
`$TELEPORT_HOME/config/config.yaml` (or global `/etc/tsh.yaml`). Group captures
Expand All @@ -86,11 +86,11 @@ are supported:
```yaml
proxy_templates:
# Example template where nodes have short names like node-1, node-2, etc.
- template: '^(\w+)\.(leaf1.us.acme.com)$'
host: "$1" # host is optional and will default to the full %h if not specified
- template: '^(\w+)\.(leaf1.us.acme.com):(.*)$'
proxy: "$2:3080"
host: "$1:$3" # host is optional and will default to the full %h:%p if not specified
# Example template where nodes have FQDN names like node-1.leaf2.eu.acme.com.
- template: '^(\w+)\.(leaf2.eu.acme.com)$'
- template: '^(\w+)\.(leaf2.eu.acme.com):(.*)$'
proxy: "$2:443"
```

Expand All @@ -105,13 +105,13 @@ multiple leaf clusters, their template configuration can look like:

```yaml
proxy_templates:
- template: '^([^\.]+)\.(.+)$'
host: "$1"
- template: '^([^\.]+)\.(.+):(.*)$'
proxy: "$2:3080"
host: "$1:$3"
```

In the node spec `%r@%h:%p` the host name `%h` will be replaced by the host from
the template specification and will default to full `%h` if it's not present in
In the node spec `%r@%h:%p` the hostname `%h:%p` will be replaced by the host from
the template specification and will default to full `%h:%p` if it's not present in
the template.

So given the above proxy template configuration, the following proxy command:
Expand Down