No more logmein Free? OpenSource to the rescue! Part 2:Securing Guacamole and exposing it to the Web
In part 1 of my series on Guacamole we learned how to install Guacamole on an Ubuntu machine. As Guacamole is still being developed it can not be guaranteed that is 100% safe so extra security measures are advisable before opening Guacamole to the big bad internet. This guide shows you how to use Apache2 as a frontend. In a later guide I will also look into securing Apache with ModSecurity and Mod-Spamhaus but this is beyond the scope of this guide. I also have a VPN between my VPS and my internal server (so I don't need to expose my internal network to the internet), this is also out of the scope of this guide. To use this guide you must have succesfully installed Guacamole inside your own network.
As I own a VPS I used the VPS as a frontend proxy (connected through a VPN to my internal Guacamole server) but Apache2 can also run on the same machine as Guacamole. If you want to use this guide in this scenario there is less configuration. In both scenarios I will be using AJP as a communication protocol between Tomcat7 and Apache2.
1. First we need to install mod-proxy to allow Apache to act as a Frontend (proxy) to Tomcat7
apt-get install libapache2-mod-proxy-html
2. Secondly Tomcat7 (on the Guacamole server) needs to be configured for AJP.
To allow AJP connections to Tomcat, you must add a connector to Tomcat's server.xml. There may already be an example connector in your server.xml, in which case all you need to do is uncomment it, editing the port number as desired (in this guide we love it at the default 8009):
<Connector port="8009" protocol="AJP/1.3"
The URIEncoding="UTF-8" attribute above ensures that connection names, user names, etc. which contain non-latin characters are properly received. If you will be creating connections that have Cyrillic, Chinese, Japanese, etc. characters in the names or parameter values, you should be sure to set this attribute.
Tomcat must be restarted after the connector is added.
service tomcat7 restart
3. Once the connector is open, and Tomcat is listening on the port specified, you can edit your Apache configuration, adding a location which will proxy the Guacamole web application served via AJP by Tomcat:
Allow from all
ProxyPass ajp://HOSTNAME:8009/guacamole/ max=20 flushpackets=on
The most important thing in this entire section is the option flushpackets=on. Most proxies, including mod_proxy, will buffer all data sent over the connection, waiting until the connection is closed before sending that data to the client. As Guacamole's tunnel will stream data to the client over an open connection, buffering this stream breaks Guacamole's communication.
If the option flushpackets=on is not specified, Guacamole will not work.
4. As AJP does not encrypt and it doesn't use authentication I enabled ufw on my Guacamole machine to only allow communication from the correct host. Don't forget to add exclusions for your SSH access before enabling it though!
ufw allow from [internalLAN] to [internalIP] port 22
ufw allow from [apache-VPN-IP] to [Guacamole-VPN-IP] port 8009
So if your VPN address are 192.168.111.5 (Guacamole) and 192.168.111.10 (Apache2), your internal Guacamole address is 192.168.1.5 and your LAN is 192.168.1.0/24 the commands are:
ufw allow from 192.168.1.0/24 to 192.168.1.5 port 22
ufw allow from 192.168.111.10 to 192.168.111.5 port 8009
5. Now it's time to finish configuring Apache2 by adding Apache authentication and HTTPS. To use HTTPS you can either use a selfsigned certificate (causing errors to pop up in your browser), buy a web certificate or use StartSSL to get a free one. This guide assumes you have both the key and the crt available, if you need help with this you can check here.
First create a DocumentRoot folder for the website (in this guide /var/guacamole.example.com)
Now we will create an Apache2 password file we will be using later to add an extra layer of authentication. Go to http://www.htaccesstools.com/htpasswd-generator/ and generate as many user/password combinations as you see fit and put these in /var/guacamole.example.com/.htpasswd. In this example I used user test with password 123
Next we add a new website to Apache2 by adding a file to /etc/apache2/sites-available. In this example I am working with the domainname guacamole.example.com and a free SSL certificate from StartSSL, change this to the domainname of your server (you can also use the IP address of course) To make sure we always go to HTTPS a permanent redirect is specified on port 80 (HTTP)
The ' Allow from [YOU]' allows the machine with IP address [YOU] to continue without authentication, so if you have a non-dynamic IP address you can use this command to log in just a bit faster. If you have a dynamic IP address just delete that line.
Redirect permanent / https://guacamole.example.com/
Redirect permanent /guacamole https://guacamole.example.com/guacamole
ProxyPass ajp://192.168.111.5:8009/guacamole/ max=20 flushpackets=on
AuthName "Password Protected Area"
Deny from all
Allow from [YOU]
Now enable the website by running
and restart Apache2 by running
service apache2 restart
You should now be able to open the website https://guacamole.example.com/guacamole and after entering the correct Apache2 username/password see your Guacamole server!
Note: To achieve real end to end encryption you should only use Remote Desktop (which is encrypted by default) or buy a personal license to RealVNC which allows encrypting the communication between Guacamole and VNC. In this example encryption between client and Apache2 server is achieved by HTTPS and encryption between Apache2 and Tomcat7 by using a VPN.