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¶
| 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¶
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.
Linux¶
Enable IP forwarding:
# Temporary (resets on reboot)
sudo sysctl -w net.ipv4.ip_forward=1
# Permanent
echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Configure NAT with iptables:
# Assuming your public interface is eth0
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i tun0 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o tun0 -m state --state RELATED,ESTABLISHED -j ACCEPT
Using nftables instead:
sudo nft add table ip nat
sudo nft add chain ip nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule ip nat postrouting oifname "eth0" masquerade
sudo nft add chain ip filter forward { type filter hook forward priority 0 \; }
sudo nft add rule ip filter forward iifname "tun0" oifname "eth0" accept
sudo nft add rule ip filter forward iifname "eth0" oifname "tun0" ct state related,established accept
Replace eth0 with your actual network interface name (ip addr or ip link to check).
macOS¶
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¶
Enable IP forwarding:
# Temporary
sudo sysctl -w net.inet.ip.forwarding=1
# Permanent in /etc/rc.conf
echo 'gateway_enable="YES"' | sudo tee -a /etc/rc.conf
Configure NAT with ipfw:
sudo sysctl -w net.inet.ip.fw.enable=1
sudo natd -s -m -u -dynamic -i nat0
# Or using ipfw rules directly
sudo ipfw add 100 nat 1 all from any to any via tun0
For a full ipfw/natd setup, add to /etc/rc.conf:
firewall_enable="YES"
firewall_type="OPEN"
natd_enable="YES"
natd_interface="vtnet0" # your public interface
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 = true
dhcp_range = "10.200.0.0/24"
dns_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/tunnat_enabled— Enables server-side NAT for client trafficdhcp_range— IP range assigned to connected clientsdns_servers— DNS servers handed to clients via DHCP
Running the Server in TUN Mode¶
Direct Execution¶
As a systemd Service¶
The service runs the same binary regardless of mode. Ensure server.toml has TUN-mode settings as shown above.
Verification Steps¶
Check server logs:
Look for entries showing the WebSocket path and TUN handler:
INFO rvpn_server: Listening on 0.0.0.0:443
INFO rvpn_server: WebSocket path: /api/v1/ws
INFO rvpn_server: TUN mode enabled
Verify NAT rules are active (Linux):
Test connectivity:
Connect a client in TUN mode and verify:
1. Client receives an IP in the dhcp_range (e.g., 10.200.0.x)
2. Client can ping external IPs (e.g., 8.8.8.8)
3. Client DNS queries resolve correctly
Check active connections on server:
Troubleshooting¶
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¶
- 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¶
- 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¶
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¶
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¶
| 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 |