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

# Generated by NetworkManager
nameserver 9.9.9.10
nameserver 208.67.222.222
nameserver 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 network
# /etc/init.d/network reload
You can use drill to check which DNS server you’re using:
$ drill eff.org

> ...
> ;; SERVER: 9.9.9.10
> ...

3 comments:

  1. donynam says:

    1) # uci commit <— missing 1 argument
    should change to
    uci commit network
    2) In LED 17.01.4
    reload_config doesn't work.
    $reload_config
    uci: Entry not found
    The following command work.
    /etc/init.d/network reload

  2. Jke says:

    I find that after adding in the commands for custom ipv6 advertised IPs:
    uci add_list dhcp.lan.dns=’2620:fe::10′
    it just adds this and advertises this added IP, but continues to advertise itself as well. How do you get around that?

Your comment: