VNC Remote Desktop Guard (vnc)
The VNC Remote Desktop Guard plugin inspects Remote Framebuffer (RFB 003.003 - 003.008) protocols used by VNC servers. It parses the initial version exchange, tracks security type negotiation, and intercepts SecurityResult authentication failures (status 1 = failed) to automatically ban remote desktop credential stuffers.
Capabilities & Threat Defense
| Threat / Attack Vector | Defense Mechanism | Action Taken |
|---|---|---|
| VNC Password Brute-Force | Intercepts RFB SecurityResult failure code (1) | IP automatically banned after max_auth_failures |
| Obsolete RFB Client Probing | Enforces protocol version sanity checks | Incompatible clients cleanly rejected |
| Connection Flooding | Enforces rate limits per minute and burst caps | Connection throttled before reaching VNC server |
Installation
Install the plugin via CLI or declaratively:
# Install using short nametcp-warden plugins install vnc# Or install via Git repository URLtcp-warden plugins install https://github.com/routewarden/plugins/vncConfiguration Reference
Add a VNC guard service to tcp-warden.yaml:
services: vnc_bastion: listen: ":5900" upstream: "127.0.0.1:59000" protocol: "vnc" rate_limit: connections_per_minute: 30 burst: 5 max_auth_failures: 3 ban_after_failures: 3 ban_duration: "2h" plugin_config: max_auth_failures: 3Configuration Options
| Field | Type | Default | Description |
|---|---|---|---|
listen | string | ":5900" | Local proxy listen address and port. |
upstream | string | "127.0.0.1:59000" | Target VNC server address and port. |
protocol | string | "vnc" | Must be set to "vnc" or "rfb". |
max_auth_failures | int | 3 | Number of failed authentication attempts before banning. |
ban_duration | string | "2h" | Duration of the automated IP ban ("30m", "2h", "24h"). |
Network & Deployment Architecture
Because VNC operates on an unprivileged port (5900), firewall redirects (nftables/iptables) are not required. Deploy RouteWarden using direct reverse proxying or container isolation:
Option A: Direct Port Swapping (Bare-Metal / VM)
Rebind your VNC server (e.g., x11vnc or tigervnc) to listen strictly on loopback port 59000, and configure RouteWarden listen: ":5900" and upstream: "127.0.0.1:59000":
# tcp-warden.yaml — RouteWarden binds to standard VNC port 5900services: vnc_bastion: listen: ":5900" upstream: "127.0.0.1:59000" # Or private host "10.0.0.50:5900" protocol: "vnc"Option B: Docker Compose Bridge Network
Publish port 5900 on RouteWarden while keeping the desktop container private:
services: routewarden: image: ghcr.io/routewarden/tcp-warden:latest ports: - "5900:5900" - "9091:9091" volumes: - ./tcp-warden.yaml:/etc/routewarden/tcp-warden.yaml:ro depends_on: - vnc-server vnc-server: image: dorowu/ubuntu-desktop-lxde-vnc # Do NOT publish host ports; keep internal to bridge networkTesting & Verification
Verify the RFB banner and test connection via a VNC client:
# Inspect RFB protocol banner through RouteWardennc 127.0.0.1 5900# Server returns: RFB 003.008