Systemd-networkd: How can I prepend a static nameserver entry to DHCP-discovered nameservers?

7

2

I'm using systemd 213 on Arch Linux, and systemd-networkd/resolved with DHCP to connect to the internet. I'm also running a caching DNS server on 127.0.0.1. I'd like to make this server the first DNS server in the list, but I'd also like to use the nameservers discovered by systemd-resolved. Using a static resolv.conf isn't really possible, because I connect to networks with different DNS settings.

I know I can set fallback DNS servers in /etc/systemd/resolved.conf, but is there a way with systemd-networkd to prepend my local DNS server to those discovered by DHCP?


Edit: What I've tried so far

  • Adding a manual DNS entry in the .network file results in that entry being appended instead of prepended:

    # This file is managed by systemd-resolved(8). Do not edit.
    #
    # Third party programs must not access this file directly, but
    # only through the symlink at /etc/resolv.conf. To manage
    # resolv.conf(5) in a different way, replace the symlink by a
    # static file or a different symlink.
    
    nameserver 141.48.3.51
    nameserver 141.48.3.17
    nameserver 141.48.3.3
    # Too many DNS servers configured, the following entries may be ignored
    nameserver 127.0.0.1
    
  • If I add UseDNS=true in the [DHCPv4] section as well, as described in the systemd.network(5), manpage, the nameservers discovered by DHCP are ignored and only the static DNS entry is used, which is not what I want either:

    # This file is managed by systemd-resolved(8). Do not edit.
    #
    # Third party programs must not access this file directly, but
    # only through the symlink at /etc/resolv.conf. To manage
    # resolv.conf(5) in a different way, replace the symlink by a
    # static file or a different symlink.
    
    nameserver 127.0.0.1
    
  • Using the in_addr representation for the DNS address just appends my nameserver, just like using the normal representation.

runiq

Posted 2014-06-12T09:16:42.133

Reputation: 71

Answers

3

Have you tried adding these two lines:

  [Network]
  DNS=127.0.0.1

to one of the files /etc/systemd/network/*.network? For instance, for a dhcp client, modify /etc/systemd/network/80-dhcp.network to contain the lines:

  [Match]
  Name=en*

  [Network]
  DHCP=yes
  DNS=127.0.0.1

EDIT:

Have you tried the in_addr representation? Try substituting 127.0.0.1 with 16777343.

MariusMatutiae

Posted 2014-06-12T09:16:42.133

Reputation: 41 321

I found this answer when searching for a way to configure 3 static DNS servers on an Ubuntu 18.04 machine. The /etc/systemd/network, and creating a new file in that directory with the suggested two lines (containing just one of the DNS servers I need to configure) followed by a reboot didn't help. – kasperd – 2019-02-02T20:26:51.757

The solution which worked for me was to add a DNS section to /etc/systemd/resolved.conf. – kasperd – 2019-02-02T20:36:14.620

I did, but unfortunately the DHCP-discovered nameservers still take precedence. I also tried adding UseDNS=false in the [DHCPv4] section, which resulted in the DHCP-discovered nameservers not being added to /run/systemd/network/resolv.conf at all. I'll update my initial post with the things I've tried so far. – runiq – 2014-06-12T11:48:03.673

@runiq Please see my little edit. – MariusMatutiae – 2014-06-12T13:39:47.657

1Nope, sorry—no difference to just using the "normal" representation. I've included the resulting resolv.conf files for reference. – runiq – 2014-06-13T06:38:50.633

0

The trick seems to be that your config file in /etc/systemd/network must lexically sort earlier than the default configs in /run/systemd/network which are prefixed with 10-. Note that if you override the default configuration you must also enable DHCP on the interface otherwise the interface will come up without DHCP configured.

Here's an example config file that I placed at /etc/system/network/1-test.network:

[Match]
Name=ens5

[Network]
DHCP=ipv4
DNS=8.8.8.8

[DHCP]
UseDNS=false

To apply these settings run systemctl restart systemd-networkd. This doesn't appear to bring down the interface, just re-configure it. You can then use networkctl status ens5 to validate that the settings were applied.

I validated this at least works on Ubuntu 18.04 (bionic).

MIke Crute

Posted 2014-06-12T09:16:42.133

Reputation: 101

-1

Same as @MariusMatutiae 's answer but move DNS entry above DHCP=yes

  [Match]
  Name=en*

  [Network]
  DNS=127.0.0.1
  DHCP=yes

Yanke Guo

Posted 2014-06-12T09:16:42.133

Reputation: 1