Skip to content

DNS Leak Prevention

Without proper DNS configuration, your DNS queries may leak outside the VPN tunnel, revealing which domains you visit to your ISP or local network.


When you connect to a VPN, your traffic is encrypted and routed through the VPN server. However, DNS queries are often handled separately by your operating system’s DNS resolver, which may send queries to your ISP’s DNS servers directly:

Without DNS proxy:
┌──────────────┐ ┌─────────────┐
│ Your device │ ──────► │ ISP DNS │ ← DNS leak!
│ │ └─────────────┘
│ ── VPN ────► │ ┌─────────────┐
└──────────────┘ ──────► │ VPN Server │ ← Regular traffic
└─────────────┘

Even if your web traffic goes through the VPN tunnel, your ISP can see every domain you resolve.


The rVPN DNS proxy runs locally on your device. It receives DNS queries and forwards them through the encrypted VPN tunnel to the server, which resolves them:

With DNS proxy enabled:
┌──────────────┐ ┌─────────────┐
│ Your device │ │ ISP DNS │ ← Not used
│ │ └─────────────┘
│ [DNS proxy] │ ──────► │ VPN Server │ ← Encrypted tunnel
└──────────────┘ └─────────────┘

Your ISP sees no DNS queries. All DNS resolution happens inside the encrypted tunnel.


The DNS proxy respects split tunnel rules:

Domain typeBehaviour
Bypassed domainsResolved locally (not through VPN)
Blocked domains (ads/trackers)Return NXDOMAIN immediately
All other domainsResolved through VPN tunnel

This means:

  • Domestic streaming sites you bypass resolve locally (no VPN overhead)
  • Ad-blocker works without sending requests to the VPN server
  • All other domains are private

1. Enable DNS proxy in client.toml:

[dns_proxy]
enabled = true
listen_address = "127.0.0.1:53"

2. Run the client with root privileges (required to bind port 53):

Terminal window
sudo rvpn -c ~/.config/rvpn/client.toml

3. Configure system DNS:

System Settings -> Network -> your connection -> Details -> DNS

Add 127.0.0.1 as the primary DNS server. Remove any other entries.

Or via command line:

Terminal window
sudo networksetup -setdnsservers Wi-Fi 127.0.0.1

To verify:

Terminal window
# Should show 127.0.0.1
networksetup -getdnsservers Wi-Fi
# Should return your VPN server's IP
dig @127.0.0.1 api.ipify.org

To restore original DNS:

Terminal window
sudo networksetup -setdnsservers Wi-Fi empty

Option 1: Direct resolv.conf

Run the client as root:

Terminal window
sudo rvpn -c ~/.config/rvpn/client.toml

Edit /etc/resolv.conf:

nameserver 127.0.0.1

Option 2: systemd-resolved (recommended)

Add to /etc/systemd/resolved.conf:

[Resolve]
DNS=127.0.0.1

Then restart:

Terminal window
sudo systemctl restart systemd-resolved

Verify:

Terminal window
resolvectl status | grep DNS
  1. Edit connection: nm-connection-editor
  2. IPv4 Settings -> Method: Manual
  3. Add DNS server: 127.0.0.1
  4. Save and reconnect

Visit these sites with your VPN connected:

  1. https://dnsleaktest.com
  2. https://ipleak.net
  3. https://browserleaks.com/dns

The DNS servers shown should be your VPN server’s DNS (or the dns_servers configured in your server.toml), not your ISP’s DNS.


In TUN mode, the client receives dns_servers from the server via DHCP and automatically uses them. The DNS proxy is still recommended when using SOCKS5 mode, as TUN mode has built-in DNS handling.

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

These DNS servers are pushed to TUN clients. The client uses them directly for DNS resolution.


To use specific DNS providers through the VPN tunnel:

Server-side (pushed to TUN clients):

[server.tun]
dns_servers = ["1.1.1.1", "8.8.8.8"] # Cloudflare + Google

Or a privacy-focused choice:

[server.tun]
dns_servers = ["9.9.9.9", "149.112.112.112"] # Quad9

dns_servers accepts IP literals only; hostnames will fail to parse.

Client-side in SOCKS5 mode:

The DNS proxy forwards to the server, which resolves using dns_servers. To use specific DNS through the tunnel, configure them on the server.


Bypass Domain Nameservers (Local DNS Fallback)

Section titled “Bypass Domain Nameservers (Local DNS Fallback)”

When the DNS proxy is set as your system DNS resolver, bypass domains (domains that go outside the VPN) need special handling. If the proxy tried to use the system resolver for bypass domains, the query would loop back to itself, causing a complete DNS failure when the tunnel is down.

To prevent this, rVPN sends raw UDP DNS queries directly to public nameservers for bypass domains, completely skipping the system resolver:

SettingDefaultPurpose
nameservers["223.5.5.5:53", "1.1.1.1:53", "8.8.8.8:53"]Public DNS servers for bypass domain resolution

Configure in client.toml:

[dns_proxy]
enabled = true
nameservers = ["223.5.5.5:53", "119.29.29.29:53", "1.1.1.1:53"]
  • CN users: Put a China-based DNS first (e.g., AliDNS 223.5.5.5 or DNSPod 119.29.29.29) for the best latency on domestic sites.
  • Global users: The default order works well worldwide.
  • These servers are only used for bypass domains. Tunnel domains are still resolved through the encrypted VPN tunnel.

rVPN does not proxy raw DNS-over-HTTPS (DoH) or DNS-over-TLS (DoT) requests from client applications.

The local DNS proxy intercepts traditional UDP DNS queries from the operating system. For domains that should go through the tunnel, it forwards them to the server via rVPN’s encrypted WebSocket tunnel using a custom DNS protocol (not DoH or DoT). The server resolves these using its standard system DNS resolver. There is currently no server-side DoH/DoT configuration available.


  • Verify DNS proxy is running: dig @127.0.0.1 example.com
  • Check the listen_address in client.toml matches your system DNS setting
  • Try a different DNS server: dig @8.8.8.8 example.com
  • Port 53 may be in use: sudo lsof -i :53
  • Try port 5353 instead (no root required)
  • Try different DNS servers (Cloudflare 1.1.1.1 is typically fastest)
  • Reduce dns_cache_ttl in client.toml for frequently changing domains
  • Ensure no other DNS settings exist in system settings
  • Check browser DNS settings (Firefox can override system DNS)
  • Chrome (desktop/Android): Disable Secure DNS in Chrome settings: Settings → Privacy and security → Security → Use secure DNS → turn it off. Then clear Chrome’s DNS cache: navigate to chrome://net-internals/#dns and click Clear host cache.
  • iOS Chrome: If sites fail to resolve, force-close the app or clear browsing data to flush the DNS cache.
  • Ensure no VPN-less DNS resolver is running (e.g., mDNSResponder)