Remote Desktop Gateway – Apache Guacamole

Apache Guacamole is a Remote Desktop Gateway. The purpose of this application is to provide secure access for enterprise servers to the remote workers. The application supports protocols like SSH, RDP and VNC. The end user only requires an HTML5 capable browser and Internet connection to use the remote gateway and connect with the enterprise servers.

The Guacamole application has two components. One is HTML5 web applications running on java/tomcat. The end users interact with the web application. Second is the proxy daemon which connects with the backend servers over SSH, RDP or VNC protocols.

The following guide outlines the deployment methodology and installation instructions for deploying Apache Guacamole application. The application is deployed on Ubuntu 20.04 server with Guacamole version 1.4.0. The web application is available is a pre-built (.war) but the proxy server needs to be compiled using source code. The application supports LDAP integration and Mysql/MariaDB for storing of user and proxy connection information.

Installation of Guacamole Server Application

The guacamole server application require build tools and development libraries to be compiled successfully and proxy RDP, VNC and SSh connections.

$ sudo apt install build-essential libcairo2-dev libjpeg-turbo8-dev \
libpng-dev libtool-bin libossp-uuid-dev libvncserver-dev freerdp2-dev \
libssh2-1-dev libtelnet-dev libwebsockets-dev libpulse-dev libvorbis-dev \
libwebp-dev libssl-dev libpango1.0-dev libswscale-dev libavcodec-dev \
libavutil-dev libavformat-dev

Download and compile the guacamole server source code.

$ wget https://apache.org/dyn/closer.lua/guacamole/1.4.0/source/guacamole-server-1.4.0.tar.gz
$ cd guacamole-server-1.4.0
$ autoreconf -fi

# Configure Guacamole server installation
$ ./configure --with-init-dir=/etc/init.d

# Compiling the source code
$ make

# Installing guacamole server
$ sudo make install

Update the symbolic links of the system libraries and reload the systemd manager.

$ sudo ldconfig
$ sudo systemctl daemon-reload

Installation of Guacamole Web Application

Install the Apache tomcat server.

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

Download the pre-built guacamole web application and move it into tomcat webapps directory

$ wget https://apache.org/dyn/closer.lua/guacamole/1.4.0/binary/guacamole-1.4.0.war?action=download -O guacamole-1.4.0.war
$ sudo mv guacamole-1.4.0.war /var/lib/tomcat9/webapps/guacamole.war

Enable the tomcat to start on boot and restart the tomcat daemon to deploy the new web application.

$ sudo systemctl enable tomcat9
$ sudo systemctl restart tomcat9

The Guacamole basic setup is done and you can login to the web application using the guacamole server IP, tomcat server port and guacamole web application URL http://192.168.122.56:8080/guacamole/. The default login for the admin is guacadmin with password guacadmin.

Create Guacamole Configuration Directories and Files

Create guacamole base configuration directory with extensions and lib sub-directories.

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

Create configuration files for the web application and proxy daemon.

$ sudo touch /etc/guacamole/guacamole.properties
$ sudo touch /etc/guacamole/guacd.conf

Configure bind IP and port for the guacamole daemon /etc/guacamole/guacd.conf.

[server]
bind_host = 0.0.0.0
bind_port = 4822

Enable and restart guacd service.

$ sudo systemctl enable guacd
$ sudo systemctl restart guacd

Configuring MariaDB Database

MariaDB will be used to store connection information for users. Create a database and configure privileges for the guacamole application on a MariaDB server.

$ sudo mysql -u root -p

# Create Database
MariaDB > CREATE DATABASE guacamole_db;
# Create new user and assign strong password.
MariaDB > CREATE USER 'guacamole'@'localhost' IDENTIFIED BY 'STRONGPASS';
# Allow the user guacamole to access the guacamole database.
MariaDB > GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole'@'%';
# Reload privileges
MariaDB > FLUSH PRIVILEGES;
MariaDB > exit

On the guacamole server download and extract the database extension.

$ wget https://apache.org/dyn/closer.lua/guacamole/1.4.0/binary/guacamole-auth-jdbc-1.4.0.tar.gz?action=download -O guacamole-auth-jdbc-1.4.0.tar.gz
$ tar zxvf guacamole-auth-jdbc-1.4.0.tar.gz

Import the mysql schema from the extracted files.

$ cd guacamole-auth-jdbc-1.4.0/mysql/
$ cat schema/*.sql | mysql -u guacamole -p guacamole_db -h mariadbserver

Copy the database extension from the same mysql directory to guacamole extensions directory.

$ sudo cp guacamole-auth-jdbc-mysql-1.4.0.jar \
/etc/guacamole/extensions/guacamole-auth-jdbc-mysql.jar

Download the mysql java connector from https://dev.mysql.com/downloads/connector/j/ as debian package for Ubuntu 20.04 and install the package.

$ sudo dpkg -i mysql-connector-j_8.0.31-1ubuntu20.04_all.deb 

Copy the MySQL/J connector library to the /etc/guacamole/lib/ directory.

$ sudo cp /usr/share/java/mysql-connector-j-8.0.31.jar \
/etc/guacamole/lib/mysql-connector.jar

Configure database configuration parameters in file /etc/guacamole/guacamole.properties

mysql-hostname: database-server
mysql-port: 3306
mysql-database: guacamole_db
mysql-username: guacamole
mysql-password: STRONGPASS

Configuring LDAP Authentication

Guacamole supports LDAP authentication via LDAP extension. Download the LDAP extension and copy it into guacamole extensions directory.

$ wget https://apache.org/dyn/closer.lua/guacamole/1.4.0/binary/guacamole-auth-ldap-1.4.0.tar.gz?action=download -O guacamole-auth-ldap-1.4.0.tar.gz
$ tar zxvf guacamole-auth-ldap-1.4.0.tar.gz
$ cd guacamole-auth-ldap-1.4.0/
$ sudo cp guacamole-auth-ldap-1.4.0.jar /etc/guacamole/extensions/guacamole-auth-ldap.jar

Edit the file /etc/guacamole/guacamole.properties and configure LDAP connection properties.

# LDAP Configurtions
ldap-hostname: ldapserver.domain.com
ldap-port: 636
ldap-encryption-method: ssl
ldap-search-bind-dn: uid=ldapadmin,cn=sysaccounts,cn=etc,dc=domain,dc=com
ldap-search-bind-password: BINDPASSWORD
ldap-user-base-dn: cn=users,cn=accounts,dc=domain,dc=com
ldap-group-base-dn: cn=groups,cn=accounts,dc=domain,dc=com

The LDAP is configured for secure connection (LDAPS). If you are using self signed certificate the CA Certificate of the LDAP servers need to be added into the java keystore so that the SSL certificates are recognized by the client authenticating with the LDAP servers. Download the CA Certificate from the LDAP server and add it into the keystore. For adding the certificate the keystore password is required and the default password “changeit”.

$ sudo keytool -import  -cacerts  -alias LDAPCA -file ~/ldapca.pem
Enter keystore password: 

Restart the tomcat daemon to load the new extension.

$ sudo systemctl restart tomcat9

Enable Two-Factor Authentication

Guacamole supports two-factor authentication via TOTP extension. The TOTP support needs a database to store the user-generated keys. Make sure the database authentication and connectivity is working before setting up TOTP extension. Download the TOTP extension and copy it into guacamole extensions directory.

$ wget https://apache.org/dyn/closer.lua/guacamole/1.4.0/binary/guacamole-auth-totp-1.4.0.tar.gz?action=download -O tar guacamole-auth-totp-1.4.0.tar.gz
$ tar zxvf guacamole-auth-totp-1.4.0.tar.gz
$ sudo cp guacamole-auth-totp-1.4.0/guacamole-auth-totp-1.4.0.jar \
/etc/guacamole/extensions/guacamole-auth-totp.jar

Restart the tomcat daemon to load the extension. After restart the login will require two factor to be setup for all users. Install two-factor authentication app (Google Authenticator, etc) on mobile phone and login with the guacadmin account. On first login the application will prompt for completing the 2FA using the authentication app. Scan the code in the authentication app and enter the code in the given text box to complete the 2FA setup. For every subsequent login the 2FA code will be required along with the password.

Reverse Proxy Configuration

Guacamole web application can be configured behind NGINX reverse proxy for additional layer of security, SSL termination and High Availability.

Edit tomcat server configuration /usr/share/tomcat9/etc/server.xml and add URIEncoding=”UTF-8″ attribute to ensure that connection names, user names, etc. are properly received by the web application.

<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
URIEncoding="UTF-8"
redirectPort="8443" />

Configure Remote IP Valve in the tomcat server configuration so that tomcat can see the remote client IP connecting via reverse proxy. This needs to be done for auditing purpose. The IP address of the reverse proxies need to be defined in the “trustedProxies” so that the X-Forwarded_For variable is accepted by tomcat from specific host.

<!-- Configuring Tomcat to pass through the remote IP address provided
by the reverse proxy in the X-Forwarded-For header  -->

	<Valve className="org.apache.catalina.valves.RemoteIpValve"
               internalProxies="127.0.0.1"
	       trustedProxies="192.168.122.232"
               remoteIpHeader="x-forwarded-for"
               remoteIpProxiesHeader="x-forwarded-by"
               protocolHeader="x-forwarded-proto" />

On the reverse proxy server configure the proxy parameters in the NGINX site configuration for guacamole web application.

server {
    listen 443 ssl http2;
    server_name  gateway.domain.com;

    ssl_certificate /etc/nginx/certs/webserver.crt;
    ssl_certificate_key /etc/nginx/certs/webserver.key;

    location / {
    	proxy_pass http://192.168.122.56:8080/guacamole/;
    	proxy_buffering off;
    	proxy_http_version 1.1;
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection $http_connection;
    	access_log off;
     }
}

References

https://guacamole.apache.org/doc/gug/installing-guacamole.html
https://adamtheautomator.com/apache-guacamole/

Leave a Reply