6

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.

3 Answers3

4

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.

JucaPirama
  • 406
  • 2
  • 10
4

It is possible to make dns priority with

nmcli -p connection modify MY_VPN_CONNECTION ipv4.dns-priority -42

found this here https://github.com/systemd/systemd/issues/6076

Kerya
  • 41
  • I knew there must be a simpler method. Now that (K)ubuntu uses NetworkManager, all other solutions I've found seemed fragile, overly complicated, or required hard-coding things. I used the Network Settings > Import VPN connection GUI tool, but looking at the /etc/resolv.conf before and after connection, the DNS server of the VPN was at the bottom of the priority list. After this fix, it's the only entry, DNS works perfectly, and there was no need for any scripting. – Walf Aug 06 '20 at 01:44
  • IMO this is the correct solution as it involves working with NetworkManager rather than against it. there are more docs about the values here but what mattered to me was: 50 is default for VPN, 100 for everything else. Lower number = higher priority. If you use a negative number (very high priority), nameservers from all other connections with a higher number will be removed. – maaarghk Oct 29 '21 at 18:51
3

Thanks to JucaPirama's answer for the direction I needed, this is my final setup using dnsmasq in front of systemd-resolved.

Disable the systemd-resolved stub DNS server. In /etc/systemd/resolved.conf change

#DNSStubListener=yes

to

DNSStubListener=no

Restart systemd-resolved.

sudo systemctl restart systemd-resolved

Install dnsmasq.

sudo apt-get install dnsmasq

Setup dnsmasq. In /etc/dnsmasq.conf, use systemd-resolved's resolv.conf file by changing

#resolv-file=/etc/resolv.conf

to

resolv-file=/run/systemd/resolve/resolv.conf

Set the VPN's DNS server for just its domains by adding

server=/internal.example.com/192.168.1.53

Disable DHCP to prevent any potential conflicts by changing

#no-dhcp-interface=

to

no-dhcp-interface=

Restart dnsmasq.

sudo systemctl restart dnsmasq

Unlink /etc/resolv.conf from systemd-resolved's configuration.

sudo unlink /etc/resolv.conf

Edit /etc/resolv.conf to use dnsmasq. This step might not be needed because Network Manager at some point overrode it to point to 127.0.0.53 anyway.

nameserver 127.0.0.53