How to Install and Use Apache Guacamole Remote Desktop on Rocky Linux 8

Apache Guacamole is a free, open-source, clientless, remote desktop gateway. It supports standard protocols like SSH, RDP, and VNC. It does not need any third-party plugins and clients to work. You can access your machine using a web-based gateway. It can be put behind a proxy server which allows you to access your servers from anywhere in the world.

Guacamole is made up of two components:

  • guacamole-server contains all the native, server-side components required by Guacamole to connect to remote desktops. guacd is the proxy daemon that runs on the Guacamole server, accepts user connections and then connects them to the remote desktops.
  • guacamole-client contains all Java and Javascript components of Guacamole which make up the web application where users can connect to their desktops.

In this tutorial, you will learn how to install and use Apache Guacamole on a Rocky Linux 8 based server. You will also learn how to use it to connect to a remote desktop. We will be installing Guacamole by building from its source code.

Prerequisites

  • A server running Rocky Linux 8 with a minimum of 2GB RAM and 2 CPU Cores.

  • A domain name for the helpdesk pointing to the server. For our tutorial, we will use the uvdesk.example.com domain.

  • A non-root based user with sudo privileges.

  • Make sure everything is updated.

    $ sudo dnf update
    
  • Install basic utility packages. Some of them may already be installed.

    $ sudo dnf install wget curl nano unzip yum-utils -y
    

Step 1 - Configure Firewall

The first step is to configure the firewall. Rocky Linux uses Firewalld Firewall. Check the firewall's status.

$ sudo firewall-cmd --state
running

The firewall works with different zones, and the public zone is the default one that we will use. List all the services and ports active on the firewall.

$ sudo firewall-cmd --permanent --list-services

It should show the following output.

cockpit dhcpv6-client ssh

Allow HTTP and HTTPS ports.

$ sudo firewall-cmd --permanent --add-service=http
$ sudo firewall-cmd --permanent --add-service=https

Recheck the status of the firewall.

$ sudo firewall-cmd --permanent --list-services

You should see a similar output.

cockpit dhcpv6-client http https ssh

Reload the firewall to enable the changes.

$ sudo firewall-cmd --reload

Step 2 - Install Libraries

Before installing the libraries, we need to install the EPEL repository and enable the PowerTools repository.

$ sudo dnf install epel-release -y
$ sudo dnf config-manager --set-enabled powertools

The first step is to install libraries required to build Guacamole. Install the required libraries.

$ sudo dnf install cairo-devel libjpeg-turbo-devel libjpeg-devel libpng-devel libtool libuuid-devel uuid-devel make cmake

The above dependencies are compulsory ones, which means without them, Guacamole can't be built. You can install some optional dependencies to add support for various protocols and features.

But first, you need to enable the RPMFusion Free Repository because it contains the package ffmpeg-devel.

$ sudo dnf install --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm

Install the optional dependencies.

$ sudo dnf install ffmpeg-devel freerdp-devel pango-devel libssh2-devel libtelnet-devel libvncserver-devel libwebsockets-devel pulseaudio-libs-devel openssl-devel compat-openssl10 libvorbis-devel libwebp-devel libgcrypt-devel

Step 3 - Install Apache Tomcat

For our tutorial, we will install Apache Tomcat 9, which requires Java 8 and later to work.

Install Java

We will install OpenJDK 11, the open-source implementation of the Java platform.

Run the following command to install OpenJDK.

$ sudo dnf install java-11-openjdk-devel

Verify the installation.

$ java -version
openjdk 11.0.14 2022-01-18 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.14+9-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.14+9-LTS, mixed mode, sharing)

Create Tomcat User

Next, create a user for the Tomcat service. We will set /opt/tomcat as the home directory.

$ sudo useradd -m -U -d /opt/tomcat -s /bin/false tomcat

Download Tomcat

The latest version of Tomcat v10 can be downloaded from its download page. At the time of writing this tutorial, v9.0.59 is the latest available version. Check the latest version before you download Tomcat.

Use wget to download Tomcat.

$ TVERSION=9.0.59
$ wget https://dlcdn.apache.org/tomcat/tomcat-9/v${TVERSION}/bin/apache-tomcat-${TVERSION}.tar.gz

Extract the file to the /opt/tomcat directory.

$ sudo tar -xf apache-tomcat-${TVERSION}.tar.gz --strip-components=1 -C /opt/tomcat/

Change the ownership of the directory to the Tomcat user.

$ sudo chown -R tomcat:tomcat /opt/tomcat

Create a Systemd Unit File and Start Tomcat

Create and open the file /etc/systemd/system/tomcat.service for editing.

$ sudo nano /etc/systemd/system/tomcat.service

Paste the following code.

[Unit]
Description=Apache Tomcat 9 Servlet container
Wants=network.target
After=network.target

[Service]
Type=forking
User=tomcat
Group=tomcat

Environment="JAVA_HOME=/usr/lib/jvm/jre"
Environment="JAVA_OPTS=-Djava.awt.headless=true"
Environment="CATALINA_BASE=/opt/tomcat"
Environment="CATALINA_HOME=/opt/tomcat"
Environment="CATALINA_PID=/opt/tomcat/temp/tomcat.pid"
Environment="CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC"

ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
Restart=always

[Install]
WantedBy=multi-user.target

Save the file by pressing Ctrl + X and entering Y when prompted to save.

Reload the service daemon to enable the Tomcat service.

$ sudo systemctl daemon-reload

Enable and Start the Tomcat service.

$ sudo systemctl enable tomcat --now

Check the service status.

$ sudo systemctl status tomcat
? tomcat.service - Apache Tomcat 9 Servlet container
   Loaded: loaded (/etc/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2022-03-09 09:48:38 UTC; 8s ago
  Process: 25308 ExecStart=/opt/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 25315 (java)
    Tasks: 29 (limit: 11412)
   Memory: 154.9M
   CGroup: /system.slice/tomcat.service
           ??25315 /usr/lib/jvm/jre/bin/java -Djava.util.logging.config.file=/opt/tomcat/conf/logging.properties ..

Mar 09 09:48:38 guacamole systemd[1]: Starting Apache Tomcat 9 Servlet container...
Mar 09 09:48:38 guacamole systemd[1]: Started Apache Tomcat 9 Servlet container.

Step 4 - Download and Build Guacamole

You can obtain the latest stable version of Guacamole from its website. At the time of writing this tutorial, the latest version available was 1.4.0. Download the Guacamole source code.

$ GVERSION=1.4.0
$ wget https://downloads.apache.org/guacamole/${GVERSION}/source/guacamole-server-${GVERSION}.tar.gz

Extract the archive and switch to the newly-created directory.

$ tar -xzf guacamole-server-${GVERSION}.tar.gz
$ cd guacamole-server-${GVERSION}/

Run the configure command to determine which libraries are available and to select components for building.

$ ./configure --with-systemd-dir=/etc/systemd/system/

The directory /etc/systemd/system/ is where the startup script will be installed during the build process to configure Guacamole to start automatically on boot.

You will get the following output on successful completion.

checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
...

------------------------------------------------
guacamole-server version 1.4.0
------------------------------------------------

   Library status:

     freerdp2 ............ yes
     pango ............... yes
     libavcodec .......... yes
     libavformat.......... yes
     libavutil ........... yes
     libssh2 ............. yes
     libssl .............. yes
     libswscale .......... yes
     libtelnet ........... yes
     libVNCServer ........ yes
     libvorbis ........... yes
     libpulse ............ yes
     libwebsockets ....... yes
     libwebp ............. yes
     wsock32 ............. no

   Protocol support:

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

   Services / tools:

      guacd ...... yes
      guacenc .... yes
      guaclog .... yes

   FreeRDP plugins: /usr/lib64/freerdp2
   Init scripts: no
   Systemd units: /etc/systemd/system/

Type "make" to compile guacamole-server.

If you don't have some libraries installed, you will see no instead of yes in the output. But if a critical library is missing, the command will fail. To check for more configure options, run the ./configure --help command.

Compile and install the Guacamole server by using the following commands.

$ make && sudo make install

Run the following command to update the system's cache of installed libraries.

$ sudo ldconfig

Reload the service daemon.

$ sudo systemctl daemon-reload

Enable and start the Guacamole service.

$ sudo systemctl enable guacd --now

Verify the status of the service.

$ sudo systemctl status guacd
? guacd.service - Guacamole Server
   Loaded: loaded (/etc/systemd/system/guacd.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2022-03-10 09:13:41 UTC; 7s ago
     Docs: man:guacd(8)
 Main PID: 85349 (guacd)
    Tasks: 1 (limit: 11181)
   Memory: 10.8M
   CGroup: /system.slice/guacd.service
           ??85349 /usr/local/sbin/guacd -f

Mar 10 09:13:41 guacamole systemd[1]: Started Guacamole Server.
Mar 10 09:13:41 guacamole guacd[85349]: Guacamole proxy daemon (guacd) version 1.4.0 started
Mar 10 09:13:41 guacamole guacd[85349]: guacd[85349]: INFO:        Guacamole proxy daemon (guacd) version 1.4.0 started
Mar 10 09:13:41 guacamole guacd[85349]: guacd[85349]: INFO:        Listening on host ::1, port 4822
Mar 10 09:13:41 guacamole guacd[85349]: Listening on host ::1, port 4822

Step 5 - Install Guacamole Client

Now that you have installed the server, the next step is to install the client.

Create the configuration directory for Guacamole.

$ sudo mkdir /etc/guacamole

Unlike the Guacamole server, the Guacamole client is available in source code and binary form. For our tutorial, we will download the binary. You can, however, choose to build the client from the source.

Download the Guacamole client binary from the website.

$ sudo wget https://downloads.apache.org/guacamole/${GVERSION}/binary/guacamole-${GVERSION}.war -O /etc/guacamole/guacamole.war

The above command downloads and copies the Guacamole binary file to the /etc/guacamole directory.

For the client to function, it needs to be deployed from Tomcat's directory, which is $CATALINA_HOME/webapps/. In Step 3, we set /opt/tomcat as $CATALINA_HOME.

Run the following command to create a symbolic link from /etc/guacamole/guacamole.war to the Tomcat webapps directory.

$ sudo ln -s /etc/guacamole/guacamole.war /opt/tomcat/webapps/

Change the permission of the app to tomcat user.

$ sudo chown -R tomcat:tomcat /opt/tomcat/webapps

Create the web application configuration file at /etc/guacamole/guacd.conf.

$ sudo nano /etc/guacamole/guacd.conf

Paste the following code in it. Replace your_server_IP with your server's public IP address.

#
# guacd configuration file
#

[daemon]

#pid_file = /var/run/guacd.pid
log_level = info

[server]

bind_host = your_server_IP
bind_port = 4822

#
# The following parameters are valid only if
# guacd was built with SSL support.
#

# [ssl]

# server_certificate = /etc/ssl/certs/guacd.crt
# server_key = /etc/ssl/private/guacd.key

Save the file by pressing Ctrl + X and entering Y when prompted to save.

Restart the Guacamole server and Tomcat to apply the changes.

$ sudo systemctl restart tomcat guacd

Step 6 - Install and Configure MySQL

Apache Guacamole offers various types of authentication methods. For testing purposes, simple password-based authentication is sufficient. But for production environments, we need to implement a stronger and better method of authentication. Here, we will implement database-based authentication using MySQL.

Install MySQL.

$ sudo dnf install mysql-server

Enable and start the MySQL service.

$ sudo systemctl enable mysqld --now

Secure MySQL installation.

$ sudo mysql_secure_installation

For the first step, you will be asked if you want to set up the Validate Password Plugin, which you can use to test the strength of your MySQL password. Choose Y to proceed. You will be asked to choose the password validation level in the next step. Choose 2 which is the strongest level and will require your password to be at least eight characters long and include a mix of uppercase, lowercase, numeric and special characters.

Securing the MySQL server deployment.

Connecting to MySQL using a blank password.

VALIDATE PASSWORD COMPONENT can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD component?

Press y|Y for Yes, any other key for No: Y

There are three levels of password validation policy:

LOW    Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary                  file

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2

You will be asked to choose a root password in the next step. Choose a strong password that fulfills the requirements of the password validation plugin. In the next step, you will be asked whether to continue with the chosen password. Press y to continue.

Please set the password for root here.

New password:

Re-enter new password:

Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y

Press Y and then ENTER key for all the following prompts to remove anonymous users and the test database, disable root logins and load the newly set rules.

...
Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y
Success.
...
Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y
Success.
...
Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y
 - Dropping test database...
Success.
 - Removing privileges on test database...
Success.
Reloading the privilege tables will ensure that all changes
made so far will take effect immediately.
...
Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y
Success.
All done!

Enter the MySQL shell. Enter your root password to continue.

$ mysql -u root -p

Create guacamole_user user. Make sure the password meets the requirements set before.

mysql> CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'Your_password2';

Create guacamole_db database.

mysql> CREATE DATABASE guacamole_db;

Grant the user privileges on the guacamole_db database.

mysql> GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost';

Exit the Shell.

mysql> exit

Step 7 - Configure Apache Guacamole

Guacamole's configuration directory is defined by the variable, GUACAMOLE_HOME. All the configuration files, extensions, etc., are in this directory. The /etc/guacamole/guacamole.properties file stores all the configurations and settings for Guacamole and its extensions.

Extensions and libraries require additional directories. Create them.

$ sudo mkdir /etc/guacamole/{extensions,lib}

Set the Guacamole home variable and store it in the /etc/default/tomcat configuration file.

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

Configure Apache Guacamole Database Authentication

We have already set up the database for Guacamole in the previous step. We need to download the Guacamole JDBC authenticator plugin and the MySQL Java Connector library to complete the configuration.

Download the Guacamole JDBC Plugin from its website.

$ cd ~
$ wget https://downloads.apache.org/guacamole/${GVERSION}/binary/guacamole-auth-jdbc-${GVERSION}.tar.gz

Extract the plugin to the /etc/guacamole/extensions directory.

$ tar -xf guacamole-auth-