mirror of
https://github.com/systemd/systemd
synced 2024-09-06 16:56:43 +00:00
Merge pull request #25947 from poettering/resolved-dns-creds
resolved: add support for reading DNS config from kernel cmdline + service credentials
This commit is contained in:
commit
e0ff0ee8f9
1
TODO
1
TODO
|
@ -598,7 +598,6 @@ Features:
|
|||
• resolved: allow defining additional /etc/hosts entries via a credential (it
|
||||
might make sense to then synthesize a new combined /etc/hosts file in /run
|
||||
and bind mount it on /etc/hosts for other clients that want to read it.
|
||||
Similar, allow picking up DNS server IP addresses from credential.
|
||||
• repart: allow defining additional partitions via credential
|
||||
• timesyncd: pick NTP server info from credential
|
||||
• portabled: read a credential "portable.extra" or so, that takes a list of
|
||||
|
|
|
@ -478,6 +478,15 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>nameserver=</varname></term>
|
||||
<term><varname>domain=</varname></term>
|
||||
|
||||
<listitem><para>Configures DNS server information and search domains, see
|
||||
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
for details.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>resume=</varname></term>
|
||||
<term><varname>resumeflags=</varname></term>
|
||||
|
|
|
@ -399,6 +399,49 @@ search foobar.com barbar.com
|
|||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Credentials</title>
|
||||
|
||||
<para><command>systemd-resolved</command> supports the service credentials logic as implemented by
|
||||
<varname>LoadCredential=</varname>/<varname>SetCredential=</varname> (see
|
||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>1</manvolnum></citerefentry> for
|
||||
details). The following credentials are used when passed in:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><varname>network.dns</varname></term>
|
||||
<term><varname>network.search_domains</varname></term>
|
||||
|
||||
<listitem><para>May contain a space separated list of DNS server IP addresses and DNS search
|
||||
domains. This information is only used when no explicit configuration via
|
||||
<filename>/etc/systemd/resolved.conf</filename>, <filename>/etc/resolv.conf</filename> or the kernel
|
||||
command line has been provided.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Kernel Command Line</title>
|
||||
|
||||
<para><command>systemd-resolved</command> also honours two kernel command line options:</para>
|
||||
|
||||
<variablelist class='kernel-commandline-options'>
|
||||
<varlistentry>
|
||||
<term><varname>nameserver=</varname></term>
|
||||
<term><varname>domain=</varname></term>
|
||||
|
||||
<listitem><para>Takes the IP address of a DNS server (in case of <varname>nameserver=</varname>), and
|
||||
a DNS search domain (in case of <varname>domain=</varname>). May be used multiple times, to define
|
||||
multiple DNS servers/search domains. If either of these options are specified
|
||||
<filename>/etc/resolv.conf</filename> will not be read and the <varname>DNS=</varname> and
|
||||
<varname>Domains=</varname> settings of
|
||||
<citerefentry><refentrytitle>resolved.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
will be ignored. These two kernel command line options hence override system
|
||||
configuration.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
|
|
|
@ -115,6 +115,15 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>network.dns</varname></term>
|
||||
<term><varname>network.search_domains</varname></term>
|
||||
<listitem>
|
||||
<para>DNS server information and search domains. Read by
|
||||
<citerefentry><refentrytitle>systemd-resolved.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>passwd.hashed-password.root</varname></term>
|
||||
<term><varname>passwd.plaintext-password.root</varname></term>
|
||||
|
|
|
@ -3,15 +3,17 @@
|
|||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "constants.h"
|
||||
#include "creds-util.h"
|
||||
#include "dns-domain.h"
|
||||
#include "extract-word.h"
|
||||
#include "hexdecoct.h"
|
||||
#include "parse-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
#include "resolved-conf.h"
|
||||
#include "resolved-dnssd.h"
|
||||
#include "resolved-manager.h"
|
||||
#include "resolved-dns-search-domain.h"
|
||||
#include "resolved-dns-stub.h"
|
||||
#include "dns-domain.h"
|
||||
#include "resolved-dnssd.h"
|
||||
#include "resolved-manager.h"
|
||||
#include "socket-netlink.h"
|
||||
#include "specifier.h"
|
||||
#include "string-table.h"
|
||||
|
@ -463,6 +465,99 @@ int config_parse_dns_stub_listener_extra(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void read_credentials(Manager *m) {
|
||||
_cleanup_free_ char *dns = NULL, *domains = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
/* Hmm, if we aren't supposed to read /etc/resolv.conf because the DNS settings were already
|
||||
* configured explicitly in our config file, we don't want to honour credentials either */
|
||||
if (!m->read_resolv_conf)
|
||||
return;
|
||||
|
||||
r = read_credential_strings_many(
|
||||
"network.dns", &dns,
|
||||
"network.search_domains", &domains);
|
||||
if (r < 0 && !IN_SET(r, -ENXIO, -ENOENT))
|
||||
log_warning_errno(r, "Failed to read credentials, ignoring: %m");
|
||||
|
||||
if (dns) {
|
||||
r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_SYSTEM, dns);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse credential provided DNS server string '%s', ignoring.", dns);
|
||||
|
||||
m->read_resolv_conf = false;
|
||||
}
|
||||
|
||||
if (domains) {
|
||||
r = manager_parse_search_domains_and_warn(m, domains);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse credential provided search domain string '%s', ignoring.", domains);
|
||||
|
||||
m->read_resolv_conf = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct ProcCmdlineInfo {
|
||||
Manager *manager;
|
||||
|
||||
/* If there's a setting configured via /proc/cmdline we want to reset the configured lists, but only
|
||||
* once, so that multiple nameserver= or domain= settings can be specified on the kernel command line
|
||||
* and will be combined. These booleans will be set once we erase the list once. */
|
||||
bool dns_server_unlinked;
|
||||
bool search_domain_unlinked;
|
||||
};
|
||||
|
||||
static int proc_cmdline_callback(const char *key, const char *value, void *data) {
|
||||
struct ProcCmdlineInfo *info = ASSERT_PTR(data);
|
||||
int r;
|
||||
|
||||
assert(info->manager);
|
||||
|
||||
/* The kernel command line option names are chosen to be compatible with what various tools already
|
||||
* interpret, for example dracut and SUSE Linux. */
|
||||
|
||||
if (proc_cmdline_key_streq(key, "nameserver")) {
|
||||
if (!info->dns_server_unlinked) {
|
||||
/* The kernel command line overrides any prior configuration */
|
||||
dns_server_unlink_all(manager_get_first_dns_server(info->manager, DNS_SERVER_SYSTEM));
|
||||
info->dns_server_unlinked = true;
|
||||
}
|
||||
|
||||
r = manager_parse_dns_server_string_and_warn(info->manager, DNS_SERVER_SYSTEM, value);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse DNS server string '%s', ignoring.", value);
|
||||
|
||||
info->manager->read_resolv_conf = false;
|
||||
|
||||
} else if (proc_cmdline_key_streq(key, "domain")) {
|
||||
|
||||
if (!info->search_domain_unlinked) {
|
||||
dns_search_domain_unlink_all(info->manager->search_domains);
|
||||
info->search_domain_unlinked = true;
|
||||
}
|
||||
|
||||
r = manager_parse_search_domains_and_warn(info->manager, value);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to parse credential provided search domain string '%s', ignoring.", value);
|
||||
|
||||
info->manager->read_resolv_conf = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_proc_cmdline(Manager *m) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
r = proc_cmdline_parse(proc_cmdline_callback, &(struct ProcCmdlineInfo) { .manager = m }, 0);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to read kernel command line, ignoring: %m");
|
||||
}
|
||||
|
||||
int manager_parse_config_file(Manager *m) {
|
||||
int r;
|
||||
|
||||
|
@ -479,6 +574,9 @@ int manager_parse_config_file(Manager *m) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
read_credentials(m); /* credentials are only used when nothing is explicitly configured … */
|
||||
read_proc_cmdline(m); /* … but kernel command line overrides local configuration. */
|
||||
|
||||
if (m->need_builtin_fallbacks) {
|
||||
r = manager_parse_dns_server_string_and_warn(m, DNS_SERVER_FALLBACK, DNS_SERVERS);
|
||||
if (r < 0)
|
||||
|
|
|
@ -30,7 +30,6 @@ MemoryDenyWriteExecute=yes
|
|||
NoNewPrivileges=yes
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
ProtectProc=invisible
|
||||
ProtectClock=yes
|
||||
ProtectControlGroups=yes
|
||||
ProtectHome=yes
|
||||
|
@ -51,6 +50,8 @@ SystemCallErrorNumber=EPERM
|
|||
SystemCallFilter=@system-service
|
||||
Type=notify
|
||||
User=systemd-resolve
|
||||
LoadCredential=network.dns
|
||||
LoadCredential=network.search_domains
|
||||
{{SERVICE_WATCHDOG}}
|
||||
|
||||
[Install]
|
||||
|
|
Loading…
Reference in a new issue