Skip to content

Instantly share code, notes, and snippets.

@u1i
Created June 1, 2025 04:11
Show Gist options
  • Save u1i/190b29e920a18a9c7c7bd4123e8bdd96 to your computer and use it in GitHub Desktop.
Save u1i/190b29e920a18a9c7c7bd4123e8bdd96 to your computer and use it in GitHub Desktop.
Linux Multi-User VNC Setup
# Multi-User VNC Setup Guide
Complete setup for 20 concurrent VNC sessions with web access via Cloudflare tunnel on Ubuntu 24.04 LTS.
## Prerequisites
- Bare metal Ubuntu 24.04 LTS server
- SSH access as root
- Domain configured with Cloudflare
## Step 1: Update System
```bash
apt-get update
```
## Step 2: Install X11 and XFCE Desktop Environment
```bash
apt install xfce4 xfce4-goodies xorg dbus-x11 x11-xserver-utils
```
## Step 3: Install VNC Server
```bash
apt install tightvncserver
```
## Step 4: Fix VNC Font Issues
```bash
apt install xfonts-base xfonts-75dpi xfonts-100dpi
```
## Step 5: Create VNC User
```bash
adduser vnc-user1
usermod -aG sudo vnc-user1
```
## Step 6: Configure VNC for Single User (Test)
Switch to the user:
```bash
su - vnc-user1
```
Create VNC startup script:
```bash
mkdir -p ~/.vnc
cat > ~/.vnc/xstartup << 'EOF'
#!/bin/bash
xrdb $HOME/.Xresources
startxfce4 &
EOF
chmod +x ~/.vnc/xstartup
```
Start VNC (localhost only):
```bash
vncserver :1 -localhost
```
Set VNC password when prompted.
Exit back to root:
```bash
exit
```
## Step 7: Install noVNC and WebSocket Proxy
```bash
apt install novnc python3-websockify
```
## Step 8: Test Single Session
Start noVNC web server:
```bash
websockify --web=/usr/share/novnc/ 8080 localhost:5901
```
Test locally:
```bash
curl -I localhost:8080
```
Kill the test session:
```bash
su - vnc-user1 -c "vncserver -kill :1"
```
## Step 9: Create Multiple VNC Sessions Script
Create the setup script:
```bash
cat > /root/setup-vnc-sessions.sh << 'EOF'
#!/bin/bash
echo "Setting up 20 VNC sessions..."
# Kill any existing sessions
su - vnc-user1 -c "vncserver -kill :*" 2>/dev/null || true
# Start 20 VNC sessions
for i in {1..20}; do
echo "Starting VNC session :$i"
su - vnc-user1 -c "vncserver :$i -localhost"
done
echo "VNC sessions created on displays :1 through :20"
echo "Ports: 5901-5920"
EOF
chmod +x /root/setup-vnc-sessions.sh
```
## Step 10: Run VNC Sessions Setup
```bash
./root/setup-vnc-sessions.sh
```
## Step 11: Install Cloudflared
```bash
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb
```
If dependencies are missing:
```bash
apt-get install -f
```
## Step 12: Setup Cloudflare Tunnel
Authenticate with Cloudflare:
```bash
cloudflared tunnel login
```
Create tunnel:
```bash
cloudflared tunnel create vnc-tunnel
```
Configure tunnel (replace YOUR_TUNNEL_ID with actual tunnel ID):
```bash
cat > ~/.cloudflared/config.yml << 'EOF'
tunnel: YOUR_TUNNEL_ID
credentials-file: /root/.cloudflared/YOUR_TUNNEL_ID.json
ingress:
- hostname: subdomain.yourdomain.com
service: http://localhost:8080
- service: http_status:404
EOF
```
Add DNS record:
```bash
cloudflared tunnel route dns vnc-tunnel subdomain.yourdomain.com
```
## Step 13: Start Services
Start noVNC (without auto-connecting to specific session):
```bash
websockify --web=/usr/share/novnc/ 8080 &
```
Start Cloudflare tunnel:
```bash
cloudflared tunnel run vnc-tunnel &
```
## Step 14: Create Service Files (Optional)
Create systemd service for noVNC:
```bash
cat > /etc/systemd/system/novnc.service << 'EOF'
[Unit]
Description=noVNC WebSocket Proxy
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/bin/websockify --web=/usr/share/novnc/ 8080
Restart=always
[Install]
WantedBy=multi-user.target
EOF
```
Create systemd service for Cloudflare tunnel:
```bash
cat > /etc/systemd/system/cloudflared.service << 'EOF'
[Unit]
Description=Cloudflare Tunnel
After=network.target
[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/cloudflared tunnel run vnc-tunnel
Restart=always
[Install]
WantedBy=multi-user.target
EOF
```
Enable and start services:
```bash
systemctl enable novnc cloudflared
systemctl start novnc cloudflared
```
## Usage
### For Users:
1. Navigate to: `https://subdomain.yourdomain.com`
2. Click "Connect"
3. Enter connection details:
- **Host:** `localhost`
- **Port:** `5901` (for session :1), `5902` (for session :2), etc.
- **Password:** The VNC password set during setup
### Session Assignment:
- User 1: Port 5901 (Display :1)
- User 2: Port 5902 (Display :2)
- ...
- User 20: Port 5920 (Display :20)
## Management Commands
### Check VNC sessions:
```bash
su - vnc-user1 -c "ps aux | grep Xtightvnc"
```
### Restart all VNC sessions:
```bash
./root/setup-vnc-sessions.sh
```
### Check noVNC status:
```bash
curl -I localhost:8080
```
### Check tunnel status:
```bash
cloudflared tunnel info vnc-tunnel
```
## Security Notes
- VNC sessions are bound to localhost only (`-localhost` flag)
- Only accessible via Cloudflare tunnel (encrypted HTTPS)
- Each user should use a unique VNC session/port
- Consider implementing user authentication at the web level if needed
## Troubleshooting
### VNC session won't start:
- Check font packages are installed
- Verify XFCE is properly installed
- Check `~/.vnc/*.log` for errors
### noVNC won't connect:
- Verify websockify is running on port 8080
- Check that VNC session is running on the specified port
- Ensure localhost binding is working
### Cloudflare tunnel issues:
- Verify tunnel configuration in `~/.cloudflared/config.yml`
- Check DNS record is properly set
- Review cloudflared logs: `journalctl -u cloudflared`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment