SSL termination is the recommended method of encrypting communication between users’ browsers and Guacamole, and involves configuring a reverse proxy like Nginx or Apache to handle strictly the SSL/TLS portion of the conversation with the Tomcat instance hosting Guacamole, handling encrypted HTTP externally while passing unencrypted HTTP to Tomcat internally.

This documentation deals with configuring Apache to handle SSL/TLS termination for Guacamole, and assumes that you already have an Apache server properly configured for SSL/TLS, including the necessary private key and certificate. If you have not already done so, be sure to set up both Apache and Guacamole, confirming that each works properly independently before proceeding.

Proxying Guacamole through Apache

If Apache has been configured for SSL/TLS, there should be a <VirtualHost> section within this configuration that defines the certificate and private key used by Apache, and which requires Apache to listen on the standard HTTPS port (443). To proxy Guacamole through Apache such that Guacamole communication is encrypted, two additional <Location> sections will need to be added within this <VirtualHost> section:

<Location /guacamole/>
    Order allow,deny
    Allow from all
    ProxyPass http://HOSTNAME:8080/guacamole/ flushpackets=on
    ProxyPassReverse http://HOSTNAME:8080/guacamole/
</Location>

<Location /guacamole/websocket-tunnel>
    Order allow,deny
    Allow from all
    ProxyPass ws://HOSTNAME:8080/guacamole/websocket-tunnel
    ProxyPassReverse ws://HOSTNAME:8080/guacamole/websocket-tunnel
</Location>

where “HOSTNAME” is the hostname or IP address of the internal Guacamole server.

These <Location> sections configure proxying of the HTTP and WebSocket protocols respectively. Apache handles the HTTP and WebSocket protocols separately, and thus requires separate configuration for the portion of the web application which uses WebSocket. Both sections are required for Guacamole to work correctly behind Apache, and the mod_proxy_wstunnel module must be installed and enabled.

Of particular importance is the flushpackets=on option within the ProxyPass directive used for HTTP in front of Guacamole. This option disables buffering of packets sent to/from Guacamole. By default, Apache will buffer communication between itself and the browser, effectively disrupting the stream of events and updates required for remote desktop. Without disabling buffering, the Guacamole connection will at best be slow, and at worst not function at all.

With minor changes to each <Location> section, Apache can also be leveraged to change the path used for Guacamole. Doing so requires only changing the path specified for each <Location> section header, and adding the ProxyPassReverseCookiePath directive to rewrite the paths of any cookies set by the web application:

<Location /new-path/>
    Order allow,deny
    Allow from all
    ProxyPass http://HOSTNAME:8080/guacamole/ flushpackets=on
    ProxyPassReverse http://HOSTNAME:8080/guacamole/
    ProxyPassReverseCookiePath /guacamole/ /new-path/
</Location>

<Location /new-path/websocket-tunnel>
    Order allow,deny
    Allow from all
    ProxyPass ws://HOSTNAME:8080/guacamole/websocket-tunnel
    ProxyPassReverse ws://HOSTNAME:8080/guacamole/websocket-tunnel
    ProxyPassReverseCookiePath /guacamole/ /new-path/
</Location>

Applying the updated configuration

After the above changes have been made, Apache must be reloaded to force rereading of its configuration files:

$ sudo systemctl reload httpd

If you are using SELinux (the default on both CentOS and RHEL), you must also configure SELinux to allow HTTPD implementations like Apache to establish network connections:

$ sudo setsebool -P httpd_can_network_connect 1

If Guacamole is not accessible through Apache after the service has been reloaded, check the Apache logs and/or journalctl to verify that the syntax of your configuration changes is correct. Such errors will result in Apache refusing to reload its configuration, or refusing to start up entirely. If you do not see any errors from Apache, verify that you have configured SELinux to allow Apache to connect to the network and check the SELinux audit logs (/var/log/audit/audit.log) for AVC denials.