Fixing DNS leaks in LEDE

Disclaimer: I’m not an expert in networking, so the instructions below may be flawed. Be warned and proceed with caution! Corrections are highly welcome.

DNS leaks are nasty. ISPs may tamper with DNS for purposes of censorship or eavesdropping. Luckily, there are public DNS servers, e. g. Google (8.8.8.8), Cisco OpenDNS (208.67.222.222) and Quad9 (9.9.9.10) which may behave better.

I’ve set up my router to use public DNS servers instead of provider’s. In LEDE (OpenWrt) router firmware this can be done in GUI: go to Network → Interfaces → WAN → Edit → Advanced Settings, uncheck ‘Use DNS servers advertised by peer’ and add custom server IPs below.

The trouble is that LEDE runs its own DNS server and advertises its address (e. g. 192.168.0.1) to clients via DHCP. When NetworkManager connects to OpenVPN it keeps this address as one of DNS resolvers (even if you add push "dhcp-option DNS 9.9.9.10" to OpenVPN server config). You can check it with

cat /etc/resolv.conf
> 9.9.9.10
> 208.67.222.222
> 192.168.0.1

This way, DNS requests may occasionally be sent to the router which forwards them to configured servers skipping VPN tunnel and making them visible to the ISP (unless you’ve set up DNSCrypt, of course).

To avoid that one can put desired servers to resolv.conf anf force Linux to prevent its modification (NetworkManager updates it on every connection).

Another option is to change LEDE config to advertise custom servers instead of its own IP. Unfortunately, I couldn’t find GUI settings for that, so it must be done via SSH:

ssh root@192.168.0.1

# uci add_list dhcp.lan.dhcp_option='6,9.9.9.10,208.67.222.222'

If your provider supports IPv6, you can add those too:

# uci add_list dhcp.lan.dns='2620:fe::10'
# uci add_list dhcp.lan.dns='2620:0:ccc::2'

Setting custom DNS for the router itself (GUI steps described above) should be possible with:

# uci set network.wan.peerdns='0'
# uci set network.wan.dns='9.9.9.10 208.67.222.222'

If you are connected via another protocol (like PPPoE), replace wan with your interface name. You can get the list with

# uci show network | grep interface
...
network.mymodem=interface

Finally, don’t forget to apply the changes:

# uci commit
# reload_config

You can use drill to check which DNS server you’re using:

$ drill eff.org
> ...
> ;; SERVER: 9.9.9.10
> ...

Your comment: