Apache Guacamole is software developed by the Apache organization for clientless remote desktop use (we call it clientless because no plugins or client software are required). It supports standard protocols such as VNC, RDP and SSH.
Thanks to HTML5, once Guacamole is installed on a server, all you need to access your desktops is a web browser.
You can install it natively, with Docker or NGINX Proxy, and the required libraries are Cairo, libjpeg, libpng and OSSP UUID.
Required library packages by operating system
Ubuntu: libcairo2-dev libjpeg-turbo8-dev libjpeg62-dev libpng12-dev libtool-bin libossp-uuid-dev
Debian: libcairo2-dev libjpeg62-turbo-dev libjpeg62-dev libpng12-dev libtool-bin libossp-uuid-dev
Fedora/CentOS: cairo-devel libjpeg-devel libpng-devel libtool uuid-devel
Note:
If libjpeg-turbo is not available on your platform and you do not want to compile it from source, libjpeg will also work, although it will not be as fast.
Optional dependencies:
Guacamole's optional dependencies determine which parts of guacamole-server will be used. This includes support for various remote desktop protocols, as well as any additional features of those protocols:
- VNC support depends on the libvncclient library, which is part of libVNCServer.
- RDP support depends on a recent version of FreeRDP (1.0 or higher, but not an unreleased version from git).
- SSH support depends on libssh2, OpenSSL and Pango (a text layout and font rendering library used by Guacamole's built-in terminal emulator).
- Telnet depends on libtelnet and Pango.
- Kubernetes support depends on libwebsockets, OpenSSL and Pango.
The guacenc utility, provided by guacamole-server to convert screen recordings into video, depends on FFmpeg and will only be built if at least the libavcodec, libavformat, libavutil and libswscale libraries provided by FFmpeg are installed.
Important
If you do not have these dependencies, the features or protocols that depend on them will not be enabled. Read this section carefully before deciding not to install an optional dependency.
Debian/Ubuntu: libavcodec-dev libavformat-dev libavutil-dev libswscale-dev freerdp2-dev libpango1.0-dev libssh2-1-dev libtelnet-dev libvncserver-dev libwebsockets-dev libpulse-dev libssl-dev libvorbis-dev libwebp-dev
Fedora/CentOS: ffmpeg-devel freerdp-devel pango-devel libssh2-devel libtelnet-devel libvncserver-devel libwebsockets-devel pulseaudio-libs-devel openssl-devel libvorbis-devel libwebp-devel
Step-by-step installation and configuration of Apache Guacamole:
The example will use an installation on an Ubuntu 20.04 LTS (64 Bit) server with the preinstalled image, Ubuntu 18.04 Desktop (64 Bit) as a client, and a Windows 2019 Datacenter (English 64Bit) RDP client will also be added.
Installing required packages:
# apt install libcairo2-dev libjpeg-turbo8-dev libjpeg-dev libpng-dev libtool-bin libossp-uuid-dev
Installing optional packages:
# apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev freerdp2-dev libssh2-1-dev libtelnet-dev libvncserver-dev libpulse-dev libssl-dev libvorbis-dev libwebp-dev
Installing required packages:
# apt install libcairo2-dev libjpeg-turbo8-dev libjpeg62-dev libpng12-dev libtool-bin libossp-uuid-dev
Installing optional packages:
# apt install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev freerdp2-dev libssh2-1-dev libtelnet-dev libvncserver-dev libpulse-dev libssl-dev libvorbis-dev libwebp-dev
Download the Guacamole server package (you can find the latest available version at Apache Guacamole Downloads):
# wget https://downloads.apache.org/guacamole/1.5.5/source/guacamole-server-1.5.5.tar.gzExtract the downloaded tar.gz file:
# tar -xvf guacamole-server-1.5.5.tar.gzGo to the extracted directory:
# cd guacamole-server-1.5.5/Configure using the included script:
# ./configure --with-init-dir=/etc/init.dCompile:
# makeInstall the build:
# make installUpdate the library configuration:
# ldconfigReload daemons:
# systemctl daemon-reloadStart and enable:
# systemctl start guacd && systemctl enable guacdCheck the status of the Guacamole service:
# systemctl status guacdVerify operation via the port:
# ss -lnpt | grep guacdInstall tomcat:
# apt install tomcat9 tomcat9-admin tomcat9-common tomcat9-userVerify operation via the port:
# ss -lnpt | grep javaDownload the webapp binary package for tomcat:
# wget https://downloads.apache.org/guacamole/1.5.5/binary/guacamole-1.5.5.warMove it to the tomcat version's directory:
# mv guacamole-1.5.5.war /var/lib/tomcat9/webapps/guacamole.warRestart the service:
# systemctl restart tomcat9 guacdCreate a directory for the configuration files for using guacamole:
# mkdir /etc/guacamole/Create a properties file:
# vi /etc/guacamole/guacamole.propertiesEnter the following information (you can specify the user directory or desired port):
# Hostname and port of guacamole proxy
guacd-hostname: localhost
guacd-port: 4822
# Auth provider class (authenticates user/pass combination, needed if using the provided login screen)
auth-provider: net.sourceforge.guacamole.net.basic.BasicFileAuthenticationProvider
basic-user-mapping: /etc/guacamole/user-mapping.xmlObtain a password for a Guacamole user:
# echo -n CONTRASEÑA | openssl md5Modify the user mapping file:
# vi /etc/guacamole/user-mapping.xmlExample file configuration (entering the password parameter is not necessary):
<user-mapping>
<!-- Per-user authentication and config information -->
<authorize username="admin" password="CONTRASEÑA_EN_MD5" encoding="md5">
<connection name="GuacamoleVNC">
<protocol>vnc</protocol>
<param name="hostname">localhost</param>
<param name="port">5901</param>
<param name="password">XXXX</param>
</connection>
<connection name="GuacamoleSSH">
<protocol>ssh</protocol>
<param name="hostname">localhost</param>
<param name="username">root</param>
<param name="port">22</param>
<param name="password">XXXX</param>
</connection>
<connection name="UbuntuRDP">
<protocol>rdp</protocol>
<param name="hostname">10.20.10.7</param>
<param name="username">xrdpuser</param>
<param name="port">3389</param>
<param name="password">XXXXX</param>
</connection>
<connection name="WindowsRDP">
<protocol>rdp</protocol>
<param name="hostname">10.20.10.5</param>
<param name="port">3389</param>
<param name="username">administrator</param>
<param name="password">XXXX</param>
<param name="ignore-cert">true</param>
</connection>
<connection name="WindowsTELNET">
<protocol>telnet</protocol>
<param name="hostname">10.20.10.5</param>
<param name="port">23</param>
<param name="username">administrator</param>
<param name="password">XXXX</param>
</connection>
</authorize>
</user-mapping>
Change permissions for use by the user only:
# chmod 600 /etc/guacamole/user-mapping.xmlAssign owner and group permissions:
# chown tomcat9:tomcat9 /etc/guacamole/user-mapping.xmlRestart or reload the services:
# systemctl restart tomcat9 guacdAt this point, you should be able to access the web application served by tomcat through port 8080 (Check Firewall) from your browser, displaying the guacamole home page with the configured user and connections when you log in:
For more protection, you can install fail2ban to block connection attempts:
# apt install fail2banReview the configuration file to check whether the jail is active:
# vi /etc/fail2ban/jail.d/defaults-debian.confThe following should appear:
[guacamole]
enabled = true
Check the status using:
# fail2ban-client statusFinally, choose your preferred web server for the reverse proxy:
Quick configuration for Apache Proxy with HTTPS
Installing the service:
# apt install apache2
Enabling modules:
# a2ensite default-ssl && a2enmod ssl && a2enmod proxy && a2enmod proxy_http && a2enmod proxy_balancer && a2enmod lbmethod_byrequests
Restart or reload the service:
# systemctl restart apache2
Modify the default site:
# vi /etc/apache2/sites-available/default-ssl.conf
Enter/modify the basic required configuration:
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SSLEngine on
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
<Location /guacamole/>
Order allow,deny
Allow from all
ProxyPass http://IP:8080/guacamole/ flushpackets=on
ProxyPassReverse http://IP:8080/guacamole/
</Location>
SSLCertificateFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
</IfModule>
To create the Let's Encrypt certificate, you can use the following article depending on the version used, or install the packages required for Let's Encrypt certification:
# apt install certbot python3-certbot-apache
Certify the domain or subdomain using Let's Encrypt:
# certbot --apache -d sub.domain.comQuick configuration for NGINX Proxy with HTTPS
# apt install nginx# vi /etc/nginx/sites-available/defaultserver {
listen 80 default_server;
listen [::]:80 default_server;
return 301 https://sub.domain.com;
}
server {
listen 443 ssl;
server_name sub.domain.com;
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
location / {
proxy_buffering off;
proxy_pass http://localhost:8080/guacamole/;
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;
}
location /.well-known/ {
allow all;
root /var/www/html;
}
}
Installing the packages required for Let's Encrypt certification:
# apt install certbot python3-certbot-nginx
Certify the domain or subdomain using Let's Encrypt:
# certbot --nginx -d sub.domain.com