Skip to content

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 VectorDefense MechanismAction Taken
VNC Password Brute-ForceIntercepts RFB SecurityResult failure code (1)IP automatically banned after max_auth_failures
Obsolete RFB Client ProbingEnforces protocol version sanity checksIncompatible clients cleanly rejected
Connection FloodingEnforces rate limits per minute and burst capsConnection 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/vnc

Configuration 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: 3

Configuration Options ​

FieldTypeDefaultDescription
listenstring":5900"Local proxy listen address and port.
upstreamstring"127.0.0.1:59000"Target VNC server address and port.
protocolstring"vnc"Must be set to "vnc" or "rfb".
max_auth_failuresint3Number of failed authentication attempts before banning.
ban_durationstring"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 network

Testing & 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

Released under the MIT License.