diff --git a/website/content/docs/common-workflows/workflow-ssh-proxycommand.mdx b/website/content/docs/common-workflows/workflow-ssh-proxycommand.mdx new file mode 100644 index 000000000..fc6bdfa65 --- /dev/null +++ b/website/content/docs/common-workflows/workflow-ssh-proxycommand.mdx @@ -0,0 +1,143 @@ +--- +layout: docs +page_title: SSH ProxyCommand Workflow +sidebar_title: SSH ProxyCommand Workflow +description: How to manage SSH proxy configuration with Boundary +--- + +# SSH ProxyCommand Workflow + +The most common pattern for using Boundary to SSH is with the built-in `boundary connect ssh` command. However, +there are more idomatic approaches that can be employed to make Boundary transparent to users, and at the same +time simplify common developer and operator workflows. Using `ProxyCommand` to execute a proxy when invoking the +SSH client is a common practice. In this workflow, we'll cover configuring your SSH client to execute the +`boundary` command, enabling a simplified SSH workflow that leverages Boundary's authenticated proxy for accessing +targets. + +## SSH Configuration + +Start by configuring a `Host` entry in `.ssh/ssh_config` for `localhost`: + +```bash +Host ttcp_* + ProxyCommand sh -c "boundary connect -target-id %h -exec nc -- {{boundary.ip}} {{boundary.port}}" +``` + +The `ProxyCommand` tells the SSH client to invoke `boundary connect`. We are passing the `-exec nc` flag to +`boundary connect` to wrap [netcat](http://netcat.sourceforge.net/), and then pass the `boundary.ip` and `boundary.port` +varibles as arguments to `nc`. This allows us to proxy our SSH connection through a local netcat tunnel that's +managed as a Boundary session. + +When you run `ssh ttcp_1234567890` (example target ID), SSH will invoke `boundary connect`, and will tunnel the traffic through +the local Boundary proxy in a wrapped netcat session, passing in the target ID as the hostname to the `boundary` command. + +## Authenticate to Boundary + +Before `ssh` can invoke `boundary connect` you need to authenticate. In this example, we're using `boundary dev` with the +default username (admin) and password (password): + +```bash +$ boundary authenticate password -login-name=admin -password password -auth-method-id=ampw_1234567890 +``` + +## SSH to Target + +Running Boundary in [dev mode](https://www.boundaryproject.io/docs/getting-started#what-is-dev-mode) creates other +default resources such as a target and auth method. The default target (ttcp_1234567890) is already setup with a host +at `localhost` and a default port of `22`. + +You can simply run `ssh` as you normally would and all the traffic will be proxied over the Boundary proxy to your target machine: + +```bash +$ ssh ttcp_1234567890 +Password: +Last login: Thu Nov 19 10:32:09 2020 +➜ ~ +``` + +On the controller, you should see the session being invoked in the logs: + +```bash +controller.worker-handler: connection established: session_id=s_WkaQbqmrJx connection_id=sc_RDYNFFI2M4 client_tcp_address=127.0.0.1 client_tcp_port=57421 endpoint_tcp_address=::1 endpoint_tcp_port=22 +``` + +You can inspect the session on the CLI as well: + +```bash +$ boundary sessions read -id $(boundary sessions list -scope-id p_1234567890 -format json | jq '.[0]["id"]' | tr -d '"') + +Session information: + Auth Token ID: at_a8itRfDSyV + Created Time: Thu, 19 Nov 2020 10:52:44 PST + Endpoint: tcp://localhost:22 + Expiration Time: Thu, 19 Nov 2020 18:52:44 PST + Host ID: hst_1234567890 + Host Set ID: hsst_1234567890 + ID: s_WkaQbqmrJx + Status: active + Target ID: ttcp_1234567890 + Type: tcp + Updated Time: Thu, 19 Nov 2020 10:52:47 PST + User ID: u_1234567890 + Version: 2 + + Scope: + ID: p_1234567890 + Name: Generated project scope + Parent Scope ID: o_1234567890 + Type: project + + States: + Start Time: Thu, 19 Nov 2020 10:52:47 PST + Status: active + + End Time: Thu, 19 Nov 2020 10:52:47 PST + Start Time: Thu, 19 Nov 2020 10:52:44 PST + Status: pending +``` + +# Advanced Usage + +Another way to access targets using ProxyCommand is by setting the `Host` value to the target domain instead of the target ID. +This is useful if you want to use the domain name instead of the target ID when forking SSH. An extra step is required to make this +work where you must authorize the session to the target and store it in your environment since we're no longer passing the target +ID to the SSH command. This will allow Boundary to pull the target information from the token you created in the `authorize session` +command. + +## Configure SSH + +```bash +Host localhost + # requires BOUNDARY_CONNECT_AUTHZ_TOKEN to be set from authorize-session command + ProxyCommand sh -c "boundary connect -exec nc -- {{boundary.ip}} {{boundary.port}}" +``` + +## Authenticate to Boundary + +Before `ssh` can invoke `boundary connect` you need to authenticate. In this example, we're using `boundary dev` with the +default username (admin) and password (password): + +```bash +$ boundary authenticate password -login-name=admin -password password -auth-method-id=ampw_1234567890 +``` + +## Authorize the Session + +Running Boundary in [dev mode](https://www.boundaryproject.io/docs/getting-started#what-is-dev-mode) creates other +default resources such as a target and auth method. The default target (ttcp_1234567890) is already setup with a host +at `localhost` and a default port of `22`. + +Authorize a session to the default target and store the token in the `BOUNDARY_CONNECT_AUTHZ_TOKEN` environment variable. +This will be used by Boundary when it's invoked by SSH: + +```bash +$ export BOUNDARY_CONNECT_AUTHZ_TOKEN=$(boundary targets authorize-session -id ttcp_1234567890 -format json | jq '.authorization_token' | tr -d '"') +``` + +## SSH to Target +```bash +$ ssh user@localhost +Password: +Last login: Thu Nov 19 10:32:09 2020 +➜ ~ +``` diff --git a/website/data/docs-navigation.js b/website/data/docs-navigation.js index f1bc623ba..732ebaf4f 100644 --- a/website/data/docs-navigation.js +++ b/website/data/docs-navigation.js @@ -90,6 +90,7 @@ export default [ 'manage-users-groups', 'manage-roles', 'manage-sessions', + 'workflow-ssh-proxycommand', ], }, '---',