Setting up Guacamole and configure OpenID Connect

I have self-hosted Guacamole on and off now for the past 5 years with variant levels of success via Docker or installed on a dedicated box. One thing I have never really understood was how to configure it properly and then get it set up with additional extensions. Even searching through guides I have always had a hard time getting to the end with a working Guacamole up and running.
So with this guide, I am going to run through the setup process of getting it installed and built on top of Ubuntu Server 20.04 then getting OpenID Connect to work with Microsoft Azure Active Directory to connect.
What is Guacamole?
Apache Guacamole is a clientless remote desktop gateway. Where traditional you would use apps like Remote Desktop Connection or Remmina to connect to RDP, VNC, or SSH protocols, Guacamole can stand in as an alternative.
Guacamole acts as a clientless solution built in HTML5 which enables the ability to connect to these protocols via a web page.
More information can be found on their website and their documentation.
Installing Guacamole
I started with a fully patched Ubuntu Server VM running Ubuntu Server 20.04.2
. This means running through your sudo apt update && sudo apt upgrade -y
steps and making sure everything is neat and tidy before you kick off the install.
Guacamole Dependencies:
Install the following dependencies.
sudo apt install -y gcc vim curl wget g++ libcairo2-dev libjpeg-turbo8-dev libpng-dev libtool-bin libossp-uuid-dev libavcodec-dev libavutil-dev libswscale-dev build-essential libpango1.0-dev libssh2-1-dev libvncserver-dev libtelnet-dev libssl-dev libvorbis-dev libwebp-dev
The dependencies above are based on the documentation provided by Apache Guacamole. These dependencies may change in the furture as they update/ upgrade their software.
Installing FreeRDP2
Next, we need to install the FreeRDP2
which can be found in the Remmina PPA.
sudo add-apt-repository ppa:remmina-ppa-team/remmina-next-daily
sudo apt update
sudo apt install freerdp2-dev freerdp2-x11 -y
FreeRDP2 is required by Guacamole for the RDP protocol. If this is not installed you will be using an older version which may cause some problems connecting to new operating system versions.
Install Apache Tomcat
We next need to install Tomcat so that the Guacamole Java war file can be served. Since we are also using Java we need to install this first.
sudo apt install openjdk-11-jdk
Once installed, check to see if it installed successfully by checking the version.
java --version

As per best practice, it's best to create a user for Tomcat.
sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat
Next, we need to download the latest version of Tomcat. You can get the latest version by checking their website here.
wget https://downloads.apache.org/tomcat/tomcat-9/v9.0.52/bin/apache-tomcat-9.0.52.tar.gz -P ~
Once the download completes, you will create a new folder /opt/tomcat
and then extract the tar into this folder.
sudo mkdir /opt/tomcat
sudo tar -xzf apache-tomcat-9.0.52.tar.gz -C /opt/tomcat/
sudo mv /opt/tomcat/apache-tomcat-9.0.52 /opt/tomcat/tomcatapp
We then need to set up the tomcat user with rights to access and read the /opt/tomcat
directory.
sudo chown -R tomcat: /opt/tomcat
We also need to make all shell scripts executable in /opt/tomcat/tomcatapp
directory.
The Tomcat Systemd service needs to get set up. Create a systemd service in /etc/systemd/system
.
sudo nano /etc/systemd/system/tomcat.service
and paste the following in.
[Unit]
Description=Tomcat 9 servlet container
After=network.target
[Service]
Type=forking
User=tomcat
Group=tomcat
Environment="JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64"
Environment="JAVA_OPTS=-Djava.security.egd=file:///dev/urandom -Djava.awt.headless=true"
Environment="CATALINA_BASE=/opt/tomcat/tomcatapp"
Environment="CATALINA_HOME=/opt/tomcat/tomcatapp"
Environment="CATALINA_PID=/opt/tomcat/tomcatapp/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"
ExecStart=/opt/tomcat/tomcatapp/bin/startup.sh
ExecStop=/opt/tomcat/tomcatapp/bin/shutdown.sh
[Install]
WantedBy=multi-user.target
Save it and reload it.
sudo systemctl daemon-reload
than
sudo systemctl enable --now tomcat
Check that the Tomcat
service is successfully now running.
systemctl status tomcat

Building Guacamole from Source
Download the latest version of Guacamole Server:
wget https://downloads.apache.org/guacamole/1.3.0/source/guacamole-server-1.3.0.tar.gz -P ~
Extract the source tar after download:
tar xzf ~/guacamole-server-1.3.0.tar.gz
Change into the directory:
cd ~/guacamole-server-1.3.0
Then execute the configure script to check if any required dependencies are missing.
./configure --with-init-dir=/etc/init.d

Then, we need to run the make command.
make
This will take a little while as it processes through, however once it does finish you can than install Guacamole Server using the following command.
sudo make install
To finish up the install, we need to run a ldconfig command to create the necessary links and cache to the most recent shared libraries found in the guacamole server directory.
sudo ldconfig
Next, we need to reload systemd to find the guacamole service.
sudo systemctl daemon-reload
Then we can start and enable the new guacd service.
sudo systemctl start guacd
sudo systemctl enable guacd

Installing Guacamole Web Application
There are two files that are important to create to successfully deploy Guacamole, guacamole.war
(which is the file containing the web application) and the guacamole.properties
which is the main configuration file for Guacamole. The recommended way to set up Guacamole involves placing these files in standard locations, and then creating symbolic links to them so that Tomcat can find them.
Guacamole-client contains all Java and Maven components of Guacamole (guacamole, guacamole-common, guacamole-ext, and guacamole-common-js). These components ultimately make up the web application that will serve the HTML5 Guacamole client to users that connect to your server. This web application will connect to guacd, part of guacamole-server, on behalf of connected users in order to serve them any remote desktop they are authorized to access.
Install Guacamole Client
The Guacamole client is available as a binary. To install it, just pull it from the Guacamole binaries downloads page as shown below, copy it to /etc/guacamole/ directory and rename it at the same time.
sudo mkdir /etc/guacamole
wget https://downloads.apache.org/guacamole/1.3.0/binary/guacamole-1.3.0.war -P ~
sudo mv ~/guacamole-1.3.0.war /etc/guacamole/guacamole.war
To install the Guacamole client binary, create a symbolic link of the guacamole client to Tomcat webapps directory as shown below:
sudo ln -s /etc/guacamole/guacamole.war /opt/tomcat/tomcatapp/webapps
Configure Guacamole Server
After the installation of the Guacamole server daemon, you need define how to Guacamole client will connect to the Guacamole server (guacd) under the /etc/guacamole/guacamole.properties configuration file. Within this configuration, you need to simply define Guacamole server hostname, port, user mapping configuration file, authentication provider.
GUACAMOLE_HOME is the name given to Guacamole’s configuration directory, which is located at /etc/guacamole by default. All configuration files, extensions, etc. reside within this directory.
Create GUACAMOLE_HOME environment variable
echo "GUACAMOLE_HOME=/etc/guacamole" | sudo tee -a /etc/default/tomcat
Create /etc/guacamole/guacamole.properties
config file and populate is as shown below:
sudo nano /etc/guacamole/guacamole.properties
Copy the contents below into the guacamole.properties file.
guacd-hostname: localhost
guacd-port: 4822
After the configuration, save it and link the Guacamole configurations directory to Tomcat servlet directory as illustrated below.
sudo ln -s /etc/guacamole /opt/tomcat/tomcatapp/.guacamole
Configuring MariaDB
We need to next install MariaDB. This is so that we can store our connection configurations in a database. In order to install MariaDB the first step is to add the repository key.
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0XF1656F24C74CD1D8
Next, the repository needs to be added for the appropriate server architecture.
sudo add-apt-repository "deb [arch=amd64] http://mariadb.mirror.liquidtelecom.com/repo/10.4/ubuntu $(lsb_release -cs) main"
Both the server and client applications for must now be installed.
sudo apt install mariadb-server mariadb-client -y
The default time zone must be set for MariaDB using the default-time-zone parameter int in the /etc/mysql/my.cnf
file. This setting must be placed in the mysqld section of the my.cnf
file.

The database and user for Guacamole must next be created. First, create the database. The database can be named whatever you want, for simplicity’s sake I’m sticking with the examples used in the documentation.
Open MySQL;
sudo mysql
Create the guacamole_db
database:
CREATE DATABASE guacamole_db;
Next, create the user that guacamole will use in order to interact with the database. My super strong password reappears, ideally use something better than that.
CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'Password';
The user that was created in the previous step must be granted privileges for the database we configured. Flush privileges to reload the grant table and this stage is done.
GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* to 'guacamole_user'@'localhost';
FLUSH PRIVILEGES;
In order to use MySQL, we must install an extension and a library. We need to first create the folder extensions inside the /etc/guacamole/
location. The extension file, guac-auth-jdbc-1.0.0.tar.gz, must be downloaded from the Apache Guacamole website. Once decompressed, copy the guac-auth-jdbc-1.0.0.jar file to the /etc/guacamole/extensions directory.
sudo mkdir /etc/guacamole/extensions
sudo wget https://apache.mirror.digitalpacific.com.au/guacamole/1.3.0/binary/guacamole-auth-jdbc-1.3.0.tar.gz -P ~
sudo cp guacamole-auth-jdbc-1.3.0/mysql/guacamole-auth-jdbc-1.3.0.jar /extensions/
Guacamole also requires a library in order to interact with MySQL. The MySQL Connector/J is used as a library by Guacamole to interface with MySQL. Download the file and install the .deb.
sudo dpkg -i mysql-connector-java_8.0.26-1ubuntu20.04_all.deb
Once installed, a symbolic link must be created of the .jar file that was installed in the /etc/guacamole/lib directory.
sudo mkdir /etc/guacamole/lib
sudo ln -s /usr/share/java/mysql-connector-java-8.0.17.jar /etc/guacamole/lib/.
The decompressed files for the JDBC extension contain a schema directory with configuration files for different database types. The .sql configuration files must be applied to the database.
cat schema/*.sql | sudo mysql -u root guacamole_db
Edit the guacamole.properties
file to point to the mysql database on localhost at port 3306
. Ensure that the mysql-database
and mysql-username
values match what was configured in the database, and use an awesome password.

The .sql configuration files should have configured a user in the database named guacadmin
with the password guacadmin
. Restart the tomcat8
and guacd
services, and you should now be able to log in as the guacadmin
user. Change the password to something strong (not my weak example password from the config file).
sudo systemctl restart tomcat guacd
Once you have changed the password to the guacadmin
account, we need to create a new user of an account from Azure Active Directory. Do not set a password at this stage, and you need to make sure that you are enabling the Administrative permissions. This is so that you can actually do stuff inside Guacamole one your set up.

Setting up Azure Active Directory
Log into AAD
, and navigate to the App Registrations
blade.

Click on new registration
and enter a meaningful name, I called mine Guacamole
.
Make sure you select your corresponding account type, most will likely be set up to Accounts in this organizational directory only (Tenant Name Here only - Single tenant)
.
Enter your Redirect URI
from what we created from Gitea and click Register
.
Your Redirect URI will look something like this;
https://guacamole.awesomedomain.com
Make sure to enable Allow public client flows
and also tick Access tokens
and ID tokens
.
Click onto the Overview
page and copy the Client-ID
. We will need this later to correctly fill in the guacamole.properties section.
Back on the Guacamole server, open up guacamole.properties
and add the openid sections. Make sure to update the <tenantID>
and <ClientID>
parts.
openid-authorization-endpoint: https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/authorize
openid-jwks-endpoint: https://login.microsoftonline.com/<tenantID>/discovery/v2.0/keys
openid-issuer: https://login.microsoftonline.com/<tenantID>/v2.0
openid-client-id: <ClientID>
openid-redirect-uri: https://guacamole.awesomedomain.com
openid-username-claim-type: email
openid-scope: openid email profile
Finally, we need to add the OpenID Connect extension to the extension folder.
Download the extension from the Guacamole website, extract and move the jar into the extensions folder.
sudo wget https://www.strategylions.com.au/mirror/guacamole/1.3.0/binary/guacamole-auth-openid-1.3.0.tar.gz -P ~
sudo cp guacamole-auth-openid-1.3.0/guacamole-auth-openid-1.3.0.jar /extensions/
sudo /extensions/guacamole-auth-openid-1.3.0.jar /extensions/1-guacamole-auth-openid-1.3.0.jar
Give the services a restart to load and see the new stuff.
sudo systemctl restart tomcat guacd
Now you might have noticed in the second last code block, that the last command adds to the beginning 1-
. Something that is not really obvious and also not very well documented is that the extensions Guacamole loads are loaded in alphabetical order. We need the OpenID extension to load first allowing us to use that login method rather than the SQL one.
This means by default the SQL extension would load first showing you the default login screen rather than loading you straight into Guacamole.
If all goes well, you should now be able to authenticate via Azure Active Directory and log into Guacamole with administrative rights.
Ideally, it would be nice to have a button added to the login screen which allows you to click OpenID Connect kinda like how Gitea does it. That way it gives you the ability to use LDAP and use Security Groups etc.
However, as far as my knowledge there doesn't seem to be an ability to use multiple authentication types like that.
Bonus: Setting up Guacamole to work with Nginx Proxy Manage
For Guacamole to work with Nginx Proxy Manager you need to specify a custom location.
