← Back to all cheatsheets
Linux
vncremote-desktoptigervnclinuxsecurity

VNC Server Cheat Sheet

Overview

VNC (Virtual Network Computing) provides remote graphical desktop access to Linux servers. It uses the RFB (Remote Framebuffer) protocol to transmit screen updates and receive keyboard/mouse input.

Common VNC Server Implementations

ImplementationDescription
TigerVNCActively maintained, high performance, most recommended
TightVNCOptimized for slow network connections
x11vncShares the existing X display (no virtual display)
TurboVNCOptimized for 3D and video workloads

This cheat sheet focuses primarily on TigerVNC, the most widely used implementation.

How VNC Works

VNC Client (viewer) --> [RFB Protocol / Port 5900+N] --> VNC Server (display :N)
  • Display :1 listens on port 5901
  • Display :2 listens on port 5902
  • Display :0 is typically the physical display

Installation

Ubuntu / Debian

# Install TigerVNC server
sudo apt update
sudo apt install tigervnc-standalone-server tigervnc-common

# Install a desktop environment (if not already installed)
sudo apt install xfce4 xfce4-goodies          # Lightweight
# OR
sudo apt install ubuntu-desktop                 # Full GNOME

RHEL / CentOS / Fedora

# RHEL / CentOS (with EPEL)
sudo dnf install epel-release
sudo dnf install tigervnc-server

# Fedora
sudo dnf install tigervnc-server

# Install a desktop environment
sudo dnf groupinstall "Xfce"                   # Lightweight
# OR
sudo dnf groupinstall "Server with GUI"         # Full GNOME

Arch Linux

sudo pacman -S tigervnc

# Install a desktop environment
sudo pacman -S xfce4 xfce4-goodies

Install x11vnc (Share Existing Display)

# Ubuntu / Debian
sudo apt install x11vnc

# RHEL / CentOS / Fedora
sudo dnf install x11vnc

Basic Usage

Set VNC Password

vncpasswd                                       # Set password for current user
# You'll be prompted to enter and confirm a password
# Optionally set a view-only password when asked

Password is stored in ~/.vnc/passwd.

Start VNC Server

vncserver                                        # Start on next available display
vncserver :1                                     # Start on display :1 (port 5901)
vncserver :2                                     # Start on display :2 (port 5902)
vncserver -geometry 1920x1080                    # Set resolution
vncserver -depth 24                              # Set color depth (8, 16, 24)
vncserver -localhost yes                         # Listen only on localhost (for SSH tunneling)

Stop VNC Server

vncserver -kill :1                               # Kill display :1
vncserver -kill :*                               # Kill all VNC sessions for current user

List Running VNC Sessions

vncserver -list                                  # List active sessions

x11vnc (Share Existing Display)

# Share the current X display
x11vnc -display :0 -auth guess

# With password and forever mode (don't exit after first client disconnects)
x11vnc -display :0 -auth guess -forever -rfbauth ~/.vnc/passwd

# Listen only on localhost
x11vnc -display :0 -auth guess -forever -localhost

Configuration

Key Configuration Files

FilePurpose
~/.vnc/xstartupStartup script — defines which desktop environment to launch
~/.vnc/configDefault VNC server options
~/.vnc/passwdEncrypted VNC password
~/.vnc/*.logSession log files
~/.vnc/*.pidProcess ID files for running sessions

Configure Desktop Environment (~/.vnc/xstartup)

Create or edit ~/.vnc/xstartup:

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec startxfce4

For GNOME:

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec gnome-session

For MATE:

#!/bin/sh
unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS
exec mate-session

Make it executable:

chmod +x ~/.vnc/xstartup

Default Server Options (~/.vnc/config)

Create or edit ~/.vnc/config:

# Display geometry
geometry=1920x1080

# Color depth
depth=24

# Only allow connections from localhost (use with SSH tunnel)
localhost

# Disable clipboard transfer (security)
# SendCutText=0
# AcceptCutText=0

Common vncserver Options

OptionDescription
-geometry WxHSet screen resolution (e.g., 1920x1080)
-depth NColor depth: 8, 16, or 24
-localhost yesAccept connections only from localhost
-rfbport PORTSpecify custom RFB port
-name STRINGSet the desktop name shown in viewer
-fgRun in the foreground (don’t daemonize)
-SecurityTypes TYPESet authentication type (e.g., VncAuth, TLSVnc, None)

Running as a Systemd Service

Create a Systemd Unit File

Create /etc/systemd/system/vncserver@.service:

[Unit]
Description=Remote desktop service (VNC)
After=syslog.target network.target

[Service]
Type=forking
User=your_username
Group=your_username
WorkingDirectory=/home/your_username
PIDFile=/home/your_username/.vnc/%H:%i.pid

ExecStartPre=/bin/sh -c '/usr/bin/vncserver -kill :%i > /dev/null 2>&1 || :'
ExecStart=/usr/bin/vncserver :%i -geometry 1920x1080 -depth 24 -localhost yes
ExecStop=/usr/bin/vncserver -kill :%i

Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Replace your_username with the actual user.

Manage the Service

# Reload systemd after creating/editing the unit file
sudo systemctl daemon-reload

# Enable the service to start on boot (display :1)
sudo systemctl enable vncserver@1

# Start the service
sudo systemctl start vncserver@1

# Stop the service
sudo systemctl stop vncserver@1

# Check the service status
sudo systemctl status vncserver@1

# View logs
journalctl -u vncserver@1 -f

SSH Tunneling

VNC traffic is unencrypted by default. Always use SSH tunneling for remote connections.

Create an SSH Tunnel

# From your local machine, forward local port 5901 to remote VNC display :1
ssh -L 5901:localhost:5901 user@remote-server

# Run in the background (no interactive shell)
ssh -L 5901:localhost:5901 -N -f user@remote-server

# Then connect your VNC viewer to localhost:5901

SSH Tunnel with a Jump Host

# Tunnel through a bastion/jump host to reach the VNC server
ssh -L 5901:vnc-server:5901 -J user@jump-host user@vnc-server

Using SSH Config for Persistent Tunnels

Add to ~/.ssh/config:

Host vnc-tunnel
    HostName remote-server
    User your_username
    LocalForward 5901 localhost:5901

Then connect with:

ssh vnc-tunnel
# VNC viewer connects to localhost:5901

Security

Restrict to Localhost Only

Always bind VNC to localhost and use SSH tunneling for remote access:

# Start VNC server bound to localhost
vncserver :1 -localhost yes

Or set in ~/.vnc/config:

localhost

Firewall Rules

If you must expose VNC directly (not recommended), restrict access:

# UFW (Ubuntu/Debian)
sudo ufw allow from 192.168.1.0/24 to any port 5901    # Allow only from LAN
sudo ufw deny 5901                                       # Block all other VNC access

# firewalld (RHEL/CentOS/Fedora)
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port port="5901" protocol="tcp" accept'
sudo firewall-cmd --reload

# iptables
sudo iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 5901 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 5901 -j DROP

Enable TLS Encryption

TigerVNC supports TLS for encrypted connections:

# Generate a self-signed certificate
openssl req -x509 -newkey rsa:4096 -keyout ~/.vnc/key.pem -out ~/.vnc/cert.pem -days 365 -nodes

# Start VNC with TLS
vncserver :1 -SecurityTypes TLSVnc -X509Key ~/.vnc/key.pem -X509Cert ~/.vnc/cert.pem

Security Best Practices

  1. Never expose VNC directly to the internet — always use SSH tunneling
  2. Use strong VNC passwords — at least 8 characters with mixed case, numbers, and symbols
  3. Bind to localhost — use -localhost yes to prevent direct remote connections
  4. Keep VNC software updated — apply security patches regularly
  5. Use TLS encryption when SSH tunneling is not an option
  6. Limit users — only run VNC for users who need remote desktop access
  7. Monitor logs — check ~/.vnc/*.log for unauthorized access attempts
  8. Use fail2ban — configure fail2ban to block brute-force attempts on VNC ports

Connecting from Clients

Common VNC Viewers

ViewerPlatformNotes
TigerVNC ViewerLinux, Windows, macOSRecommended, matches TigerVNC server
RealVNC ViewerLinux, Windows, macOS, mobileFree for personal use
RemminaLinuxMulti-protocol (VNC, RDP, SSH)
VinagreLinux (GNOME)Built into GNOME
Screen SharingmacOSBuilt-in VNC viewer

Connect to a VNC Server

# TigerVNC Viewer
vncviewer localhost:5901                         # Connect via SSH tunnel
vncviewer 192.168.1.100:5901                     # Connect directly (LAN only)

# Remmina (from command line)
remmina -c vnc://localhost:5901

macOS Built-in Viewer

# Open Screen Sharing from terminal
open vnc://localhost:5901

Uninstallation

Remove VNC Server

# Stop all running VNC sessions
vncserver -kill :*

# Stop and disable the systemd service
sudo systemctl stop vncserver@1
sudo systemctl disable vncserver@1
sudo rm /etc/systemd/system/vncserver@.service
sudo systemctl daemon-reload

Remove Packages

# Ubuntu / Debian
sudo apt remove --purge tigervnc-standalone-server tigervnc-common
sudo apt autoremove

# RHEL / CentOS / Fedora
sudo dnf remove tigervnc-server

# Arch Linux
sudo pacman -Rns tigervnc

Clean Up Configuration

# Remove VNC configuration directory
rm -rf ~/.vnc

Troubleshooting

Common Issues

IssueCauseSolution
Black/gray screenMissing or broken xstartupCreate/fix ~/.vnc/xstartup with correct desktop environment
”Connection refused”VNC server not running or wrong portCheck vncserver -list and verify the display number
”Authentication failure”Wrong passwordReset with vncpasswd
Session starts then immediately diesError in xstartup scriptCheck ~/.vnc/*.log for errors
Cannot connect remotelyFirewall blocking or localhost-onlyCheck firewall rules; use SSH tunnel if -localhost yes is set
Poor performance / lagHigh resolution or slow networkReduce geometry, lower color depth, use compression in viewer
”A VNC server is already running”Stale PID file or session still activeKill with vncserver -kill :N or remove stale PID file
Desktop environment not loadingDE not installed or wrong exec commandInstall DE packages; verify the exec command in xstartup

Debugging Steps

# Check VNC server logs
cat ~/.vnc/*.log

# Check if VNC is listening
ss -tlnp | grep 590

# Check if the VNC process is running
ps aux | grep vnc

# Test local connection
vncviewer localhost:5901

# Check systemd service logs
journalctl -u vncserver@1 --no-pager -n 50

Quick Reference

Essential Commands

vncpasswd                                        # Set VNC password
vncserver :1                                     # Start display :1
vncserver :1 -geometry 1920x1080 -localhost yes  # Start with options
vncserver -list                                  # List active sessions
vncserver -kill :1                               # Stop display :1
vncserver -kill :*                               # Stop all sessions

Key Files

~/.vnc/xstartup                                  # Desktop startup script
~/.vnc/config                                    # Default server options
~/.vnc/passwd                                    # VNC password (encrypted)
~/.vnc/*.log                                     # Session logs
/etc/systemd/system/vncserver@.service           # Systemd service unit

Default Ports

Display :0  -->  Port 5900 (usually physical display)
Display :1  -->  Port 5901
Display :2  -->  Port 5902
Display :N  -->  Port 5900 + N