My PC – Just About Anywhere With Apache Guacamole

With significantly enhanced internet bandwidths now available to small businesses and households alike, the prospects of being able to remotely access powerful desktop environments off ridiculously thin clients (yes, even that tiny little Raspberry Pi) no longer seem to have necessarily remained confined to just the domains of enterprise computing. Given the sheer sophistication of networking technologies now at the disposal of an average IT professional, I am surprised most of us still travel to our offices with cumbersome back-loads of laptops along with their associated paraphernalia and routinely hook them up to monitors, mice and keyboards that most office “hot desks” are anyways equipped with. And I am also a bit frustrated that those ubiquitous mobile phones we have almost started treating like our body parts are still not capable, despite the impressive computing power they carry, of doubling up as thin devices that can lend themselves to a decent display on a computer monitor, thereby opening possibilities of letting us connect to the desktops of real laptops or PCs or virtual machines sitting and listening somewhere in that internet maze. I understand there has been a movement of sorts in this direction (do read up on a project called maru) but the effort has been limited to an extremely narrow range of mobile hardware (nexus phones mainly) besides being fraught with bug reports, which kind of inclines me towards classifying the project as half-hearted at best.

Age old remote desktop access technologies like VNC or RDP do seem to offer workable solutions in this area but every single one of them them suffers from the requirement to necessarily have some kind of client software such as VNC viewer or MS Terminal Service Client before you can as much as connect to remote machines. These software are by no means easy on client-side resources which almost immediately ensures you are no longer in feather-weight or even lightweight realms of operation. I haven’t tried installing such software on a raspberry pi for example but based on my experience with a pi, I wouldn’t be surprised at all if any such effort gets hopelessly marred by installation hurdles, unexpected bugs or unacceptably poor performance. Moreover, none of these technologies seem to be completely platform-agnostic in the sense of being able to offer at least consistent user experience across a range of client operating systems. Another aspect these traditional technologies generally take a severe beating on is connectivity. They operate over over non-standard ports (5901 for VNC, 3389 for RDP and so on) thereby keeping them at the mercy of firewalls rules which, not without reason, seem to be getting more stringent by the day. On the whole, the reasons that make such technologies unattractive clearly smack of the reasons that have historically been behind showing the door to technologies like EJB, RMI and Web Services viz lack of portability, tight couplings, the challenge posed by firewalls etc.

As a corollary then, the problem of remote desktop access over a lean client should naturally lend itself to the same flavors of solutions that made technologies like REST and RESTful APIs the heroes of modern-day, distributed computing. What if entire desktop environments could be transmitted to clients over plain HTTP, using nothing other than good old HTML? A magical world involving no browser plugins, no downloadable jars, no special tinkering with ports or firewalls and yet letting you “visit” your favourite remote PC on a browser just as you would visit any other standard website. And, no special surprise in this increasingly open-sourced world, all that for free?

Come Apache Guacamole. This cunning piece of software, built exactly to let users work their way around difficulties explained above, allows you to pull remote desktops on to any browser that supports HTML5 – and needless to say, most modern ones like Firefox, Chrome, Edge etc do. At once, that makes things really exciting. For example, how about being able to leave your laptop at home, being able to travel to your office with just a 50 gram raspberry pi in your pocket and still be able to efficiently work on that super laptop you left behind? Or, in a few years from now, when projects like maru come of age, just that android in the pocket of your jeans? Assuming you have an access route back to the network your PC or laptop is connected to, you could quickly install and configure this piece of software to expose single or multiple desktops as HTML-over-HTTP(s) targets. Security, clearly, is the first thing that springs to mind. An entire desktop view, made up only of HTML5 and being passed around over HTTP may seem a scary proposition to begin with, but rest assured, in no way does guacamole compromise the security of the target machine. As a convenient wrapper around the target desktop, it has some very sophisticated security features built in which, if configured correctly and used responsibly, could in fact render your desktop more secure with it than without. If you do not have access to your home/target network from across the open internet, a quick read of this article I wrote some time back could potentially get you up and going without too much of an effort or spend. In the following sections, and with reference to the architecture diagram shown below, I will explain exactly how Apache Guacamole goes about churning out the magic mentioned above.

As this diagram shows, at the heart of guacamole is a client-server duo with the client talking to the server over a protocol called, not surprisingly, the “guacamole protocol”. The client is a javascript-intensive WAR application which, based on the data it receives from the server over the guacamole protocol, is capable of running some conversions on the fly and spitting out HTML5 to a client browser. The server module, called guacd (d for daemon), is a reasonably more complex, native C/C++ based library that has several “plugins”, one for each remote access protocol like VNC or RDP. Any single plugin can convert data received over the remote access protocol it is meant for into the common guacamole protocol and send it over to the client for conversion to HTML5. For example, a guacd VNC plugin can connect to a remote node over VNC and convert the desktop data it receives into information that can be transmitted over the guacamole protocol. The client (WAR application) reads this data and converts it into HTML5 which, along with a bunch of javascript instructions is transmitted over HTTP to the client browser. The client WAR, in theory, can be contained in any run-off-the-mill servlet container (though Apache Tomcat seems to be the favourite here), while the server (guacd) runs as a binary daemon / service. The last component in this combination is a MySQL database server that the WAR application uses to keep records of users, their credentials, connection details etc. In terms of actual functionality, the MySQL server therefore represents more of an admin component than anything else. With this kind of a set up, the real thick client that handles all the VNC or RDP-related mess is the guacamole server which could be placed inside the firewall. Once set up, it can be made to interact with any number of remote nodes on the same (safer) side of the firewall with each of these nodes running a remote desktop server of any choice (XRDP, TigerVNC, TightVNC) etc. In effect, this configuration neatly hides away all complications from the end client sitting outside the firewall and receiving pure HTML5 over HTTP or HTTPS. Of course, at the end of the day, your remote nodes would have to be running a desktop server of some flavour to be able to expose their desktop environments out but those convolutions would remain hidden on the “server side” if you like.

It took me a bit of an effort to install Apache Guacamole 1.0.0 on a 64-bit Debian 10 (Buster) box and while I did manage to make it work to perfection in the end, I must admit the steps were a somewhat involved, largely because guacd needs to be compiled and built from source, thereby making it necessary to have a number of development utilities and libraries in place to begin with. It would be great to get guacd as a .deb package or over a custom ppa but that does not seem to be case yet. I have documented the entire set of steps below and can confirm they work for debian 10 – however, please be aware the procedure and/or the exact dependencies required may differ slightly from one Linux distro to another. For Ubuntu 16.06 and above and for versions of debian up to and including 7, this script on git hub makes the installation as easy as invoking it and sipping through a cup of coffee while it completes. Unless, like me, you are stuck with debian 10, by all means go ahead and use this script for installation.

Once installed, the guacamole control panel is available at http://:8080/guacamole in a standard HTML5 browser. The default credentials are guacadmin / guacadmin which, for obvious reasons, you should change after signing in. On the settings page you can add remote PCs to connect to by specifying, at the very minimum, their IP addresses, ports and remote access protocols to use for connections (e.g VNC or RDP). The settings page also offers a range of other parameters to tweak and fiddle around with in terms of matching your security, performance and network requirements.

I found performance to be at it’s best with a remote node running XRDP on Linux Mint 19.2 and attached to the same LAN as the guacamole server. Within the bandwidth limits of my home ISP offering about 200/10 Mbps download/upload and my office (same city but some 16 miles away) metering up to about 150/10 Mbps, I felt quite comfortable working off a raspberry pi from my office and remotely connected over VPN to my favourite home PC running a XRDP server. I can reasonable assume performance will get to be significantly better if I don’t tunnel my connection through the VPN and take a direct route. Remember, there is nothing stopping you from running a XRDP service on the guacamole server itself such that the server connects to itself as the remote node. Needless to say, in this special case, the IP entered for the remote node should be 127.0.0.1 or simply localhost.

Installing Apache Guacamole on Debian 10 (buster)

Installation of Apache Guacamole on debian 10 is slightly more involved compared to installation of other software and includes compilation of packages from source. Below are the steps, assuming you have MySQL/Maria Db and Tomcat 9 already installed. Apache Guacamole depends on Tomcat and MySQL/Maria Db and while installation of these software is beyond the scope of this article, by all means refer to this page for MariaDB and this for Tomcat 9 if you need any help with these installations. I have also assumed your Tomcat home (base) is /opt/tomcat/tomcat-server but if it is not, feel free to ammend the instructions below accordingly.

All commands below should be run with sudo rights. Start by installaing some of the base dev tools and dependencies required by guacamole:

apt-get update
apt-get install build-essential autoconf libtool m4 libpng-dev libjpeg-dev libcairo-dev libossp-uuid-dev libtelnet-dev libpango1.0-dev libssh2-1-dev libwebp-dev libvncserver-dev libpulse-dev libvorbis-dev libavcodec-dev libswscale-dev libwebsockets-dev

The following 2 packages are not available for debian 10 (buster) but need to be borrowed from debian stretch. Not the best practice but this is the only workaround I could get away with. To borrow these packages from stretch, create a file /etc/apt/sources.list.d/temp-debian-stretch.list with the following content:

deb http://deb.debian.org/debian/stretch main 

Now run the following commands

apt update
apt-get install libmysql-java libfreerdp-dev
rm /etc/apt/sources.list.d/temp-debian-stretch.list
apt-get update

Install the guacamole server by downloading the source and making it from scratch:

apt-get install git
git clone git://github.com/apache/guacamole-server.git
cd guacamole-server
autoreconf -fi
./configure --with-init-dir=/etc/init.d
make
make install
ldconfig

Make sure there are no errors. Create and configure a database for guacamole:

mysql -u root -p
create database guacamole;
create user 'guacamoleuser'@'localhost' identified by '';
grant select,insert,update,delete on guacamole.* to 'guacamoleuser'@'localhost';
flush privileges;
quit;

Download and untar the guacamole auth-jdbc package:

wget https://www.apache.org/dist/guacamole/1.0.0/binary/guacamole-auth-jdbc-1.0.0.tar.gz
tar -zxvf guacamole-auth-jdbc-1.0.0.tar.gz

Create the following directories:

mkdir -p /etc/guacamole /etc/guacamole/extensions /etc/guacamole/lib

Download the guacamole client war and deploy it to tomcat

wget https://www.apache.org/dist/guacamole/1.0.0/binary/guacamole-1.0.0.war
cp guacamole-1.0.0.war /opt/tomcat/tomcat-server/webapps/
ln -s /opt/tomcat/tomcat-server/webapps/guacamole-1.0.0 /opt/tomcat/tomcat-server/webapps/guacamole
chown -R tomcat:tomcat /opt/tomcat/tomcat-server/webapps

Copy the authentication jar to /etc/guacamole/extensions/

cp guacamole-auth-jdbc-1.0.0/mysql/guacamole-auth-jdbc-mysql-1.0.0.jar /etc/guacamole/extensions/

Create a file /etc/guacamole/guacamole.properties with the following content:

mysql-hostname: localhost
mysql-port: 3306
mysql-database: guacamole
mysql-username: guacamoleuser
mysql-password: 

Create the db structure for guacamole:

cat guacamole-auth-jdbc-1.0.0/mysql/schema/*.sql | mysql -u root -p guacamole

Create a soft link for the mysql connector to be used by guacamole:

ln -s /usr/share/java/mysql-connector-java.jar /etc/guacamole/lib/

Run the following commands to enable freerdp:

mkdir -p /usr/lib/$(dpkg-architecture -qDEB_BUILD_GNU_TYPE)/freerdp
ln -s /usr/local/lib/freerdp/guac*.so /usr/lib/$(dpkg-architecture -qDEB_BUILD_GNU_TYPE)/freerdp/
ldconfig

Enable the guacd daemon and start the service:

update-rc.d guacd defaults
systemctl start guacd

Ensure the guacd daemon is running by executing the following command and examining the output (look for “active(running)”):

systemctl status guacd

Restart tomcat and guacd

systemctl restart tomcat
systemctl restart guacd

Guacamole should be available at following URL:

http://<IP address of Host>/guacamole

About Dipak Jha

Dipak Jha is is a hands-on Solutions & Integration Architect. He is based at London, UK and works as a SME on Cloud Technologies, Enterprise Architecture, Middleware, Systems Integration, Transformations, Migrations, and general Internet technologies.

Leave a Comment

Your email address will not be published. Required fields are marked *