Skip to content

Server Configuration Reference

Complete reference for all fields in server.toml.


Top-level Fields

All fields live under a [server] section, or at the root level (both are accepted).

Field Type Default Description
bind_address string "0.0.0.0:443" Address and port to listen on. Use "0.0.0.0:443" for all interfaces or "127.0.0.1:8443" for localhost-only (behind a reverse proxy).
tls_cert_file path "certs/cert.pem" Path to the TLS certificate (PEM format).
tls_key_file path "certs/key.pem" Path to the TLS private key (PEM format).
identity_key_file path "server_identity.key" Path to the server's X3DH identity key. Generated with rvpn-server keygen.
websocket_path string "/api/v1/ws" WebSocket endpoint path. Change this per-deployment to avoid detection.
http_port integer (disabled) If set, also listen on this port for plain HTTP (e.g. 80) for ACME challenges and HTTP→HTTPS redirects.
redirect_http_to_https bool true When http_port is set, redirect all HTTP requests to HTTPS.
decoy_root path (none) Path to a directory of static files to serve to unauthenticated browsers. Makes the server look like a normal website.
prekey_rotation_hours integer 168 How often (in hours) the server rotates its X3DH signed prekey. Default is 7 days.
one_time_prekey_count integer 100 How many one-time prekeys to generate and publish in the prekey bundle.
prekey_bundle_file path (none) If set, load X3DH keys from this file instead of generating new ones. Use this to restore a backed-up identity.

[server.rate_limit]

Controls how many connections an IP address can establish.

Field Type Default Description
max_connections_per_ip integer 500 Maximum simultaneous connections from a single IP address.
max_handshakes_per_minute integer 2000 Maximum new handshake attempts from a single IP per minute. Helps prevent brute-force probing.
[server.rate_limit]
max_connections_per_ip     = 10
max_handshakes_per_minute  = 20

[server.network]

Server-side network settings used when operating in TUN / full-tunnel mode.

Field Type Default Description
nat_enabled bool true Enable NAT (masquerading) for traffic exiting the server. Required for clients to reach the internet via the tunnel.
dhcp_range string "10.200.0.0/24" IP pool for assigning tunnel addresses to clients.
dns_servers list ["1.1.1.1"] DNS servers pushed to clients for tunnel-mode connections.
[server.network]
nat_enabled  = true
dhcp_range   = "10.200.0.0/24"
dns_servers  = ["1.1.1.1", "8.8.8.8"]

[server.tun]

Settings for true TUN-to-TUN mode. When enabled, the server creates a TUN interface and routes client packets through it.

Field Type Default Description
enabled bool false Enable TUN mode. When false, server uses relay mode (Brook-style).
tun_ip string "10.200.0.1/24" TUN interface IP address and subnet prefix.
mtu integer 1420 MTU for the TUN interface.
interface_name string "tun0" Name of the TUN interface to create.
[server.tun]
enabled = true
tun_ip = "10.200.0.1/24"
mtu = 1420
interface_name = "tun0"

Full Example

[server]
bind_address           = "0.0.0.0:443"
tls_cert_file          = "/etc/rvpn/certs/cert.pem"
tls_key_file           = "/etc/rvpn/certs/key.pem"
identity_key_file      = "/etc/rvpn/server_identity.key"
websocket_path         = "/api/v1/ws"
http_port              = 80
redirect_http_to_https = true
decoy_root             = "/var/www/decoy"
prekey_rotation_hours  = 168
one_time_prekey_count  = 100

[server.rate_limit]
max_connections_per_ip    = 500
max_handshakes_per_minute = 2000

[server.network]
nat_enabled  = true
dhcp_range   = "10.200.0.0/24"
dns_servers  = ["1.1.1.1"]

[server.tun]
enabled = true
tun_ip = "10.200.0.1/24"
mtu = 1420
interface_name = "tun0"

Reverse Proxy Mode

When running behind Caddy, nginx, or another TLS-terminating reverse proxy, set bind_address to a localhost port and let the proxy handle TLS. Point the proxy's WebSocket forward to the same path:

[server]
bind_address      = "127.0.0.1:8443"
tls_cert_file     = ""      # not used — proxy handles TLS
tls_key_file      = ""
websocket_path    = "/api/v1/ws"

Caddy example:

your.domain.com {
    handle /api/* {
        reverse_proxy 127.0.0.1:8443
    }
    handle {
        root * /var/www/html
        file_server
    }
}

The path matcher must be /api/* (prefix match), not /api (exact match only).