From 61ecb465b1c803316cb55bae0c2d7cf3c0008589 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Feb 2016 18:40:02 +0100 Subject: resolved: turn on DNSSEC by default, unless configured otherwise Let's make sure DNSSEC gets more testing, by defaulting DNSSEC to "allow-downgrade" mode. Since distros should probably not ship DNSSEC enabled by default add a configure switch to disable this again. DNSSEC in "allow-downgrade" mode should mostly work without affecting user experience. There's one exception: some captive portal systems rewrite DNS in order to redirect HTTP traffic to the captive portal. If these systems implement DNS servers that are otherwise DNSSEC-capable (which in fact is pretty unlikely, but still...), then this will result in the captive portal being inaccessible. To fix this support in NetworkManager (or any other network management solution that does captive portal detection) is required, which simply turns off DNSSEC during the captive portal detection, and resets it back to the default (i.e. on) after captive portal authentication is complete. --- src/resolve/resolved-manager.c | 2 +- src/resolve/resolved.conf.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/resolve') diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index bf5efe4cfa..09e15fa230 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -485,7 +485,7 @@ int manager_new(Manager **ret) { m->llmnr_support = RESOLVE_SUPPORT_YES; m->mdns_support = RESOLVE_SUPPORT_NO; - m->dnssec_mode = DNSSEC_NO; + m->dnssec_mode = DEFAULT_DNSSEC_MODE; m->read_resolv_conf = true; m->need_builtin_fallbacks = true; m->etc_hosts_last = m->etc_hosts_mtime = USEC_INFINITY; diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in index efc9c6733a..a288588924 100644 --- a/src/resolve/resolved.conf.in +++ b/src/resolve/resolved.conf.in @@ -16,4 +16,4 @@ #FallbackDNS=@DNS_SERVERS@ #Domains= #LLMNR=yes -#DNSSEC=no +#DNSSEC=@DEFAULT_DNSSEC_MODE@ -- cgit v1.2.3-54-g00ecf From 41815a4aa66c59070dc86aa99eebfa720e8a263e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 15 Feb 2016 21:25:33 +0100 Subject: resolve: print a noisy warning if we show crypto keys that could not be authenticated Doing DNS retrieval on non-authenticated crypt keys is useless, hence warn loudly about it. --- src/resolve/dns-type.c | 17 +++++++++++++++++ src/resolve/dns-type.h | 1 + src/resolve/resolve-tool.c | 17 +++++++++++++++++ 3 files changed, 35 insertions(+) (limited to 'src/resolve') diff --git a/src/resolve/dns-type.c b/src/resolve/dns-type.c index b2f479cae5..78d9d5733f 100644 --- a/src/resolve/dns-type.c +++ b/src/resolve/dns-type.c @@ -193,6 +193,23 @@ bool dns_type_is_obsolete(uint16_t type) { DNS_TYPE_NULL); } +bool dns_type_needs_authentication(uint16_t type) { + + /* Returns true for all (non-obsolete) RR types where records are not useful if they aren't + * authenticated. I.e. everything that contains crypto keys. */ + + return IN_SET(type, + DNS_TYPE_CERT, + DNS_TYPE_SSHFP, + DNS_TYPE_IPSECKEY, + DNS_TYPE_DS, + DNS_TYPE_DNSKEY, + DNS_TYPE_TLSA, + DNS_TYPE_CDNSKEY, + DNS_TYPE_OPENPGPKEY, + DNS_TYPE_CAA); +} + int dns_type_to_af(uint16_t t) { switch (t) { diff --git a/src/resolve/dns-type.h b/src/resolve/dns-type.h index f18ac6eef3..fb7babf12a 100644 --- a/src/resolve/dns-type.h +++ b/src/resolve/dns-type.h @@ -132,6 +132,7 @@ bool dns_type_is_dnssec(uint16_t type); bool dns_type_is_obsolete(uint16_t type); bool dns_type_may_wildcard(uint16_t type); bool dns_type_apex_only(uint16_t type); +bool dns_type_needs_authentication(uint16_t type); int dns_type_to_af(uint16_t t); bool dns_class_is_pseudo(uint16_t class); diff --git a/src/resolve/resolve-tool.c b/src/resolve/resolve-tool.c index 9aade8e490..c1be03fbb2 100644 --- a/src/resolve/resolve-tool.c +++ b/src/resolve/resolve-tool.c @@ -339,6 +339,7 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_ uint64_t flags; int r; usec_t ts; + bool needs_authentication = false; assert(name); @@ -421,6 +422,10 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_ log_warning_errno(errno, "Failed to resolve interface name for index %i: %m", ifindex); printf("%s%s%s\n", s, isempty(ifname) ? "" : " # interface ", ifname); + + if (dns_type_needs_authentication(t)) + needs_authentication = true; + n++; } if (r < 0) @@ -441,6 +446,18 @@ static int resolve_record(sd_bus *bus, const char *name, uint16_t class, uint16_ print_source(flags, ts); + if ((flags & SD_RESOLVED_AUTHENTICATED) == 0 && needs_authentication) { + fflush(stdout); + + fprintf(stderr, "\n%s" + "WARNING: The resources shown contain cryptographic key data which could not be\n" + " authenticated. It is not suitable to authenticate any communication.\n" + " This is usually indication that DNSSEC authentication was not enabled\n" + " or is not available for the selected protocol or DNS servers.%s\n", + ansi_highlight_red(), + ansi_normal()); + } + return 0; } -- cgit v1.2.3-54-g00ecf From c77d26122a35a8555953bbe71e4a4ff664f3462c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 16 Feb 2016 14:17:53 +0100 Subject: resolved: make sure to normalize all domain names returned via the bus Most domain names we deal with are normalized anyway (since we read them that way from DNS packets), but some might not (because they are synthesized from unnormalized configuration or so), hence make sure to normalize all names before passing them out to clients, to be fully deterministic. Note that internally we are process normalized and non-normalized names the same way, and while comparing them ignore the differences due to unnormalized names. However, that internal implementation detail really shouldn't spill out the clients, hence make sure to clean it all up. --- src/resolve/resolved-bus.c | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) (limited to 'src/resolve') diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c index 6f08c43327..2d94baeb7e 100644 --- a/src/resolve/resolved-bus.c +++ b/src/resolve/resolved-bus.c @@ -140,6 +140,7 @@ static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifin static void bus_method_resolve_hostname_complete(DnsQuery *q) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_free_ char *normalized = NULL; DnsResourceRecord *rr; unsigned added = 0; int ifindex, r; @@ -199,11 +200,17 @@ static void bus_method_resolve_hostname_complete(DnsQuery *q) { if (r < 0) goto finish; + /* The key names are not necessarily normalized, make sure that they are when we return them to our bus + * clients. */ + r = dns_name_normalize(DNS_RESOURCE_KEY_NAME(canonical->key), &normalized); + if (r < 0) + goto finish; + /* Return the precise spelling and uppercasing and CNAME target reported by the server */ assert(canonical); r = sd_bus_message_append( reply, "st", - DNS_RESOURCE_KEY_NAME(canonical->key), + normalized, SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated)); if (r < 0) goto finish; @@ -395,13 +402,19 @@ static void bus_method_resolve_address_complete(DnsQuery *q) { question = dns_query_question_for_protocol(q, q->answer_protocol); DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) { + _cleanup_free_ char *normalized = NULL; + r = dns_question_matches_rr(question, rr, NULL); if (r < 0) goto finish; if (r == 0) continue; - r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name); + r = dns_name_normalize(rr->ptr.name, &normalized); + if (r < 0) + goto finish; + + r = sd_bus_message_append(reply, "(is)", ifindex, normalized); if (r < 0) goto finish; @@ -671,6 +684,7 @@ fail: static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) { _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL; + _cleanup_free_ char *normalized = NULL; DnsQuery *aux; int r; @@ -727,10 +741,14 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) if (r < 0) return r; + r = dns_name_normalize(rr->srv.name, &normalized); + if (r < 0) + return r; + r = sd_bus_message_append( reply, "qqqs", - rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name); + rr->srv.priority, rr->srv.weight, rr->srv.port, normalized); if (r < 0) return r; @@ -776,9 +794,17 @@ static int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) if (r < 0) return r; + if (canonical) { + normalized = mfree(normalized); + + r = dns_name_normalize(DNS_RESOURCE_KEY_NAME(canonical->key), &normalized); + if (r < 0) + return r; + } + /* Note that above we appended the hostname as encoded in the * SRV, and here the canonical hostname this maps to. */ - r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name); + r = sd_bus_message_append(reply, "s", normalized); if (r < 0) return r; -- cgit v1.2.3-54-g00ecf