Apache Guacamole + PopOS RDP Setup Tutorial
A quick guide to set up clientless remote desktop access via web browser using Apache Guacamole and PopOS.
Overview
- Guacamole: Web-based remote desktop gateway (HTML5, no client software needed)
- Target: PopOS with xrdp server
- Access: Any device with a web browser
- Supports: RDP, VNC, SSH, Telnet, Kubernetes connections
1. PopOS RDP Server Setup
Install and Configure xrdp
# Install xrdp (more reliable than GNOME Remote Desktop)
sudo apt update
sudo apt install xrdp
# Start and enable service
sudo systemctl enable xrdp
sudo systemctl start xrdp
# Verify service
sudo systemctl status xrdp
sudo netstat -tlnp | grep 3389
Fix PolicyKit Permission Issues
Create /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
:
[Allow Colord All Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.*
ResultAny=no
ResultInactive=no
ResultActive=yes
[Allow PackageKit All Users]
Identity=unix-user:*
Action=org.freedesktop.packagekit.*
ResultAny=no
ResultInactive=no
ResultActive=yes
Optional: Firewall Configuration
# Usually NOT needed if using Docker with LAN IP
# Only open if external access required
sudo ufw allow 3389
2. Guacamole Docker Setup
Updated Docker Compose Configuration
services:
guacdb:
container_name: guacamoledb
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'MariaDBRootPass2024'
MYSQL_DATABASE: 'guacamole_db'
MYSQL_USER: 'guacamole_user'
MYSQL_PASSWORD: 'MariaDBUserPass2024'
volumes:
- db-data:/var/lib/mysql
networks:
- guacamole-network
guacd:
container_name: guacd
image: guacamole/guacd:1.6.0
restart: unless-stopped
networks:
- guacamole-network
guacamole:
container_name: guacamole
image: guacamole/guacamole:1.6.0
restart: unless-stopped
ports:
- "8080:8080"
environment:
GUACD_HOSTNAME: "guacd"
MYSQL_HOSTNAME: "guacdb"
MYSQL_DATABASE: "guacamole_db"
MYSQL_USER: "guacamole_user"
MYSQL_PASSWORD: "MariaDBUserPass2024"
TOTP_ENABLED: "true"
WEBAPP_CONTEXT: "ROOT" # Access via http://localhost:8080
depends_on:
- guacdb
- guacd
networks:
- guacamole-network
networks:
guacamole-network:
driver: bridge
volumes:
db-data:
Database Initialization (Correct Method)
# 1. Create directory and setup
mkdir guacamole
cd guacamole
# 2. Generate database initialization file
docker run --rm guacamole/guacamole:1.6.0 /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
# 3. Start services
docker-compose up -d
# 4. Wait for database to be ready
sleep 30
# 5. Import database schema (no docker cp needed!)
docker exec -i guacamoledb mysql -u root -pMariaDBRootPass2024 guacamole_db < initdb.sql
# 6. Verify tables created
docker exec -it guacamoledb mysql -u root -pMariaDBRootPass2024 -e "USE guacamole_db; SHOW TABLES;"
3. Guacamole Configuration
Initial Setup
- Access Guacamole:
http://localhost:8080
(note: no /guacamole suffix!) - Default login:
guacadmin
/guacadmin
- Important: Change default password immediately
Create RDP Connection
-
Go to Settings → Connections → New Connection
-
Edit Connection:
- Name:
PopOS Desktop
(or any name) - Protocol:
RDP
- Name:
-
Parameters:
- Hostname: Use actual LAN IP (e.g.,
192.168.1.100
) - Port:
3389
- Username: Your PopOS username
- Password: Your PopOS password
- Hostname: Use actual LAN IP (e.g.,
-
Optional Settings:
- Security mode:
any
orrdp
- Ignore server certificate: ✓ (check)
- Disable authentication: ✓ (if needed)
- Security mode:
Guacamole Proxy Parameters
- Usually leave empty (Hostname, Port, Encryption fields)
- Only configure if guacd runs on different server
4. Critical Network Configuration Notes
⚠️ Docker Networking Gotchas
- Use IP addresses, not domain names in connection hostname
- If using Tailscale/VPN: Use physical network IP, not VPN IP
- Container DNS resolution may point to unreachable networks
- Docker can access host ports via LAN IP without firewall rules
Example IP Discovery
# Find your PopOS IP
ip addr show | grep "inet 192"
# Use this IP in Guacamole connection, not localhost or domain names
5. Testing
Verify RDP Service
# On PopOS, test local RDP
telnet localhost 3389
Test Guacamole Connection
- Login to Guacamole web interface
- Click your connection
- Should see PopOS desktop in browser
Troubleshooting
Common Issues
- "Non-numeric character in element length": Version mismatch or network issue
- "Connection refused": Check xrdp service and firewall
- PolicyKit password prompts: Add polkit configuration above
- Black screen: Try different security mode settings
- Slow performance: Normal on high-latency networks, excellent on LAN
Debug Commands
# Check xrdp status
sudo systemctl status xrdp
# Check port listening
sudo netstat -tlnp | grep 3389
# Check Guacamole logs
docker logs guacamole
docker logs guacd
# Restart PolicyKit (if needed)
sudo systemctl restart polkitd
# Or simply reboot
sudo reboot
Production Enhancements
Nginx Reverse Proxy (Optional)
Add HTTPS and custom domain access:
server {
listen 443 ssl;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
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;
}
}
Performance Notes
- Excellent for: Office work, programming, system administration
- Good for: General desktop use on LAN
- Not ideal for: High-framerate gaming, video streaming
- Best on: Local network with low latency
Supported Protocols
- RDP: Windows/Linux remote desktop
- VNC: Cross-platform graphical access
- SSH: Terminal access with file transfer
- Telnet: Legacy terminal protocol
- Kubernetes: Container orchestration access
Security Considerations
- Change default Guacamole passwords
- Use HTTPS in production (add reverse proxy)
- Consider VPN access for external connections
- Regularly update Docker images
- PolicyKit configuration limits privilege escalation
Setup tested on PopOS 22.04 with Guacamole 1.6.0 via Docker
Key Sources:
- Jeppson Tech Blog
- Docker best practices and real-world testing