Merge pull request #7588 from poettering/resolve-route-tweak

resolved domain routing tweaks and /etc/resolv.conf handling improvements
This commit is contained in:
Yu Watanabe
2017-12-13 13:43:55 +09:00
committed by GitHub
4 changed files with 93 additions and 47 deletions
+10 -4
View File
@@ -1,11 +1,17 @@
# This is a static resolv.conf file for connecting local clients to
# systemd-resolved via its DNS stub listener on 127.0.0.53.
# This file belongs to man:systemd-resolved(8). Do not edit.
#
# This is a static resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists no search
# domains.
#
# Run "systemd-resolve --status" to see details about the uplink DNS servers
# currently in use.
#
# 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,
# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,
# replace this symlink by a static file or a different symlink.
#
# See systemd-resolved.service(8) for details about the supported modes of
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.
nameserver 127.0.0.53
+20 -17
View File
@@ -425,7 +425,6 @@ int dns_scope_socket_tcp(DnsScope *s, int family, const union in_addr_union *add
DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, const char *domain) {
DnsSearchDomain *d;
DnsServer *dns_server;
assert(s);
assert(domain);
@@ -458,24 +457,27 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
if (dns_name_endswith(domain, "invalid") > 0)
return DNS_SCOPE_NO;
/* Always honour search domains for routing queries. Note that
* we return DNS_SCOPE_YES here, rather than just
* DNS_SCOPE_MAYBE, which means wildcard scopes won't be
* considered anymore. */
LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
if (dns_name_endswith(domain, d->name) > 0)
return DNS_SCOPE_YES;
/* If the DNS server has route-only domains, don't send other requests
* to it. This would be a privacy violation, will most probably fail
* anyway, and adds unnecessary load. */
dns_server = dns_scope_get_dns_server(s);
if (dns_server && dns_server_limited_domains(dns_server))
return DNS_SCOPE_NO;
switch (s->protocol) {
case DNS_PROTOCOL_DNS:
case DNS_PROTOCOL_DNS: {
DnsServer *dns_server;
/* Never route things to scopes that lack DNS servers */
dns_server = dns_scope_get_dns_server(s);
if (!dns_server)
return DNS_SCOPE_NO;
/* Always honour search domains for routing queries, except if this scope lacks DNS servers. Note that
* we return DNS_SCOPE_YES here, rather than just DNS_SCOPE_MAYBE, which means other wildcard scopes
* won't be considered anymore. */
LIST_FOREACH(domains, d, dns_scope_get_search_domains(s))
if (dns_name_endswith(domain, d->name) > 0)
return DNS_SCOPE_YES;
/* If the DNS server has route-only domains, don't send other requests to it. This would be a privacy
* violation, will most probably fail anyway, and adds unnecessary load. */
if (dns_server_limited_domains(dns_server))
return DNS_SCOPE_NO;
/* Exclude link-local IP ranges */
if (dns_name_endswith(domain, "254.169.in-addr.arpa") == 0 &&
@@ -490,6 +492,7 @@ DnsScopeMatch dns_scope_good_domain(DnsScope *s, int ifindex, uint64_t flags, co
return DNS_SCOPE_MAYBE;
return DNS_SCOPE_NO;
}
case DNS_PROTOCOL_MDNS:
if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) ||
+63 -23
View File
@@ -32,11 +32,41 @@
#include "string-util.h"
#include "strv.h"
/* A resolv.conf file containing the DNS server and domain data we learnt from uplink, i.e. the full uplink data */
#define PRIVATE_UPLINK_RESOLV_CONF "/run/systemd/resolve/resolv.conf"
/* A resolv.conf file containing the domain data we learnt from uplink, but our own DNS server address. */
#define PRIVATE_STUB_RESOLV_CONF "/run/systemd/resolve/stub-resolv.conf"
/* A static resolv.conf file containing no domains, but only our own DNS sever address */
#define PRIVATE_STATIC_RESOLV_CONF ROOTLIBEXECDIR "/resolv.conf"
static bool file_is_our_own(const struct stat *st) {
const char *path;
assert(st);
FOREACH_STRING(path,
PRIVATE_UPLINK_RESOLV_CONF,
PRIVATE_STUB_RESOLV_CONF,
PRIVATE_STATIC_RESOLV_CONF) {
struct stat own;
/* Is it symlinked to our own uplink file? */
if (stat(path, &own) >= 0 &&
st->st_dev == own.st_dev &&
st->st_ino == own.st_ino)
return true;
}
return false;
}
int manager_read_resolv_conf(Manager *m) {
_cleanup_fclose_ FILE *f = NULL;
struct stat st, own;
struct stat st;
char line[LINE_MAX];
usec_t t;
int r;
assert(m);
@@ -57,20 +87,10 @@ int manager_read_resolv_conf(Manager *m) {
}
/* Have we already seen the file? */
t = timespec_load(&st.st_mtim);
if (t == m->resolv_conf_mtime)
if (timespec_load(&st.st_mtim) == m->resolv_conf_mtime)
return 0;
/* Is it symlinked to our own file? */
if (stat(PRIVATE_UPLINK_RESOLV_CONF, &own) >= 0 &&
st.st_dev == own.st_dev &&
st.st_ino == own.st_ino)
return 0;
/* Is it symlinked to our own stub file? */
if (stat(PRIVATE_STUB_RESOLV_CONF, &own) >= 0 &&
st.st_dev == own.st_dev &&
st.st_ino == own.st_ino)
if (file_is_our_own(&st))
return 0;
f = fopen("/etc/resolv.conf", "re");
@@ -87,6 +107,9 @@ int manager_read_resolv_conf(Manager *m) {
goto clear;
}
if (file_is_our_own(&st))
return 0;
dns_server_mark_all(m->dns_servers);
dns_search_domain_mark_all(m->search_domains);
@@ -117,7 +140,7 @@ int manager_read_resolv_conf(Manager *m) {
}
}
m->resolv_conf_mtime = t;
m->resolv_conf_mtime = timespec_load(&st.st_mtim);
/* Flush out all servers and search domains that are still
* marked. Those are then ones that didn't appear in the new
@@ -216,14 +239,18 @@ static void write_resolv_conf_search(
static int write_uplink_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
Iterator i;
fputs_unlocked("# This file is managed by man:systemd-resolved(8). Do not edit.\n#\n"
fputs_unlocked("# This file is managed by man:systemd-resolved(8). Do not edit.\n"
"#\n"
"# This is a dynamic resolv.conf file for connecting local clients directly to\n"
"# all known DNS servers.\n#\n"
"# all known uplink DNS servers. This file lists all configured search domains.\n"
"#\n"
"# Third party programs must not access this file directly, but only through the\n"
"# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
"# replace this symlink by a static file or a different symlink.\n#\n"
"# replace this symlink by a static file or a different symlink.\n"
"#\n"
"# See man:systemd-resolved.service(8) for details about the supported modes of\n"
"# operation for /etc/resolv.conf.\n\n", f);
"# operation for /etc/resolv.conf.\n"
"\n", f);
if (ordered_set_isempty(dns))
fputs_unlocked("# No DNS servers known.\n", f);
@@ -242,10 +269,23 @@ static int write_uplink_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSe
}
static int write_stub_resolv_conf_contents(FILE *f, OrderedSet *dns, OrderedSet *domains) {
fputs("# This file is managed by man:systemd-resolved(8). Do not edit.\n#\n"
"# 127.0.0.53 is the systemd-resolved stub resolver.\n"
"# run \"systemd-resolve --status\" to see details about the actual nameservers.\n\n"
"nameserver 127.0.0.53\n", f);
fputs_unlocked("# This file is managed by man:systemd-resolved(8). Do not edit.\n"
"#\n"
"# This is a dynamic resolv.conf file for connecting local clients to the\n"
"# internal DNS stub resolver of systemd-resolved. This file lists all\n"
"# configured search domains.\n"
"#\n"
"# Run \"systemd-resolve --status\" to see details about the uplink DNS servers\n"
"# currently in use.\n"
"#\n"
"# Third party programs must not access this file directly, but only through the\n"
"# symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a different way,\n"
"# replace this symlink by a static file or a different symlink.\n"
"#\n"
"# See man:systemd-resolved.service(8) for details about the supported modes of\n"
"# operation for /etc/resolv.conf.\n"
"\n"
"nameserver 127.0.0.53\n", f);
if (!ordered_set_isempty(domains))
write_resolv_conf_search(domains, f);
-3
View File
@@ -22,8 +22,5 @@
#include "resolved-manager.h"
#define PRIVATE_UPLINK_RESOLV_CONF "/run/systemd/resolve/resolv.conf"
#define PRIVATE_STUB_RESOLV_CONF "/run/systemd/resolve/stub-resolv.conf"
int manager_read_resolv_conf(Manager *m);
int manager_write_resolv_conf(Manager *m);