# AutoSSH as a Windows Service

![](https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FjLoKNVGoCz147gMAfpeG%2FReverse%20SSH%20Tunnel.jpg?alt=media\&token=ccf52ea8-c563-4871-a09b-839a354f7e55)

If you prefer to run autossh as a windows service, you can follow these steps.

## Definitions

**KCM Server:** The instance running Keeper Connection Manager.

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

## Prerequisite - Install Cygwin

On the remote endpoint, install Cygwin from <https://www.cygwin.com/install.html>.  The direct download link is <https://www.cygwin.com/setup-x86_64.exe>.&#x20;

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FB7SxZALZTbDTGW5ENwi2%2Fchrome_PeK6NWCOhn.png?alt=media&#x26;token=0210835b-31d2-42b6-9f15-08a7044790e7" alt=""><figcaption></figcaption></figure>

After it's installed, we will select both the openssh and the autossh packages to download and install.

Click Next > Install from Internet > All Users > Next > Next > Next > Choose any mirror > Next (as shown below).

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FeGp3nv4BOGEEbl39PBje%2Fchrome_MKu1KDAV4p.gif?alt=media&#x26;token=8322d083-3c1a-46d4-9d60-f59f14c8b5e5" alt=""><figcaption></figcaption></figure>

At the "Select Packages" screen, change the view from Pending to Full and then enter "ssh" in the search box. Select the down arrow on autossh, choose latest version. Select the down arrow on openssh, choose the latest version (shown below).

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FoJkVqDNIIzQN1KUdj8OR%2FBK54j1E16g.gif?alt=media&#x26;token=065b52f1-165d-4f3c-be70-0ef3024e6d56" alt=""><figcaption></figcaption></figure>

## Reverse Tunnel Setup

The instructions below outline how to establish a connection from a KCM Server in the cloud, to a 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 Keys on the Remote Endpoint**

On the Windows Remote Endpoint, **using Cygwin Terminal** create an SSH key pair which will be used to establish an *outbound* connection from the Endpoint to the KCM Server. Enter the following into the Cygwin Terminal:

```
ssh-keygen -t ed25519
```

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FfGFPXmHJFA5PyqntVUPy%2Fmsedge_vt5jaHQFVl.png?alt=media&#x26;token=a1d32206-0816-4232-9713-d1f5c12dce30" alt=""><figcaption></figcaption></figure>

It will ask where you want to save the key, you can just press enter to take the default and continue.

This will create two files, a private key and a public key.  Leave the private key in place. We will copy the public key from the target endpoint onto the KCM server.

Next, we will copy the **public key file (.pub)** from the windows endpoint to the KCM Server in \~/.ssh/authorized\_keys.

{% hint style="success" %}
You can transfer the .pub file by any method that you choose.
{% endhint %}

You can transfer the .pub file by any method that you choose.  If you have outbound traffic allowed on the windows target endpoint, you can use the following command in the **Cygwin Terminal**:

```
cd .ssh
ssh-copy-id user@kcm.server.xyz
```

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2F8NOaP9WPb2vrrsAuGBC7%2Fchrome_PrcXuskDc9.png?alt=media&#x26;token=9e93c539-ff29-4ef6-86c8-45719e6b3b5f" alt=""><figcaption></figcaption></figure>

**(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**.

```
ssh username@kcm.server.xyz

Last login: Mon Jul  4 20:28:10 2022 from ip-10-0-1-7.my.remote
```

**(4) Establish the persistent SSH tunnel**

To create the persistent tunnel, enter the following two commands into the **windows command prompt or PowerShell** (*not* in the Cygwin Terminal):

{% hint style="warning" %}
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.
{% endhint %}

{% code title="Navigate to this directory" %}

```powershell
cd C:\cygwin64\bin
```

{% endcode %}

Choose any open port to use, in this example we use port 9000.

{% code title="Use 9000 or any open port" overflow="wrap" %}

```powershell
cygrunsrv -I AutoSSH -p /usr/bin/autossh -a "-M 20000 -R 0.0.0.0:9000:localhost:3389 username@hostenameORipaddress" -e AUTOSSH_NTSERVICE=yes
```

{% endcode %}

**(5) Configure the Windows Service**

Open Services and look for the new service called "AutoSSH" and open it, but don't start it just yet.

We will set an automatic delayed start and logon by the Administrator account.  These will help allow the service to start properly.

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2Fy0u1KvdSA8jdjYk0GJbq%2Fmsedge_HRyzgcXFtd.png?alt=media&#x26;token=c0627c83-56af-4dd4-9a02-d2742cb5beeb" alt=""><figcaption></figcaption></figure>

On the Log On tab, click browser and enter the administrator object name and click "Check Names".  Make sure to put the password for the administrator account into both fields.

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2F5IGrL2xUvey7KaLnbtDf%2Fmsedge_h8pK2SGxu3.png?alt=media&#x26;token=e5976e21-1f78-4c78-b2e4-ab23bf98d90c" alt=""><figcaption></figcaption></figure>

Now we are ready to start the AutoSSH Service (shown below).

<figure><img src="https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FjcXe9xWtCDuXT5PqAqGo%2Fchrome_rfyWZNrFSC.gif?alt=media&#x26;token=ae0ca2b4-df6c-4585-b0b8-fb718ba90226" alt=""><figcaption></figcaption></figure>

{% hint style="success" %}
**Start the AutoSSH service and confirm that it is running.**&#x20;
{% endhint %}

**(6) Update GatewayPorts setting on KCM Server**

{% hint style="info" %}
This step only needs to be completed once, so if you have already completed it while setting up a different reverse ssh tunnel method, you can move on to step 8
{% endhint %}

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
```

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

**(7) Update docker-compose to reference the host**

{% hint style="info" %}
This step applies only to the docker installations.
{% endhint %}

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.

Create a new RDP connection with the hostname of `host.docker.internal` and the port of 9000 (or your chosen port).

![Create Connection via Reverse SSH Tunnel](https://3357255970-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fb7weUpu7VBcMnESSH8vG%2Fuploads%2FPWQHq7zcnNwFHfnT7li2%2FScreen%20Shot%202022-07-04%20at%2010.43.47%20PM.png?alt=media\&token=45504026-cab5-497f-9fa7-9ca54fd2a844)

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 5** of this guide on a different available port (e.g. 9001, 9002, etc...). Then create a connection 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.

{% embed url="<https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/>" %}

{% embed url="<https://superuser.com/questions/588591/how-to-make-an-ssh-tunnel-publicly-accessible>" %}

{% embed url="<https://serverfault.com/questions/379344/selecting-interface-for-ssh-port-forwarding>" %}

{% embed url="<https://medium.com/@TimvanBaarsen/how-to-connect-to-the-docker-host-from-inside-a-docker-container-112b4c71bc66>" %}
