Apache Guacamole
Clientless Remote Desktop Gateway
Deploy Apache Guacamole to access your servers through a web browser using VNC, RDP, and SSH protocols. No client software required—just HTML5.
What is Apache Guacamole?
Apache Guacamole is a clientless remote desktop gateway that allows you to access your servers through a web browser using protocols like VNC, RDP, and SSH. Unlike traditional remote desktop solutions that require client software installation, Guacamole provides remote access through HTML5, making it perfect for accessing your infrastructure from any device with a modern web browser.
Architecture Overview
guacamole-server
The native backend that handles remote desktop protocols (VNC, RDP, SSH).
guacamole-client
The Java web application that serves the HTML5 interface.
Both components communicate via the Guacamole protocol, with connection information stored in a MySQL/PostgreSQL database.
Prerequisites
- A RamNode VPS with at least 2GB RAM (4GB recommended for production)
- Ubuntu 22.04 LTS or Ubuntu 24.04 LTS
- Root or sudo access to your server
- A domain name pointed to your VPS (optional but recommended for SSL)
- Basic knowledge of Linux command line
Initial Server Setup
Update your system and install required dependencies:
sudo apt update && sudo apt upgrade -y sudo apt install -y build-essential libcairo2-dev libjpeg-turbo8-dev \ libpng-dev libtool-bin uuid-dev 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 libossp-uuid-dev
Install Tomcat
Guacamole requires a servlet container. We'll use Apache Tomcat 9:
# Install Tomcat sudo apt install -y tomcat9 tomcat9-admin tomcat9-common tomcat9-user # Start and enable Tomcat sudo systemctl start tomcat9 sudo systemctl enable tomcat9
Verify Tomcat is running:
sudo systemctl status tomcat9
Install MySQL Database
Install and configure MySQL to store Guacamole's connection and user data:
# Install MySQL sudo apt install -y mysql-server # Secure MySQL installation sudo mysql_secure_installation
During the secure installation:
- Set a strong root password
- Remove anonymous users: Yes
- Disallow root login remotely: Yes
- Remove test database: Yes
- Reload privilege tables: Yes
Create the Guacamole database and user:
sudo mysql -u root -p # Execute the following SQL commands: CREATE DATABASE guacamole_db; CREATE USER 'guacamole_user'@'localhost' IDENTIFIED BY 'StrongPasswordHere'; GRANT SELECT,INSERT,UPDATE,DELETE ON guacamole_db.* TO 'guacamole_user'@'localhost'; FLUSH PRIVILEGES; EXIT;
Download and Compile guacamole-server
# Set version variable
GUAC_VERSION="1.5.5"
# Download and extract
cd /tmp
wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/source/guacamole-server-${GUAC_VERSION}.tar.gz
tar -xzf guacamole-server-${GUAC_VERSION}.tar.gz
cd guacamole-server-${GUAC_VERSION}Configure and compile:
./configure --with-init-dir=/etc/init.d --enable-allow-freerdp-snapshots make sudo make install
Update library cache and reload systemd:
sudo ldconfig sudo systemctl daemon-reload sudo systemctl enable guacd sudo systemctl start guacd
Install guacamole-client
cd /tmp
wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/binary/guacamole-${GUAC_VERSION}.war
sudo mv guacamole-${GUAC_VERSION}.war /var/lib/tomcat9/webapps/guacamole.warCreate the Guacamole configuration directory:
sudo mkdir -p /etc/guacamole/{extensions,lib}Configure MySQL Authentication
cd /tmp
wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/binary/guacamole-auth-jdbc-${GUAC_VERSION}.tar.gz
tar -xzf guacamole-auth-jdbc-${GUAC_VERSION}.tar.gzDownload MySQL connector and copy files:
# Download MySQL connector
wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-8.2.0.tar.gz
tar -xzf mysql-connector-j-8.2.0.tar.gz
# Copy files to Guacamole directories
sudo cp guacamole-auth-jdbc-${GUAC_VERSION}/mysql/guacamole-auth-jdbc-mysql-${GUAC_VERSION}.jar /etc/guacamole/extensions/
sudo cp mysql-connector-j-8.2.0/mysql-connector-j-8.2.0.jar /etc/guacamole/lib/Initialize the database schema:
cd guacamole-auth-jdbc-${GUAC_VERSION}/mysql/schema
cat *.sql | sudo mysql -u root -p guacamole_dbConfigure Guacamole
Create the main configuration file:
# MySQL properties mysql-hostname: localhost mysql-port: 3306 mysql-database: guacamole_db mysql-username: guacamole_user mysql-password: StrongPasswordHere # Additional settings mysql-default-max-connections-per-user: 0 mysql-default-max-group-connections-per-user: 0
Create symbolic link and set permissions:
sudo ln -s /etc/guacamole /usr/share/tomcat9/.guacamole # Set proper permissions sudo chown -R tomcat:tomcat /etc/guacamole sudo chown -R tomcat:tomcat /var/lib/tomcat9/webapps/guacamole.war # Restart services sudo systemctl restart tomcat9 sudo systemctl restart guacd
Configure Firewall
sudo ufw allow 8080/tcp # Tomcat (temporary - use nginx proxy in production) sudo ufw allow 22/tcp # SSH sudo ufw enable
Access Guacamole
Access Guacamole through your web browser:
http://your-server-ip:8080/guacamole
Default Credentials:
- Username: guacadmin
- Password: guacadmin
IMPORTANT: Change the default password immediately after first login!
Nginx Reverse Proxy with SSL
Set Up Nginx Reverse Proxy
sudo apt install -y nginx certbot python3-certbot-nginx
Create Nginx configuration:
server {
listen 80;
server_name guacamole.yourdomain.com;
location / {
proxy_pass http://localhost: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;
proxy_cookie_path /guacamole/ /;
access_log off;
}
}Enable the site and obtain SSL certificate:
sudo ln -s /etc/nginx/sites-available/guacamole /etc/nginx/sites-enabled/ sudo nginx -t sudo systemctl restart nginx # Obtain SSL certificate sudo certbot --nginx -d guacamole.yourdomain.com
Update firewall rules:
sudo ufw allow 'Nginx Full' sudo ufw delete allow 8080/tcp sudo ufw reload
Configuring Connections
Adding an SSH Connection
- Log into Guacamole
- Click "Settings" in the top-right
- Select "Connections" → "New Connection"
- Fill in the details:
- Name: Descriptive name for the connection
- Protocol: SSH
- Hostname: Target server IP or hostname
- Port: 22 (default)
- Username: SSH username
- Password or Private key: Authentication method
Adding an RDP Connection
For Windows servers:
- Protocol: RDP
- Hostname: Windows server IP
- Port: 3389
- Username: Windows username
- Password: Windows password
- Security mode: Any
- Ignore server certificate: Yes (for testing)
Adding a VNC Connection
- Protocol: VNC
- Hostname: VNC server IP
- Port: 5901 (or your VNC port)
- Password: VNC password
Security Hardening
1. Two-Factor Authentication
Install the TOTP extension for 2FA:
cd /tmp
wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/binary/guacamole-auth-totp-${GUAC_VERSION}.tar.gz
tar -xzf guacamole-auth-totp-${GUAC_VERSION}.tar.gz
sudo cp guacamole-auth-totp-${GUAC_VERSION}/guacamole-auth-totp-${GUAC_VERSION}.jar /etc/guacamole/extensions/
sudo systemctl restart tomcat9Users can now enable 2FA in their settings.
2. Restrict Tomcat to Localhost
Edit /etc/tomcat9/server.xml and modify the Connector element:
<Connector port="8080" protocol="HTTP/1.1"
address="127.0.0.1"
connectionTimeout="20000"
redirectPort="8443" />sudo systemctl restart tomcat9
3. Configure Connection Limits
Add to /etc/guacamole/guacamole.properties:
# Limit concurrent connections mysql-default-max-connections: 10 mysql-default-max-connections-per-user: 2 # Session timeout (in minutes) api-session-timeout: 60
Troubleshooting
Guacamole Not Loading
# Check Tomcat logs sudo tail -f /var/log/tomcat9/catalina.out # Verify guacd is running sudo systemctl status guacd
Connection Failed Errors
# Check guacd logs sudo journalctl -u guacd -n 50 # Verify target server is reachable telnet target-server-ip 22 # For SSH telnet target-server-ip 3389 # For RDP
Database Connection Issues
# Test MySQL connectivity mysql -u guacamole_user -p guacamole_db # Check MySQL is listening sudo netstat -tlnp | grep 3306
Slow Performance
Increase Tomcat memory in /etc/default/tomcat9:
JAVA_OPTS="-Djava.awt.headless=true -Xmx2048m -XX:+UseConcMarkSweepGC"
sudo systemctl restart tomcat9
Backup and Maintenance
Backup Database
Create automated backups
#!/bin/bash BACKUP_DIR="/var/backups/guacamole" DATE=$(date +%Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR # Backup database mysqldump -u guacamole_user -p'StrongPasswordHere' guacamole_db > $BACKUP_DIR/guacamole_db_$DATE.sql # Backup configuration tar -czf $BACKUP_DIR/guacamole_config_$DATE.tar.gz /etc/guacamole/ # Keep only last 30 days find $BACKUP_DIR -name "*.sql" -mtime +30 -delete find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
Make executable and add to cron:
sudo chmod +x /usr/local/bin/backup-guacamole.sh sudo crontab -e # Add daily backup at 2 AM: 0 2 * * * /usr/local/bin/backup-guacamole.sh
Monitoring
# Check if services are running sudo systemctl is-active guacd tomcat9 mysql nginx # Monitor resource usage htop # Check connection count mysql -u guacamole_user -p'StrongPasswordHere' guacamole_db -e \ "SELECT COUNT(*) as active_connections FROM guacamole_connection"
Advanced Configuration
LDAP/Active Directory Integration
cd /tmp
wget https://downloads.apache.org/guacamole/${GUAC_VERSION}/binary/guacamole-auth-ldap-${GUAC_VERSION}.tar.gz
tar -xzf guacamole-auth-ldap-${GUAC_VERSION}.tar.gz
sudo cp guacamole-auth-ldap-${GUAC_VERSION}/guacamole-auth-ldap-${GUAC_VERSION}.jar /etc/guacamole/extensions/Add to guacamole.properties:
# LDAP configuration ldap-hostname: ldap.yourdomain.com ldap-port: 389 ldap-username-attribute: sAMAccountName ldap-encryption-method: none ldap-search-bind-dn: cn=admin,dc=yourdomain,dc=com ldap-search-bind-password: ldap_password ldap-user-base-dn: ou=users,dc=yourdomain,dc=com
Connection Recording
sudo mkdir -p /var/guacamole/recordings sudo chown -R tomcat:tomcat /var/guacamole
Add to guacamole.properties:
recording-path: /var/guacamole/recordings create-recording-path: true
Configure per-connection in the GUI under "Screen recording" settings.
Key Takeaways
- Always use SSL/TLS in production (Nginx reverse proxy with Let's Encrypt)
- Change default credentials immediately
- Enable 2FA for additional security
- Regular backups of the database are essential
- Monitor resource usage and adjust as needed
- Keep Guacamole and all dependencies updated
