Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

In this article I'll show you how to setup a reverse ssh tunnel to a EC2 instance in AWS running Guacamole. There are many articles on setting up Guacamole servers and connecting to devices that are on the same local network, but I didn’t see any discussing ssh tunnels and how to connect devices on NATed or firewalled networks to a cloud server. Let's get started.

 

Create a Guacamole AWS EC2 Instance

The first thing we need to do is create our EC2 instance in AWS(Note: If you don’t have an AWS account you can register for a free one here). Login to AWS, and go to your EC2 Dashboard and from the dashboard click Launch instance. Enter a server name (I’m using ‘guacamole-server’),  and now on the Application and OS Images(Amazon Machine Image) search for 'guacamole'.  Click on the AWS Marketplace AMIs, and select the image titled: Apache Guacamole packaged by Bitnami . You can choose another Guacamole AMI but some of the steps might be a little different.

pic1 - ami selection Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

In addition, please take note of the Bitnami documentation link.  I used the vendor recommended instance type: t3a.small.

 

pic2 - instance type Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

Our next step is to create a key pair so we can log in to our instance with SSH. Click "Create new key pair" with the following options:

  • Key pair name: guacamole-server-key
  • Key pair type: RSA
  • Private key format: .pem (note: you can convert your key pair for Putty later with Puttygen).

 

pic3 - key pair Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

When you create the new key, it will automatically download to your local machine. Once you have the server working, you can configure more advanced security settings, for now leave the default setting. On the 'Configure storage' page, I set the storage capacity for the instance to 30 GB.

 

pic4 - network and storage Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

Launch your instance and then locate its Public IPv4 address by clicking on the instance itself. 

 

pic5 - public ip Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

Let's connect to our EC2 instance using PuTTY and create a private key using PuTTYgen for authentication. If you haven't already done so, download PuTTygen. Open PuTTYgen and click on 'Load' to select the downloaded key file (guacamole-server-key). Save the private key file by clicking on 'Save private key' (do not click on 'Generate') and name it 'guacamole-server-key.ppk'.

 

pic6 - puttygen Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

If you don’t have putty download click here, we will use it to connect to the EC2 instance. For the hostname, you'll want to put This email address is being protected from spambots. You need JavaScript enabled to view it.'. Then, on the left side of the Putty window, expand SSH, then expand Auth, and highlight 'Credentials'. On 'Private key file for authentication', click 'Browse' and select the Putty Private Key File you just generated. Don't forget to save everything by going back to the Session tab, entering a session name, and clicking 'Save'.

 

pic7 - putty ssh Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

pic8 - putty session Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

Open the session and you should be connected to our Guacamole Server.

 

pic9 - putty connected to server Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

Next we need to grab the guacamole server website login information. Go to your EC2 instance and click on Actions > Monitor and troubleshoot > Get system log

 

pic10 - system log ec2 Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

Scroll up in the log a bit and you will find the guacadmin user id and password that will allow you to log into the guacamole web interface. You can test the password by opening a web browser and going to your ec2 instance public ip.

 

pic11 - guac password log Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

Before we begin configuring our client machine, let's configure a user account for our SSH tunnel. The name of my client machine is bokeh07, so that's what I'll name the account on my EC2 instance. You can set up additional keys for each account on your Guacamole server, but that's not within the scope of this article, so we're going to just copy the key used on the Bitnami account.

Commands used:

sudo adduser new_user --disabled-password

sudo su

cp /home/bitnami/.ssh/authorized_keys /home/new_user/.ssh/

chown -R new_user:new_user /home/new_user/.ssh



Finally we need to enable GatewayPorts in the SSHD configuration file (/etc/ssh/sshd_config) and restart services:

GatewayPorts yes

 

To restart services:

sudo service ssh restart

 

Setting up the client reverse ssh tunnel

 

For a client I’m using a Debian based Linux machine; the big thing is you want to make sure you have OpenSSH installed.  Now we need to copy the guacamole-server-key.pem  we downloaded to where your ssh keys are stored, mine are in /etc/ssh . Let’s run a quick test to make sure we can connect to the guacamole server.

ssh -i /etc/ssh/guacamole-server-key.pem new_userThis email address is being protected from spambots. You need JavaScript enabled to view it.

 

pic12 - ssh check client Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

To create a ssh tunnel to our guacamole instance we will use the following command:

ssh -N -R <remote port>:localhost:22 <EC2 instance public DNS> -i /etc/ssh/guacamole-server-key.pem 

Here's what each part of the command means:

  • ssh: This is the command to initiate a secure shell connection.
  • -N: This tells ssh not to execute a remote command. We only want to set up a tunnel.
  • -R: This sets up a reverse tunnel. It forwards traffic from a remote port to a local port.
  • <remote port>: This is the port on the EC2 instance that you want to forward traffic to.
  • localhost:22: This specifies the local port to forward traffic from. In this case, we want to forward traffic from the local port 22 (SSH).
  • <EC2 instance public DNS>: This is the public DNS of your EC2 instance.

Once you run this command, any traffic that is sent to <remote port> on the EC2 instance will be forwarded to port 22 on your client machine. You can see the tunnel is established by running a netstat on ec2 instance, I’m using port 7777 and you can see it listening in the screenshot below.

 

pic13 - netstat on ec2 Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

Now we need to build persistence for the ssh tunnel, that way if the client is rebooted or the tunnel drops for some reason it will re-establish automatically. To do this we'll create a service with the following command:


sudo nano /etc/systemd/system/reverse-ssh-tunnel.service

 

Paste the following code into the file:


[Unit]
Description=SSH Reverse Tunnel After=network-online.target

[Service] 
User=<your-username> 
ExecStart=/usr/bin/ssh -N -i /path/to/private/key.pem -R <remote-port>:localhost:22 <your-ec2-instance-ip> 
Restart=always 
RestartSec=10

[Install] 
WantedBy=multi-user.target

 

pic14 - systemd file Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

The [Unit] section defines metadata about the unit, such as its description and dependencies. In this case, the unit is named "SSH Reverse Tunnel" and it is set to start after the network is online (After=network-online.target).

The [Service] section specifies the properties of the service, including the user who will run it (User=<your-username>), the command to run (ExecStart=/usr/bin/ssh -N -i /path/to/private/key.pem -R <remote-port>:localhost:22 <your-ec2-instance-ip>), and the restart behavior (Restart=always and RestartSec=10). The command runs an SSH connection with reverse port forwarding, which forwards traffic from the specified remote port to the local port 22 (SSH) on the specified EC2 instance.

The [Install] section specifies the target for installation (WantedBy=multi-user.target), which determines when the service will be started or stopped. In this case, the service will be started when the system enters the multi-user mode, which is the default run level for most Linux-based systems.

 

Now we need to reload the ‘systemd’ daemon by running the following command:

sudo systemctl daemon-reload

 

Start the reverse-ssh-tunnel service by running the following command:

sudo systemctl start reverse-ssh-tunnel

 

Check the status of the service by running the following command:

sudo systemctl status reverse-ssh-tunnel

 

You can also verify the tunnel is up with netstat on our guacamole instance.

 

Connecting Guacamole to the SSH Tunnel

In this  final section we'll connect the Guacamole server to the ssh tunnel. Login to your Guacamole instance with a web browser using the Public IP of your instance and the user id and password we copied from the log file earlier. Navigate to guacadmin > Settings > Connections > New Connection and give the connection a Name and select protocol SSH. I’ll just put screenshots of my guacamole config because it’s pretty self explanatory.

 

pic15 - guac connection Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 Next scroll to the bottom of the page and Save. Then navigate to guacadmin > home and click on the new connection.

 

pic16 - connected to our client Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

pic17 - home screen with bokeh07 Create a Reverse SSH Tunnel to a Bitnami Guacamole AWS EC2 Instance

 

 

Note: I had an issue connecting Guacamole to one of my client machines, the ssh handshake was failing because the client was using a newer version of ssh. To correct the problem I added HostKeyAlgorithms +ssh-rsa at the end of my sshd config file ( /etc/ssh/sshd_config ). If you need to update the ssh configuration file be sure to restart the service ( systemctl restart ssh.service ).

 

That’s all I have for this post but if you have any questions feel free to shoot me a note at This email address is being protected from spambots. You need JavaScript enabled to view it. . Sometime in the near future I’ll make a follow on post showing how to connect VNC and RDP over the tunnel to our guacamole instance. Thanks for reading!

 

 

 

Bokeh Solutions

Focused Results!


Empowering Businesses with Comprehensive Security Solutions!

Contact Us