OpenWrt
The rVPN OpenWrt package puts the daemon on your router. LAN clients pick it up either automatically (via WPAD-advertised SOCKS5 / HTTP proxy) or transparently (in TUN mode, with policy routing sending forwarded LAN traffic through the tunnel).
Ships as two .ipk packages:
rvpn-client— the daemon, procd service, UCI schema, hotplug policy routing. Arch-specific.luci-app-rvpn— the LuCI 23.05 web UI. Arch-independent.
Requirements
Section titled “Requirements”- OpenWrt 22.03 or later.
- Router with enough RAM and flash for a ~5–10 MB static binary. Typical modern devices are fine; older 8 MB flash routers may struggle.
- A deployed rVPN server (address + prekey bundle).
Install
Section titled “Install”Grab the two .ipk files for your router’s architecture and install with opkg:
opkg install rvpn-client_1.3.1_<arch>.ipkopkg install luci-app-rvpn_1.3.1_all.ipkSupported architectures: x86_64, aarch64, armv7, mipsel_24kc, mips_24kc.
The postinst hook auto-generates an identity key at /etc/rvpn/identity.key and enables the service. The daemon stays stopped until you configure a server address.
Configure via LuCI
Section titled “Configure via LuCI”Open the router’s admin UI and navigate to Services → VPN → rVPN:
- Server — paste the base URL (e.g.
wss://vpn.example.com). The correct WebSocket path is appended automatically. - Mode — pick SOCKS5 Proxy for opt-in per-app routing on LAN clients (paired with WPAD auto-discovery), or TUN (Full VPN) for transparent whole-LAN routing.
- Prekey Bundle — paste the JSON your server operator provided into the Prekey Bundle text area and hit Save & Apply.
- Server Fingerprint (optional) — paste the operator’s
ik:1:…pin here for strict pinning. Leave blank to Trust On First Use. - Enabled — flip on. Hit Save & Apply.
The status pill on the Overview section shows Connected / Connecting / Disabled based on the live procd instance.
Configure via CLI
Section titled “Configure via CLI”The UCI schema is straightforward:
uci set rvpn.main.server_address='wss://your-server.com'uci set rvpn.main.mode='socks5'uci set rvpn.main.enabled='1'
# Optional: strict pin instead of TOFUuci set rvpn.server_identity.server_fingerprint='ik:1:...'uci set rvpn.server_identity.strict_mode='1'
uci commit rvpn/etc/init.d/rvpn restartEvery UCI option is documented inline in /etc/config/rvpn on the router. The most useful ones:
| Section | Option | Purpose |
|---|---|---|
main | server_address | Base URL of the rVPN server (no path). |
main | mode | socks5 or tun. |
server_identity | server_fingerprint | Canonical ik:1: pin. Blank = TOFU. |
server_identity | trust_on_first_use | 1 (default) captures the identity on first connect. |
server_identity | strict_mode | 1 refuses unknown identities even on first connect (needs the pin set). |
socks5 | listen_address | Where the SOCKS5 proxy binds. Default 0.0.0.0:1080. |
http_proxy | enabled | Also expose an HTTP proxy. Off by default. |
tun | ip_address | Local TUN address. Default 10.200.0.2/24. |
split_tunnel | bypass_countries | Comma-separated ISO codes whose CIDR ranges skip the tunnel. |
network | dns_servers | Fallback DNS resolvers. |
wpad | enabled | Advertise the SOCKS5 proxy via DHCP option 252. On by default. |
SOCKS5 mode + WPAD
Section titled “SOCKS5 mode + WPAD”When rVPN starts in SOCKS5 mode, the init script generates /www/wpad.dat at runtime using the router’s live LAN IP (uci get network.lan.ipaddr). It’s advertised to LAN clients via DHCP option 252. Clients that honour WPAD — macOS, Chrome, Firefox with the right prefs — pick the proxy up automatically.
If a device doesn’t honour WPAD, point it at SOCKS5 <router-lan-ip>:1080 manually.
TUN mode
Section titled “TUN mode”In TUN mode the daemon creates a virtual interface (default rvpn0) and the hotplug script /etc/hotplug.d/iface/99-rvpn-tun sets up policy routing on both IPv4 and IPv6 as soon as the interface is up:
- Table
100gets a default route via the VPN gateway. - Rules match
iif br-lanat priority100— LAN clients hit the table, the router’s own outbound traffic does not.
The rvpn firewall zone masquerades on egress and rejects inbound on both address families. So dual-stack LANs don’t leak IPv6 straight to WAN.
Server identity pinning (TOFU)
Section titled “Server identity pinning (TOFU)”Same model as every other rVPN client: on first successful connect the daemon captures the server’s Ed25519 identity in the canonical ik:1:<base32> form. If the server ever presents a different identity without a signed rotation, the daemon refuses to connect.
To pin a specific identity from the start, paste the operator’s ik:1: pin into Server Fingerprint (LuCI) or set rvpn.server_identity.server_fingerprint (CLI). Setting strict_mode='1' refuses unknown identities even on the very first connect — pair it with a pin.
See Server Identity Pinning for the full model, including how operators rotate the identity key.
Troubleshooting
Section titled “Troubleshooting”The tunnel is up but LAN clients don’t route through it (TUN mode)
Section titled “The tunnel is up but LAN clients don’t route through it (TUN mode)”Check the policy routing rules and default route are actually in place after the interface comes up:
ip rule show | grep br-lanip route show table 100Both should show entries. If they’re missing, logread -e rvpn will tell you why the hotplug script bailed (no gateway resolved, br-lan not found, etc.).
LuCI shows “Disabled” but the daemon is running
Section titled “LuCI shows “Disabled” but the daemon is running”Save & Apply didn’t reload the daemon. /etc/init.d/rvpn reload should re-run generate_config; if not, the reload trigger might not be firing:
uci show rvpn/etc/init.d/rvpn restartWPAD isn’t being picked up by clients
Section titled “WPAD isn’t being picked up by clients”Confirm the DHCP option landed:
uci get dhcp.@dnsmasq[0].dhcp_optionExpect 252,http://<router-lan-ip>/wpad.dat in the list. If not, the WPAD render failed — check logread -e rvpn for the LAN IP resolution warning.
”profile is missing a prekey bundle” at start
Section titled “”profile is missing a prekey bundle” at start”The daemon refuses to start without a prekey bundle at /etc/rvpn/prekey-bundle.json. Paste the operator’s JSON into the LuCI Prekey Bundle text area, or drop the file in directly via SCP.
For more troubleshooting help, see the Troubleshooting Guide.