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.
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.
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.
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.
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.
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
sudo chown -R tomcat: /opt/tomcat
We also need to make all shell scripts executable in
The Tomcat Systemd service needs to get set up. Create a systemd service in
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
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:
Then execute the configure script to check if any required dependencies are missing.
Then, we need to run the make command.
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.
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
/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
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
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.
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
guacamole.properties file to point to the mysql database on localhost at port
3306. Ensure that the
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
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
AAD , and navigate to the
App Registrations blade.
new registration and enter a meaningful name, I called mine
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).
Redirect URI from what we created from Gitea and click
Your Redirect URI will look something like this;
Make sure to enable
Allow public client flows and also tick
Access tokens and
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
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.
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.