Ubuntu – Prioritize VPN’s DNS Server

18.04network-managersystemdsystemd-resolved

Is there a way to prioritize a particular DNS server only when connecting to a VPN (OpenVPN) through Network Manager or one of its configuration files?

I have a VPN (192.168.1.*) I frequently connect to that has DNS (192.168.1.53) configured to resolve host names of the form *.internal.example.com on its network. My local router (192.168.0.1) has DD-WRT on it with Google's DNS setup (those aren't strictly needed).

I've replaced the systemd /etc/resolv.conf stub with a symlink to /run/systemd/resolve/resolv.conf so that host names will actually resolve using the VPN's DNS server. Yesterday it was working fine because the VPN's DNS server was at the top of the list.

# /etc/resolv.conf -> /run/systemd/resolve/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
# ...

nameserver 192.168.1.53
nameserver 192.168.0.1
nameserver 8.8.8.8
# Too many DNS servers configured, the following entries may be ignored.
nameserver 8.8.4.4
search Home internal.example.com

However, when I connected today the DNS entries were reordered.

# /etc/resolv.conf -> /run/systemd/resolve/resolv.conf
# This file is managed by man:systemd-resolved(8). Do not edit.
# ...

nameserver 192.168.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
# Too many DNS servers configured, the following entries may be ignored.
nameserver 192.168.1.53
search Home internal.example.com

The order frequently changes after a reboot. Sometimes upon reconnection to the VPN I notice the order changes (after experiencing the resolution issue).

systemd-resolve works just fine and can resolve the hosts using the proper DNS server.

$ systemd-resolve --status --no-pager
Global
          DNSSEC NTA: ...

Link 10 (tun0)
      Current Scopes: DNS
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
         DNS Servers: 192.168.1.53
          DNS Domain: internal.example.com

Link 2 (eno1)
      Current Scopes: DNS
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
         DNS Servers: 192.168.0.1
                      8.8.8.8
                      8.8.4.4
                      192.168.1.53
          DNS Domain: Home
$ systemd-resolve srv1.internal.example.com
srv1.internal.example.com: 192.168.1.113

-- Information acquired via protocol DNS in 2.1ms.
-- Data is authenticated: no

ping, nslookup, and ssh all fail though.

$ ping srv1.internal.example.com
ping: srv1.internal.example.com: Name or service not known
$ nslookup srv1.internal.example.com
Server:         192.168.0.1
Address:        192.168.0.1#53

** server can't find srv1.internal.example.com: NXDOMAIN
$ ssh srv1.internal.example.com
ssh: Could not resolve hostname srv1.internal.example.com: Name or service not known

A few notes.

I connect to the VPN through Network Manager. I have the VPN's DNS manually specified on the VPN under: IPv4 > DNS Servers.

I tried using a separate wired ethernet connection configured with the VPN's DNS under: IPv4 > Other DNS Servers.

Best Answer

As you accept using dnsmasq, how about this:

  1. Point your resolv.conf to 127.0.0.1 (nameserver 127.0.0.1)
  2. Try this config on your dnsmasq:
server=/internal.example.com/192.168.1.53
server=8.8.8.8

This would use 192.168.1.53 for domain "internal.example.com" and 8.8.8.8 for everything else.

Take a look at "-S, --local, --server=" option on dnsmasq man page.

Update: You may also want to disable DHCP, so to avoid conflicts with your local router. Maybe listening only on lo (127.0.0.1) interface.

Related Question