From 0dc673f0a5f6ee3fdba52e8bf882d67c5b888baa Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 12 Sep 2018 21:16:34 +0200 Subject: [PATCH] dns: write original DNS servers to /var/run/NetworkManager/no-stub-resolv.conf When a DNS plugin is enabled (like "main.dns=dnsmasq" or "main.dns=systemd-resolved"), the name servers announced to the rc-manager are coerced to be 127.0.0.1 or 127.0.0.53. Depending on the "main.rc-manager" setting, also "/etc/resolv.conf" contains only this coerced name server to the local caching service. The same is true for "/var/run/NetworkManager/resolv.conf" file, which contains what we would write to "/etc/resolv.conf" (depending on the "main.rc-manager" configuration). Write a new file "/var/run/NetworkManager/no-stub-resolv.conf", which contains the original name servers, uncoerced. Like "/var/run/NetworkManager/resolv.conf", this file is always written. The effect is, when one enables "main.dns=systemd-resolved", then there is still a file "no-stub-resolv.conf" with the same content as with "main.dns=default". The no-stub-resolv.conf may be a possible solution, when a user wants NetworkManager to update systemd-resolved, but still have a regular /etc/resolv.conf [1]. For that, the user could configure [main] dns=systemd-resolved rc-manager=unmanaged and symlink "/etc/resolv.conf" to "/var/run/NetworkManager/no-stub-resolv.conf". This is not necessarily the only solution for the problem and does not preclude options for updating systemd-resolved in combination with other DNS plugins. [1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/issues/20 --- man/NetworkManager.conf.xml | 12 ++++++++++-- src/dns/nm-dns-manager.c | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 87cf001621..4ed554ef20 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -331,15 +331,23 @@ no-auto-default=* after some time. This behavior can be modified passing the 'all-servers' or 'strict-order' options to dnsmasq (see the manual page for more details). + systemd-resolved: NetworkManager will + push the DNS configuration to systemd-resolved unbound: NetworkManager will talk to unbound and dnssec-triggerd, providing a "split DNS" configuration with DNSSEC support. /etc/resolv.conf will be managed by dnssec-trigger daemon. - systemd-resolved: NetworkManager will - push the DNS configuration to systemd-resolved none: NetworkManager will not modify resolv.conf. This implies rc-manager unmanaged + + Note that the plugins dnsmasq, systemd-resolved + and unbound are caching local nameservers. + Hence, when NetworkManager writes &nmrundir;/resolv.conf + and /etc/resolv.conf (according to rc-manager + setting below), the name server there will be localhost only. + NetworkManager also writes a file &nmrundir;/no-stub-resolv.conf + that contains the original name servers pushed to the DNS plugin. diff --git a/src/dns/nm-dns-manager.c b/src/dns/nm-dns-manager.c index 33a414831f..2755b26241 100644 --- a/src/dns/nm-dns-manager.c +++ b/src/dns/nm-dns-manager.c @@ -744,9 +744,36 @@ _read_link_cached (const char *path, gboolean *is_cached, char **cached) return (*cached = g_file_read_link (path, NULL)); } -#define MY_RESOLV_CONF NMRUNDIR "/resolv.conf" -#define MY_RESOLV_CONF_TMP MY_RESOLV_CONF ".tmp" -#define RESOLV_CONF_TMP "/etc/.resolv.conf.NetworkManager" +#define MY_RESOLV_CONF NMRUNDIR"/resolv.conf" +#define MY_RESOLV_CONF_TMP MY_RESOLV_CONF".tmp" +#define RESOLV_CONF_TMP "/etc/.resolv.conf.NetworkManager" + +#define NO_STUB_RESOLV_CONF NMRUNDIR "/no-stub-resolv.conf" + +static void +update_resolv_conf_no_stub (NMDnsManager *self, + char **searches, + char **nameservers, + char **options) +{ + gs_free char *content = NULL; + GError *local = NULL; + + content = create_resolv_conf (searches, nameservers, options); + + if (!g_file_set_contents (NO_STUB_RESOLV_CONF, + content, + -1, + &local)) { + _LOGD ("update-resolv-no-stub: failure to write file: %s", + local->message); + g_error_free (local); + return; + } + + _LOGT ("update-resolv-no-stub: '%s' successfully written", + NO_STUB_RESOLV_CONF); +} static SpawnResult update_resolv_conf (NMDnsManager *self, @@ -1421,6 +1448,8 @@ update_dns (NMDnsManager *self, ; } + update_resolv_conf_no_stub (self, searches, nameservers, options); + /* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf * to ensure that the glibc resolver doesn't try to round-robin nameservers, * but only uses the local caching nameserver.