Linux - AutoSSH

Connecting to an environment without ingress connections

Definitions

KCM Server: The instance running Keeper Connection Manager.

Remote Endpoint: A target Linux instance in a protected network without data ingress which cannot yet be accessed directly by the KCM Server.

Install KCM Server

If you have not set up a Keeper Connection Manager instance, follow the Auto Docker Install instructions on any instance within any cloud environment. This service will be your KCM Server.

Reverse Tunnel Setup

The instructions below outline how to establish a connection from a KCM Server in the cloud, to an internal Remote Endpoint without network ingress.

(1) Allow inbound SSH on KCM Server

On the KCM Server, ensure that inbound SSH port 22 connections are open from the Remote Server to the KCM instance. We will be establishing an outbound connection from the Remote Server to the KCM instance to set up the reverse tunnel.

(2) Generate SSH Key on the Remote Endpoint

On the Remote Endpoint, create an SSH key pair which will be used to establish an outbound connection from the Endpoint to the KCM Server.

ssh-keygen -t ed25519

This will create two files, a private key and a public key. Leave the private key as is, and copy only the .pub file to your KCM Server.

Now we need to add the contents of the public key file into a special file in your KCM server directory. Check your <home>/.ssh directory and if it doesn't already have a file called "authorized_keys" then create the file. Take the text from the public key file id_ed25519.pub and put the text into the the file~/.ssh/authorized_keys on the KCM server.

The text should have the following format:

ssh-ed25519 AAAAC3NzaC1lZDI1nScLLwc3wsBH localuser@localhost

Save the authorized_keys file as ~/.ssh/authorized_keys

(3) Verify SSH Connectivity from Remote Endpoint to KCM Server

You should now be able to SSH from the remote server into the KCM server, without any password prompt (using the keys).

$ ssh username@demo.kcmdemo.com

Last login: Mon Jul  4 20:28:10 2022 from ip-10-0-1-7.my.remote
[centos@kcmdemo.com ~]$ exit

(4) Install autossh on the Remote Endpoint

The Linux program autossh is a helper utility for creating a persistent SSH tunnel. Installation of autossh depends on the platform, but a typical command to install it would be:

sudo yum install autossh

Or, to build from source, follow these steps (for example, on an Amazon Linux 2 AMI):

$ sudo yum install gcc
$ wget http://www.harding.motd.ca/autossh/autossh-1.4e.tgz
$ tar -xf autossh-1.4e.tgz
$ cd autossh-1.4e
$ ./configure
$ make
$ sudo make install

(5) Update GatewayPorts setting on KCM Server

On the KCM Server, the SSH process (sshd) must be modified to permit remote hosts (e.g. the guacd Docker container) to be allowed to connect to forwarded ports. By default, sshd binds remote port forwards to the loopback address. Setting the value of GatewayPorts to "clientspecified" allows the client to select the address to which the forwarded port is bound.

  • Edit the file /etc/ssh/sshd_config

  • Update the GatewayPorts line to this:

GatewayPorts clientspecified
  • Restart sshd

sudo service sshd restart

(6) Command to Create Persistent Reverse SSH Tunnel

In order to establish an SSH connection from the KCM Server to the Remote Server, we need to first create a persistent reverse tunnel, initiated from the Remote Server.

On the Remote Endpoint, execute autossh in the background, using parameters similar to below. Note that the full path to the private SSH key is provided. Autossh will then run in the background and the tunnel will remain active as long as the instance is running.

Make sure that you have a firewall in place to block inbound connections on all ports except what is needed (HTTP/HTTPS/SSH). And/or change the 0.0.0.0 in the following command to the IP of your KCM server.

autossh -f -M 0 -N -o "ServerAliveInterval 30" \
  -o "ServerAliveCountMax 3" \
  -R 0.0.0.0:9000:localhost:22 \
  -i /home/ec2-user/.ssh/id_ed25519 \
  user@kcm.server.xyz

The reverse tunnel is now established between the Remote Server and the KCM Server.

To verify connectivity, you can now establish an SSH session from the KCM Server to the Remote Server over localhost on the port defined by the tunnel (in this case, port 9000).

From the KCM Server this can be tested using the command below:

ssh -i /path/to/key -p 9000 username@localhost

(7) Update docker-compose to reference the host

This step applies only to the docker installations.

In the Docker install environment, it's possible to establish a connection to the Keeper Connection Manager host instance using a special host name called host.docker.internal.

To configure this, update the file /etc/kcm-setup/docker-compose.yml guacd section to include the "extra_hosts" parameter, as seen below:

    guacd:
        image: keeper/guacd:2
        restart: unless-stopped
        environment:
            ACCEPT_EULA: "Y"
        volumes:
            - "common-storage:/var/lib/guacamole:rw"
        extra_hosts:
            - "host.docker.internal:host-gateway"

Update the docker environment for the change to take effect.

sudo ./kcm-setup.run stop
sudo ./kcm-setup.run upgrade

(8) Create Connection to the target Remote Server

Now that the reverse SSH tunnel is set up, and the docker container is able to access the reverse tunnel, you can now simply create a connection from the Keeper Connection Manager interface.

For this example, you can create a new connection which simply references the Hostname of host.docker.internal and the port of 9000.

As usual, ensure that the proper Authentication parameters are populated in the connection for the remote server. In this case, the remote server is being accessed via the established reverse SSH tunnel.

Save the connection, navigate back to the "My Connections" or "Home" screen, and then click on the connection you just created to verify the routing was successful.

Creating More Connections

If you would like to establish more connections using reverse SSH tunneling, repeat Step 6 of this guide on a different port (e.g. 9001, 9002, etc...). Then reference host.docker.internal with the specified port number when creating Connections inside Keeper Connection Manager.

References

Several references and guides posted online contain helpful information about this configuration.

Last updated