TUN Mode (Full-Tunnel VPN)
TUN mode provides a full-tunnel VPN experience where all client traffic is routed through the server. This differs from SOCKS5 relay mode, which requires per-application SOCKS5 configuration.
TUN Mode vs SOCKS5 Mode
Section titled “TUN Mode vs SOCKS5 Mode”| Feature | TUN Mode | SOCKS5 Mode |
|---|---|---|
| Traffic routing | Full tunnel, all apps | Per-app, requires SOCKS5 config |
| Setup complexity | Server-side NAT config | Client-side app configuration |
| Performance | Kernel-level packet handling | Application-level relay |
| Use case | Complete privacy, all traffic | App-specific tunneling |
In TUN mode, the client creates a virtual TUN interface and routes all traffic through it. The server receives these packets and NATs them to the internet, similar to a traditional VPN.
NAT Configuration Requirements
Section titled “NAT Configuration Requirements”TUN mode requires the server to act as a NAT gateway for client traffic. The server must have IP forwarding enabled and proper NAT rules configured.
Enable IP forwarding:
# Temporary (resets on reboot)sudo sysctl -w net.ipv4.ip_forward=1
# Permanentecho "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.confsudo sysctl -pConfigure NAT with iptables:
# Assuming your public interface is eth0# -s should match [server.network].dhcp_range in server.tomlsudo iptables -t nat -A POSTROUTING -s 10.200.0.0/24 -o eth0 -j MASQUERADEsudo iptables -A FORWARD -i tun0 -o eth0 -j ACCEPTsudo iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPTUsing nftables instead:
sudo nft add table ip natsudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }sudo nft add rule ip nat postrouting oifname "eth0" masqueradesudo nft add chain ip filter forward { type filter hook forward priority 0 \; }sudo nft add rule ip filter forward iifname "tun0" oifname "eth0" acceptsudo nft add rule ip filter forward iifname "eth0" oifname "tun0" ct state related,established acceptReplace eth0 with your actual network interface name (ip addr or ip link to check).
macOS does not support server-side TUN mode natively. For macOS servers, use SOCKS5 mode or run rvpn-server inside a FreeBSD/Linux VM with proper NAT configuration.
FreeBSD
Section titled “FreeBSD”Enable IP forwarding:
# Temporarysudo sysctl -w net.inet.ip.forwarding=1
# Permanent in /etc/rc.confecho 'gateway_enable="YES"' | sudo tee -a /etc/rc.confConfigure NAT with ipfw:
sudo sysctl -w net.inet.ip.fw.enable=1sudo natd -s -m -u -dynamic -i nat0
# Or using ipfw rules directlysudo ipfw add 100 nat 1 all from any to any via tun0For a full ipfw/natd setup, add to /etc/rc.conf:
firewall_enable="YES"firewall_type="OPEN"natd_enable="YES"natd_interface="vtnet0" # your public interfaceServer Configuration for TUN Mode
Section titled “Server Configuration for TUN Mode”[server]bind_address = "0.0.0.0:443"tls_cert_file = "/etc/letsencrypt/live/your-domain.com/fullchain.pem"tls_key_file = "/etc/letsencrypt/live/your-domain.com/privkey.pem"identity_key_file = "/etc/rvpn/server_identity.key"websocket_path = "/api/v1/ws"
[server.network]nat_enabled = truedhcp_range = "10.200.0.0/24"
[server.tun]enabled = truetun_ip = "10.200.0.1/24"mtu = 1420dns_servers = ["1.1.1.1", "8.8.8.8"]Key settings for TUN mode:
websocket_path— Must be/api/v1/wsfor TUN mode clients to reach the TUN endpoint at/api/v1/ws/tun[server.network].nat_enabledanddhcp_range— Startup-hint fields used to check your iptables NAT rules. NAT itself is programmed by your operator (iptables/pf); see the Server Installation guide.[server.tun].tun_ip— The subnet client IPs are handed out from. Change this if10.200.0.0/24clashes with your LAN.[server.tun].dns_servers— DNS resolvers pushed to clients over the tunnel
Running the Server in TUN Mode
Section titled “Running the Server in TUN Mode”Direct Execution
Section titled “Direct Execution”sudo rvpn-server -c /etc/rvpn/server.tomlAs a systemd Service
Section titled “As a systemd Service”The service runs the same binary regardless of mode. Ensure server.toml has TUN-mode settings as shown above.
sudo systemctl restart rvpn-serverVerification Steps
Section titled “Verification Steps”Check server logs:
sudo journalctl -u rvpn-server -fLook for entries showing the WebSocket path and TUN handler:
INFO Starting rVPN Server on 0.0.0.0:443INFO Server listening on wss://0.0.0.0:443INFO WebSocket endpoint (mobile TUN): /api/v1/ws/tunINFO TUN server started on 10.200.0.1/24Verify NAT rules are active (Linux):
sudo iptables -t nat -L POSTROUTING -vsudo iptables -L FORWARD -vTest connectivity:
Connect a client in TUN mode and verify:
- Client receives an IP in the
dhcp_range(e.g.,10.200.0.x) - Client can ping external IPs (e.g.,
8.8.8.8) - Client DNS queries resolve correctly
Check active connections on server:
sudo ss -tlnp | grep 443sudo ip addr show tun0 # if interface existsTroubleshooting
Section titled “Troubleshooting”Client Cannot Connect
Section titled “Client Cannot Connect”- Verify port 443 is open in firewall
- Check
websocket_pathis/api/v1/ws(clients append/tunautomatically) - Review server logs for TLS or WebSocket upgrade errors
Traffic Flows Out But Nothing Returns
Section titled “Traffic Flows Out But Nothing Returns”- Verify IP forwarding is enabled:
sysctl net.ipv4.ip_forward - Check NAT rules:
iptables -t nat -L POSTROUTING - Ensure the server’s security group/firewall allows outbound traffic on all ports
No Internet Access on Client
Section titled “No Internet Access on Client”- Confirm
nat_enabled = truein server.toml - Verify DHCP range does not conflict with existing networks
- Check that
dns_serversare reachable from the server
TUN Interface on Server
Section titled “TUN Interface on Server”The server creates a real TUN interface (e.g., tun0 with IP 10.200.0.1) when TUN mode is enabled. This provides true TUN-to-TUN tunneling:
| Component | Description |
|---|---|
| Server TUN | tun0 with IP 10.200.0.1/24 |
| Client TUN | Virtual interface with IP from 10.200.0.x |
| Routing | Kernel routes packets through TUN interface |
The server’s TUN interface handles:
- Writing packets received from clients to the kernel
- Reading response packets from the kernel
- Forwarding responses back to the appropriate client
Reverse Proxy Considerations
Section titled “Reverse Proxy Considerations”When running behind a reverse proxy (Caddy, nginx, HAProxy), ensure the proxy forwards /api/v1/ws/tun to the server. The proxy configuration for TUN mode is identical to SOCKS5 mode — both use the same WebSocket base path.
See Reverse Proxy Setup for complete proxy configurations.
Quick Reference
Section titled “Quick Reference”| Item | Value |
|---|---|
| WebSocket path | /api/v1/ws |
| TUN endpoint | /api/v1/ws/tun |
| Default port | 443 |
| DHCP range default | 10.200.0.0/24 |
| NAT required | Yes |