A Step-by-Step Guide to Installing Apache Guacamole for Clientless Remote Access

Apr 20, 2024

I needed a way to access all my servers—VNC, RDP, and SSH—from a single place, without installing a bunch of client software on every device I use. That’s when I discovered Apache Guacamole, a clientless HTML5 web-based remote desktop gateway that runs right in a web browser. It has completely changed how I manage remote connections.

What I love about Guacamole is that it’s completely clientless. It supports multiple protocols, centralizing access to all my machines. Plus, it has great features for teams, like session recording, mobile support, and integrations for security like HTTPS and MFA.

Let me walk you through how I set it up.

The Architecture

Guacamole consists of two main components that work together:

  1. guacamole-server: This is the native, server-side part that includes the guacd proxy daemon and all the libraries for handling protocols like VNC, RDP, and SSH.
  2. guacamole-client: This is the web application, served by a container like Apache Tomcat, that provides the HTML5 frontend you interact with in your browser.

Prerequisites

Before I got started, I made sure my server was ready. You’ll need:

Part 1: Install Build Dependencies

First, I had to install the build dependencies, since the Guacamole server needs to be built from source.

sudo apt update
sudo apt install -y \
  gcc g++ libcairo2-dev libjpeg-turbo8-dev libpng-dev \
  libtool-bin libossp-uuid-dev \
  libavcodec-dev libavutil-dev libswscale-dev \
  freerdp2-dev libpango1.0-dev \
  libssh2-1-dev libvncserver-dev libtelnet-dev \
  libssl-dev libvorbis-dev libwebp-dev

Dependency Breakdown

Part 2: Build and Install Guacamole Server

Next, I downloaded and built the Guacamole server itself. I always check for the latest version on their releases page first.

Download Source

# Check latest version at: https://guacamole.apache.org/releases/
GUAC_VERSION="1.5.4"

cd /tmp
wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/source/guacamole-server-${GUAC_VERSION}.tar.gz
tar -xzf guacamole-server-${GUAC_VERSION}.tar.gz
cd guacamole-server-${GUAC_VERSION}

Configure Build

I ran the configure script to prepare the build.

./configure --with-init-dir=/etc/init.d

It’s important to check the output to ensure all the protocols you need are enabled.

------------------------------------------------
guacamole-server version 1.5.4
------------------------------------------------

   Library status:

     freerdp2 ............ yes
     pango ............... yes
     libavcodec .......... yes
     libavformat ......... yes
     libavutil ........... yes
     libssh2 ............. yes
     libssl .............. yes
     libvncserver ........ yes
     libvorbis ........... yes
     libwebp ............. yes

   Protocol support:

      Kubernetes .... yes
      RDP ........... yes
      SSH ........... yes
      Telnet ........ yes
      VNC ........... yes

Apache Guacamole server configuration output

Build and Install

Then, I compiled and installed it.

make
sudo make install

And finally, updated the shared library cache.

sudo ldconfig

Part 3: Configure Guacamole Daemon

With the server built, the next step was to get the guacd daemon running.

sudo systemctl daemon-reload
sudo systemctl start guacd
sudo systemctl enable guacd

A quick status check confirms it’s active.

sudo systemctl status guacd

Part 4: Install Apache Tomcat

For the web client, I used Apache Tomcat.

sudo apt install -y tomcat9 tomcat9-admin tomcat9-common tomcat9-user

I made sure to open the firewall port and verify Tomcat was running by visiting http://your-server-ip:8080.

sudo ufw allow 8080/tcp
sudo systemctl status tomcat9

Part 5: Install Guacamole Client

Now to install the Guacamole web application itself.

I created a configuration directory and downloaded the .war file.

sudo mkdir -p /etc/guacamole
GUAC_VERSION="1.5.4"
sudo wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/binary/guacamole-${GUAC_VERSION}.war \
  -O /etc/guacamole/guacamole.war

Then, I symlinked it into Tomcat’s webapps directory and restarted the service.

sudo ln -s /etc/guacamole/guacamole.war /var/lib/tomcat9/webapps/
sudo systemctl restart tomcat9

After about 30 seconds, I could see the guacamole/ directory in ls -l /var/lib/tomcat9/webapps/, confirming it was deployed.

Part 6: Configure Guacamole

Next, I needed to tell Tomcat where to find the Guacamole configuration files.

echo "GUACAMOLE_HOME=/etc/guacamole" | sudo tee -a /etc/default/tomcat9

I created the main guacamole.properties file to connect the web app to the guacd daemon and define the authentication method.

sudo nano /etc/guacamole/guacamole.properties
# guacamole.properties

# Guacd connection
guacd-hostname: localhost
guacd-port: 4822

# Authentication provider
auth-provider: net.sourceforge.guacamole.net.basic.BasicFileAuthenticationProvider

# Basic properties
basic-user-mapping: /etc/guacamole/user-mapping.xml

Guacamole server connection properties configuration

I also created the extension and library directories and linked them for Tomcat.

sudo mkdir -p /etc/guacamole/{extensions,lib}
sudo ln -s /etc/guacamole /usr/share/tomcat9/.guacamole

Part 7: Configure User Authentication

For this initial setup, I used the basic file-based authentication. First, I generated an MD5 hash for my password.

echo -n 'yourpassword' | openssl md5

MD5 password hash generation output

Then, I created the user-mapping.xml file to define my admin user and the remote connections I wanted to access.

sudo nano /etc/guacamole/user-mapping.xml
<user-mapping>
    <!-- Admin user -->
    <authorize
        username="admin"
        password="5f4dcc3b5aa765d61d8327deb882cf99"
        encoding="md5">

        <!-- VNC Connection -->
        <connection name="Ubuntu Desktop VNC">
            <protocol>vnc</protocol>
            <param name="hostname">192.168.1.100</param>
            <param name="port">5901</param>
            <param name="password">vncpassword</param>
        </connection>

        <!-- RDP Connection -->
        <connection name="Windows Server RDP">
            <protocol>rdp</protocol>
            <param name="hostname">192.168.1.200</param>
            <param name="port">3389</param>
            <param name="username">Administrator</param>
            <param name="password">rdppassword</param>
            <param name="ignore-cert">true</param>
        </connection>

        <!-- SSH Connection -->
        <connection name="Linux Server SSH">
            <protocol>ssh</protocol>
            <param name="hostname">192.168.1.50</param>
            <param name="port">22</param>
            <param name="username">ubuntu</param>
            <param name="password">sshpassword</param>
        </connection>
    </authorize>
</user-mapping>

Finally, I restarted both services to apply the changes.

sudo systemctl restart tomcat9
sudo systemctl restart guacd

Part 8: Access Guacamole

With everything configured, I could now access the web interface at http://your-server-ip:8080/guacamole and log in with my credentials.

Guacamole web login interface

Part 9: Configure VNC on a Remote Client

To test the VNC connection, I set up a TigerVNC server on a remote Ubuntu Desktop. This involved installing the VNC server and some GNOME components.

sudo apt install -y tigervnc-standalone-server gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal

I configured the ~/.vnc/xstartup file to launch a basic desktop environment.

mkdir -p ~/.vnc
nano ~/.vnc/xstartup
#!/bin/bash

export XKL_XMODMAP_DISABLE=1
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

[ -x /etc/vnc/xstartup ] && exec /etc/vnc/xstartup
[ -r $HOME/.Xresources ] && xrdb $HOME/.Xresources

vncconfig -iconic &
gnome-panel &
gnome-settings-daemon &
metacity &
nautilus &
gnome-terminal &

VNC xstartup configuration file contents

After making the script executable (chmod +x ~/.vnc/xstartup), I set a VNC password with vncpasswd and started the server on display :1, which corresponds to port 5901.

vncserver :1 -geometry 1920x1080 -depth 24

For convenience, I also set up a systemd service (/etc/systemd/system/vncserver@.service) to auto-start the VNC server on boot.

Taking it to Production

For a real-world setup, I wouldn’t just leave it running on HTTP. I put it behind an Nginx reverse proxy with HTTPS. Also, for user authentication, the basic XML file is fine for testing, but for production, I switched to a PostgreSQL database for better security and scalability.

Using a database involves installing the PostgreSQL JDBC extension for Guacamole, creating a database and user, and updating guacamole.properties to point to it instead of the XML file.

Things I Ran Into

During my setup, I hit a few snags. If you see a blank page after logging in, the first place I’d check is the Tomcat logs (sudo tail -f /var/log/tomcat9/catalina.out). If you can’t connect to a remote desktop, make sure guacd is running and check its logs (sudo journalctl -u guacd -f). Connection issues are often simple firewall or VNC/RDP server configuration problems.

Final Thoughts

Through this process, I learned a few key things for a production-ready Guacamole setup. Security is paramount, so always use HTTPS, strong passwords (ideally with MFA), and a proper database for authentication instead of the XML file. The architecture is straightforward: guacd is the proxy daemon that does the heavy lifting, and Tomcat serves the web UI. By centralizing access this way, I’ve simplified my remote access management immensely, and the ability to record sessions is a huge plus for auditing.

El Muhammad's Portfolio

© 2025 Aria

Instagram YouTube TikTok 𝕏 GitHub