dns: add new "rc-manager=auto" mode
Add a new `main.rc-manager=auto` setting, that favours to use systemd-resolved (and not touch "/etc/resolv.conf" but configure it via D-Bus), or falls back to `resolvconf`/`netconfig` binaries if they are installed and enabled at compile time. As final fallback use "symlink", like before. Note that on Fedora there is no "openresolv" package ([1]). Instead, "systemd" package provides "/usr/sbin/resolvconf" as a wrapper for systemd-resolved's "resolvectl". On such a system the fallback to resolvconf is always wrong, because NetworkManager should either talk to systemd-resolved directly or not but never call "/usr/sbin/resolvconf". So, the special handling for resolvconf and netconfig is only done if NetworkManager was build with these applications explicitly enabled. Note that SUSE builds NetworkManager with --with-netconfig=yes --with-config-dns-rc-manager-default=netconfig and the new option won't be used there either. But of course, netconfig already does all the right things on SUSE. [1] https://bugzilla.redhat.com/show_bug.cgi?id=668153 Suggested-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
8
NEWS
8
NEWS
@@ -8,6 +8,14 @@ The API is subject to change and not guaranteed to be compatible
|
||||
with the later release.
|
||||
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
||||
|
||||
* Introduce new "rc-manager=auto" setting and make it the default,
|
||||
unless a different default is chosen at compile time.
|
||||
This mode tries to detect "systemd-resolved", "resolvconf", and "netconfig"
|
||||
and chooses the mode that seems most suitable depending on build
|
||||
setting and runtime detection.
|
||||
"resolvconf" and "netconfig" are only considered iff NetworkManager
|
||||
was built with the respective options enabled.
|
||||
|
||||
=============================================
|
||||
NetworkManager-1.26
|
||||
Overview of changes since NetworkManager-1.24
|
||||
|
13
configure.ac
13
configure.ac
@@ -891,14 +891,15 @@ AC_SUBST(NM_CONFIG_DEFAULT_MAIN_DHCP, $config_dhcp_default)
|
||||
|
||||
AC_ARG_WITH(resolvconf, AS_HELP_STRING([--with-resolvconf=yes|no|path], [Enable resolvconf support]))
|
||||
AC_ARG_WITH(netconfig, AS_HELP_STRING([--with-netconfig=yes|no], [Enable SUSE netconfig support]))
|
||||
AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
|
||||
AC_ARG_WITH(config-dns-rc-manager-default, AS_HELP_STRING([--with-config-dns-rc-manager-default=auto|symlink|file|netconfig|resolvconf], [Configure default value for main.rc-manager setting]), [config_dns_rc_manager_default=$withval])
|
||||
if test "$config_dns_rc_manager_default" != "" -a \
|
||||
"$config_dns_rc_manager_default" != auto -a \
|
||||
"$config_dns_rc_manager_default" != file -a \
|
||||
"$config_dns_rc_manager_default" != symlink -a \
|
||||
"$config_dns_rc_manager_default" != netconfig -a \
|
||||
"$config_dns_rc_manager_default" != resolvconf; then
|
||||
AC_MSG_WARN([Unknown --with-config-dns-rc-manager-default=$config_dns_rc_manager_default setting.])
|
||||
config_dns_rc_manager_default=
|
||||
config_dns_rc_manager_default=auto
|
||||
fi
|
||||
# Use netconfig by default on SUSE
|
||||
AS_IF([test -z "$with_netconfig" -a -f /etc/SuSE-release], with_netconfig=yes)
|
||||
@@ -912,9 +913,6 @@ if test "$with_resolvconf" = "yes"; then
|
||||
AC_MSG_ERROR(cannot find resolvconf in path. Set the path explicitly via --with-resolvconf=PATH.)
|
||||
fi
|
||||
fi
|
||||
if test "$with_resolvconf" != "no"; then
|
||||
AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=resolvconf)
|
||||
fi
|
||||
|
||||
if test "$with_netconfig" = "yes"; then
|
||||
AC_PATH_PROGS(with_netconfig, netconfig, yes, /sbin:/usr/sbin:/usr/local/sbin)
|
||||
@@ -922,11 +920,6 @@ if test "$with_netconfig" = "yes"; then
|
||||
AC_MSG_ERROR(cannot find netconfig in path. Set the path explicitly via --with-netconfig=PATH.)
|
||||
fi
|
||||
fi
|
||||
if test "$with_netconfig" != "no"; then
|
||||
AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=netconfig)
|
||||
fi
|
||||
|
||||
AS_IF([test -z "$config_dns_rc_manager_default"], config_dns_rc_manager_default=symlink)
|
||||
|
||||
if test "$with_resolvconf" != "no"; then
|
||||
AC_DEFINE_UNQUOTED(RESOLVCONF_PATH, "$with_resolvconf", [Path to resolvconf])
|
||||
|
@@ -115,7 +115,11 @@
|
||||
|
||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
||||
%global logging_backend_default journal
|
||||
%if 0%{?fedora} || 0%{?rhel} > 8
|
||||
%global dns_rc_manager_default auto
|
||||
%else
|
||||
%global dns_rc_manager_default symlink
|
||||
%endif
|
||||
%else
|
||||
%global logging_backend_default syslog
|
||||
%global dns_rc_manager_default file
|
||||
@@ -641,6 +645,8 @@ This tool is still experimental.
|
||||
%endif
|
||||
-Ddist_version=%{version}-%{release} \
|
||||
-Dconfig_plugins_default=%{config_plugins_default} \
|
||||
-Dresolvconf=no \
|
||||
-Dnetconfig=no \
|
||||
-Dconfig_dns_rc_manager_default=%{dns_rc_manager_default} \
|
||||
-Dconfig_logging_backend_default=%{logging_backend_default} \
|
||||
-Djson_validation=true
|
||||
@@ -779,6 +785,8 @@ intltoolize --automake --copy --force
|
||||
%endif
|
||||
--with-dist-version=%{version}-%{release} \
|
||||
--with-config-plugins-default=%{config_plugins_default} \
|
||||
--with-resolvconf=no \
|
||||
--with-netconfig=no \
|
||||
--with-config-dns-rc-manager-default=%{dns_rc_manager_default} \
|
||||
--with-config-logging-backend-default=%{logging_backend_default} \
|
||||
--enable-json-validation
|
||||
|
@@ -158,7 +158,7 @@ if [[ $NO_DIST != 1 ]]; then
|
||||
--enable-polkit=yes \
|
||||
--with-nm-cloud-setup=yes \
|
||||
--with-config-dhcp-default=internal \
|
||||
--with-config-dns-rc-manager-default=symlink \
|
||||
--with-config-dns-rc-manager-default=auto \
|
||||
|| die "Error autogen.sh"
|
||||
if [[ $QUICK == 1 ]]; then
|
||||
make dist -j 7 || die "Error make dist"
|
||||
|
@@ -309,7 +309,8 @@ no-auto-default=*
|
||||
</para>
|
||||
<para><literal>default</literal>: NetworkManager will update
|
||||
<filename>/etc/resolv.conf</filename> to reflect the nameservers
|
||||
provided by currently active connections.</para>
|
||||
provided by currently active connections. The <literal>rc-manager</literal>
|
||||
setting (below) controls how this is done.</para>
|
||||
<para><literal>dnsmasq</literal>: NetworkManager will run
|
||||
dnsmasq as a local caching nameserver, using "Conditional Forwarding"
|
||||
if you are connected to a VPN, and then update
|
||||
@@ -349,37 +350,57 @@ no-auto-default=*
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>rc-manager</varname></term>
|
||||
<listitem><para>Set the <filename>resolv.conf</filename>
|
||||
management mode. The default value depends on NetworkManager build
|
||||
options, and this version of NetworkManager was build with a default of
|
||||
"<literal>&NM_CONFIG_DEFAULT_MAIN_RC_MANAGER;</literal>".
|
||||
Regardless of this setting, NetworkManager will
|
||||
always write resolv.conf to its runtime state directory
|
||||
<filename>&nmrundir;/resolv.conf</filename>.</para>
|
||||
<listitem>
|
||||
<para>Set the <filename>resolv.conf</filename>
|
||||
management mode. This option is about how NetworkManager writes to
|
||||
<filename>/etc/resolv.conf</filename>, if at all.
|
||||
The default value depends on NetworkManager build
|
||||
options, and this version of NetworkManager was build with a default of
|
||||
"<literal>&NM_CONFIG_DEFAULT_MAIN_RC_MANAGER;</literal>".
|
||||
Regardless of this setting, NetworkManager will
|
||||
always write its version of resolv.conf to its runtime state directory
|
||||
as <filename>&nmrundir;/resolv.conf</filename>.
|
||||
</para>
|
||||
<para>If you configure <literal>dns=none</literal> or make <filename>/etc/resolv.conf</filename>
|
||||
immutable with <literal>chattr +i</literal>, NetworkManager will ignore this setting and
|
||||
always choose <literal>unmanaged</literal> (below).
|
||||
</para>
|
||||
<para><literal>auto</literal>: if systemd-resolved plugin is configured via
|
||||
the <literal>dns</literal> setting or if it gets detected as main DNS plugin,
|
||||
NetworkManager will update systemd-resolved without touching <filename>/etc/resolv.conf</filename>.
|
||||
Alternatively, if <literal>resolvconf</literal> or <literal>netconfig</literal> are enabled
|
||||
at compile time and the respective binary is found, NetworkManager will automatically use it.
|
||||
Note that if you install or uninstall these binaries, you need to reload the
|
||||
<literal>rc-manager</literal> setting with SIGHUP or
|
||||
<literal>systemctl reload NetworkManager</literal>. As last fallback
|
||||
it uses the <literal>symlink</literal> option (see next).
|
||||
</para>
|
||||
<para><literal>symlink</literal>: If <filename>/etc/resolv.conf</filename> is
|
||||
a regular file, NetworkManager will replace the file on update. If
|
||||
<filename>/etc/resolv.conf</filename> is instead a symlink, NetworkManager
|
||||
will leave it alone. Unless the symlink points to the internal file
|
||||
<filename>&nmrundir;/resolv.conf</filename>,
|
||||
in which case the symlink will be updated to emit an inotify notification.
|
||||
This allows the user to conveniently instruct NetworkManager not
|
||||
to manage <filename>/etc/resolv.conf</filename> by replacing it with
|
||||
a symlink.</para>
|
||||
a regular file or does not exist, NetworkManager will write the file directly.
|
||||
If <filename>/etc/resolv.conf</filename> is instead a symlink, NetworkManager
|
||||
will leave it alone. Unless the symlink points to the internal file
|
||||
<filename>&nmrundir;/resolv.conf</filename>,
|
||||
in which case the symlink will be updated to emit an inotify notification.
|
||||
This allows the user to conveniently instruct NetworkManager not
|
||||
to manage <filename>/etc/resolv.conf</filename> by replacing it with
|
||||
a symlink.
|
||||
</para>
|
||||
<para><literal>file</literal>: NetworkManager will write
|
||||
<filename>/etc/resolv.conf</filename> as file. If it finds
|
||||
a symlink to an existing target, it will follow the symlink and
|
||||
update the target instead. In no case will an existing symlink
|
||||
be replaced by a file. Note that older versions of NetworkManager
|
||||
behaved differently and would replace dangling symlinks with a
|
||||
plain file.</para>
|
||||
<filename>/etc/resolv.conf</filename> as regular file. If it finds
|
||||
a symlink to an existing target, it will follow the symlink and
|
||||
update the target instead. In no case will an existing symlink
|
||||
be replaced by a file. Note that older versions of NetworkManager
|
||||
behaved differently and would replace dangling symlinks with a
|
||||
plain file.
|
||||
</para>
|
||||
<para><literal>resolvconf</literal>: NetworkManager will run
|
||||
resolvconf to update the DNS configuration.</para>
|
||||
resolvconf to update the DNS configuration.</para>
|
||||
<para><literal>netconfig</literal>: NetworkManager will run
|
||||
netconfig to update the DNS configuration.</para>
|
||||
netconfig to update the DNS configuration.</para>
|
||||
<para><literal>unmanaged</literal>: don't touch
|
||||
<filename>/etc/resolv.conf</filename>.</para>
|
||||
<filename>/etc/resolv.conf</filename>.</para>
|
||||
<para><literal>none</literal>: deprecated alias for
|
||||
<literal>symlink</literal>.</para>
|
||||
<literal>symlink</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@@ -49,7 +49,7 @@ option('ifupdown', type: 'boolean', value: false, description: 'enable ifupdown
|
||||
# handlers for resolv.conf
|
||||
option('resolvconf', type: 'string', value: '', description: 'Enable resolvconf support')
|
||||
option('netconfig', type: 'string', value: '', description: 'Enable SUSE netconfig support')
|
||||
option('config_dns_rc_manager_default', type: 'combo', choices: ['symlink', 'file', 'netconfig', 'resolvconf'], value: 'symlink', description: 'Configure default value for main.rc-manager setting')
|
||||
option('config_dns_rc_manager_default', type: 'combo', choices: ['auto', 'symlink', 'file', 'netconfig', 'resolvconf'], value: 'auto', description: 'Configure default value for main.rc-manager setting')
|
||||
|
||||
# dhcp clients
|
||||
option('dhclient', type: 'string', value: '', description: 'Enable dhclient support')
|
||||
|
@@ -42,10 +42,16 @@
|
||||
|
||||
#ifndef RESOLVCONF_PATH
|
||||
#define RESOLVCONF_PATH "/sbin/resolvconf"
|
||||
#define HAS_RESOLVCONF 0
|
||||
#else
|
||||
#define HAS_RESOLVCONF 1
|
||||
#endif
|
||||
|
||||
#ifndef NETCONFIG_PATH
|
||||
#define NETCONFIG_PATH "/sbin/netconfig"
|
||||
#define HAS_NETCONFIG 0
|
||||
#else
|
||||
#define HAS_NETCONFIG 1
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
@@ -182,6 +188,7 @@ domain_is_routing (const char *domain)
|
||||
static
|
||||
NM_UTILS_LOOKUP_STR_DEFINE (_rc_manager_to_string, NMDnsManagerResolvConfManager,
|
||||
NM_UTILS_LOOKUP_DEFAULT_WARN (NULL),
|
||||
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO, "auto"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN, "unknown"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED, "unmanaged"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM (NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE, "immutable"),
|
||||
@@ -1900,6 +1907,7 @@ _check_resconf_immutable (NMDnsManagerResolvConfManager rc_manager)
|
||||
case NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE:
|
||||
case NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF:
|
||||
case NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG:
|
||||
case NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1999,6 +2007,7 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
|
||||
gboolean param_changed = FALSE;
|
||||
gboolean plugin_changed = FALSE;
|
||||
gboolean systemd_resolved_changed = FALSE;
|
||||
gboolean rc_manager_was_auto = FALSE;
|
||||
|
||||
mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config));
|
||||
systemd_resolved = nm_config_data_get_systemd_resolved (nm_config_get_data (priv->config));
|
||||
@@ -2014,7 +2023,9 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
|
||||
again:
|
||||
if (!man) {
|
||||
/* nop */
|
||||
} else if (NM_IN_STRSET (man, "symlink", "none"))
|
||||
} else if (nm_streq (man, "auto"))
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO;
|
||||
else if (NM_IN_STRSET (man, "symlink", "none"))
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
|
||||
else if (nm_streq (man, "file"))
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE;
|
||||
@@ -2031,7 +2042,7 @@ again:
|
||||
man, ""NM_CONFIG_DEFAULT_MAIN_RC_MANAGER);
|
||||
}
|
||||
man = ""NM_CONFIG_DEFAULT_MAIN_RC_MANAGER;
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
@@ -2070,6 +2081,31 @@ again:
|
||||
plugin_changed = TRUE;
|
||||
}
|
||||
|
||||
if (rc_manager == NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO) {
|
||||
rc_manager_was_auto = TRUE;
|
||||
if (nm_streq (mode, "systemd-resolved"))
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
|
||||
else if ( HAS_RESOLVCONF
|
||||
&& g_file_test (RESOLVCONF_PATH, G_FILE_TEST_IS_EXECUTABLE)) {
|
||||
/* We detect /sbin/resolvconf only at this stage. That means, if you install
|
||||
* or uninstall openresolv afterwards, you need to reload the DNS settings
|
||||
* (with SIGHUP or `systemctl reload NetworkManager.service`).
|
||||
*
|
||||
* We only accept resolvconf if NetworkManager was built with --with-resolvconf.
|
||||
* For example, on Fedora the systemd package provides a compat resolvconf
|
||||
* implementation for systemd-resolved. But using that never makes sense, because
|
||||
* there we either use full systemd-resolved mode or not. In no case does it
|
||||
* make sense to call that resolvconf implementation. */
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF;
|
||||
} else if ( HAS_NETCONFIG
|
||||
&& g_file_test (NETCONFIG_PATH, G_FILE_TEST_IS_EXECUTABLE)) {
|
||||
/* Like for resolvconf, we detect only once. We only autoenable this
|
||||
* option, if NetworkManager was built with netconfig explicitly enabled. */
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG;
|
||||
} else
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK;
|
||||
}
|
||||
|
||||
/* The systemd-resolved plugin is special. We typically always want to keep
|
||||
* systemd-resolved up to date even if the configured plugin is different. */
|
||||
if (systemd_resolved) {
|
||||
@@ -2096,10 +2132,11 @@ again:
|
||||
}
|
||||
|
||||
if (param_changed || plugin_changed || systemd_resolved_changed) {
|
||||
_LOGI ("init: dns=%s%s rc-manager=%s%s%s%s",
|
||||
_LOGI ("init: dns=%s%s rc-manager=%s%s%s%s%s",
|
||||
mode,
|
||||
(systemd_resolved ? ",systemd-resolved" : ""),
|
||||
_rc_manager_to_string (rc_manager),
|
||||
rc_manager_was_auto ? " (auto)" : "",
|
||||
NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=",
|
||||
nm_dns_plugin_get_name (priv->plugin), "", ""));
|
||||
}
|
||||
|
@@ -88,12 +88,20 @@ void nm_dns_manager_set_hostname (NMDnsManager *self,
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED: do not touch /etc/resolv.conf
|
||||
* (but still write the internal copy -- unless it is symlinked by
|
||||
* /etc/resolv.conf)
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO: if /etc/resolv.conf is marked
|
||||
* as an immutable file, use "unmanaged" and don't touch /etc/resolv.conf.
|
||||
* Otherwise, if "systemd-resolved" is enabled (or detected), configure systemd-resolved via D-Bus
|
||||
* and don't touch /etc/resolv.conf.
|
||||
* Otherwise, if "resolvconf" application is found, use it.
|
||||
* As last resort, fallback to "symlink" which writes to /etc/resolv.conf
|
||||
* if (and only if) the file is missing or not a symlink.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE: similar to "unmanaged",
|
||||
* but indicates that resolv.conf cannot be modified.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes resolv.conf
|
||||
* by symlinking it to the run state directory.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Like SYMLINK, but instead of
|
||||
* symlinking /etc/resolv.conf, write it as a file.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK: NM writes /etc/resolv.conf
|
||||
* if the file is missing or not a symlink. An existing symlink is
|
||||
* left untouched.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_FILE: Write to /etc/resolv.conf directly.
|
||||
* If it is a file, write it as file, otherwise follow symlinks.
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_RESOLVCONF: NM is managing resolv.conf
|
||||
through resolvconf
|
||||
* @NM_DNS_MANAGER_RESOLV_CONF_MAN_NETCONFIG: NM is managing resolv.conf
|
||||
@@ -103,6 +111,7 @@ void nm_dns_manager_set_hostname (NMDnsManager *self,
|
||||
*/
|
||||
typedef enum {
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNKNOWN,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_AUTO,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_IMMUTABLE,
|
||||
NM_DNS_MANAGER_RESOLV_CONF_MAN_SYMLINK,
|
||||
|
Reference in New Issue
Block a user