Skip to content

Instantly share code, notes, and snippets.

@gwire
Last active April 2, 2021 22:08
Show Gist options
  • Save gwire/c66d386b2b7a186653dd2a3627555de6 to your computer and use it in GitHub Desktop.
Save gwire/c66d386b2b7a186653dd2a3627555de6 to your computer and use it in GitHub Desktop.
Arbitrary resolver routing using netplan

Arbitrary resolver routing using netplan

I have a server that uses netplan to configure systemd-resolved for local name resolution. I’m happy with the default DNS resolvers in use, but want to use a different resolver for specific subdomains.

e.g. I might want to use CloudFlare DNS (1.1.1.1, 1.0.0.1) by default, but also specifically use Google Public DNS (8.8.8.8, 8.8.4.4) for subdomains of google.com. (These are example values, not the actual use-case.)

systemd-resolved does support have the concept of routing-domains - for example an interface being added that resolves *.internal addresses to a local nameserver by specifying ~internal as the search-domain. But unfortunately specific nameserver routing can only be configured on a per-link basis.

One hacky way around this would be to add new interfaces just to update the resolver configuration. Old-style aliases (e.g eth0:1) don’t work in iproute2 and thus can’t be configured using netplan.

However you can add arbitrary VLANs on the server with netplan. Drop something like the following yaml into /etc/netplan/googledns.yaml and run sudo netplan apply. (Or netplan try to test it out.)

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      addresses: [ "10.3.0.5/23" ]
  vlans:
    vlan10:
      id: 10
      link: eth0
      addresses: [ "10.3.0.6/24" ]
      nameservers:
        search: [ ~google.com ]
        addresses: [ 8.8.8.8, 8.8.4.4 ]

networkctl should show a new link:

$ networkctl 
IDX LINK   TYPE     OPERATIONAL SETUP
  1 lo     loopback carrier     unmanaged
  2 eth0   ether    routable    configured
  3 vlan10 vlan     routable    configured

3 links listed.

and resolvectl should show the new resolver configuration:

$ resolvectl 
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 1.1.1.1
       DNS Servers: 1.1.1.1 1.0.0.1
Link 3 (vlan10)
    Current Scopes: DNS
         Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 8.8.8.8
       DNS Servers: 8.8.8.8 8.8.4.4
        DNS Domain: ~google.com

To confirm the requests are being routed correctly, switch on debugging. (You may need to be running a recent version of systemd-resolved)

$ sudo resolvectl log-level debug
$ journalctl —f u systemd-resolved

Run DNS lookups for www.yahoo.com and www.google.com and check the debug output.

systemd-resolved[78678]: Transaction 9822 for <www.yahoo.com IN A> scope dns on eth0/*.
systemd-resolved[78678]: Using feature level UDP+EDNS0 for transaction 9822.
systemd-resolved[78678]: Using DNS server 1.1.1.1 for transaction 9822.
[…]
systemd-resolved[78678]: Transaction 9894 for <www.google.com IN A> scope dns on vlan10/*.
systemd-resolved[78678]: Using feature level UDP+EDNS0 for transaction 9894.
systemd-resolved[78678]: Using DNS server 8.8.8.8 for transaction 9894

Switch the log level back to normal.

$ sudo resolvectl log-level info
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment