From ceeddf79b8464469a5307a1030862c7c4fe289e9 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Fri, 24 Jun 2016 07:54:28 +0200 Subject: [PATCH] resolved: add option to disable caching (#3592) In some cases, caching DNS results locally is not desirable, a it makes DNS cache poisoning attacks a tad easier and also allows users on the system to determine whether or not a particular domain got visited by another user. Thus provide a new "Cache" resolved.conf option to disable it. --- NEWS | 8 ++++++++ man/resolved.conf.xml | 17 +++++++++++++++++ src/resolve/resolved-dns-transaction.c | 4 ++++ src/resolve/resolved-gperf.gperf | 1 + src/resolve/resolved-manager.c | 1 + src/resolve/resolved-manager.h | 1 + src/resolve/resolved.conf.in | 1 + 7 files changed, 33 insertions(+) diff --git a/NEWS b/NEWS index 7ecb10e2162..e4efb476c68 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,14 @@ CHANGES WITH 231: "Options=" with a drop-in, or mount /tmp from /etc/fstab with your desired options. + * systemd-resolved gained a new "Cache=" option in resolved.conf. + Local caching makes DNS poisoning attacks slightly easier and allows + a local user to detect whether any other user on the same machine has + recently visited a given DNS name (privacy). If that is a concern, + you can disable local caching with this option at the cost of slower + DNS resolution (which is particularly expensive with DNSSEC). The + default continues to be "yes" (i. e. caching is enabled). + Contributions from: ... — Somewhere, 2016-XX-XX diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml index 920ce9e89b2..024ad6a9c16 100644 --- a/man/resolved.conf.xml +++ b/man/resolved.conf.xml @@ -202,6 +202,23 @@ + + Cache= + Takes a boolean argument. If "yes" (the default), + resolving a domain name which already got queried earlier will re-use + the previous result as long as that is still valid, and thus does not + need to do an actual network request. + + However, local caching slightly increases the chance of a + successful DNS poisoning attack, and might also be a privacy problem in + some environments: By measuring the time it takes to resolve a + particular network name, a user can determine whether any other user on + the same machine recently visited that name. If either of these is a + concern, you may disable the local caching. Be aware that this comes at + a performance cost, which is very high with DNSSEC. + + + diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 09f60d3e76e..06e71454226 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -590,6 +590,10 @@ static void dns_transaction_cache_answer(DnsTransaction *t) { if (!IN_SET(t->scope->protocol, DNS_PROTOCOL_DNS, DNS_PROTOCOL_LLMNR)) return; + /* Caching disabled? */ + if (!t->scope->manager->enable_cache) + return; + /* We never cache if this packet is from the local host, under * the assumption that a locally running DNS server would * cache this anyway, and probably knows better when to flush diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf index 82f26215df6..2fd56bce26d 100644 --- a/src/resolve/resolved-gperf.gperf +++ b/src/resolve/resolved-gperf.gperf @@ -19,3 +19,4 @@ Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0 Resolve.Domains, config_parse_search_domains, 0, 0 Resolve.LLMNR, config_parse_resolve_support, 0, offsetof(Manager, llmnr_support) Resolve.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Manager, dnssec_mode) +Resolve.Cache, config_parse_bool, 0, offsetof(Manager, enable_cache) diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 30036049da6..add463b6a9a 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -500,6 +500,7 @@ int manager_new(Manager **ret) { m->llmnr_support = RESOLVE_SUPPORT_YES; m->mdns_support = RESOLVE_SUPPORT_NO; m->dnssec_mode = DEFAULT_DNSSEC_MODE; + m->enable_cache = true; 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-manager.h b/src/resolve/resolved-manager.h index 114fec79277..deebd8e4845 100644 --- a/src/resolve/resolved-manager.h +++ b/src/resolve/resolved-manager.h @@ -46,6 +46,7 @@ struct Manager { ResolveSupport llmnr_support; ResolveSupport mdns_support; DnssecMode dnssec_mode; + bool enable_cache; /* Network */ Hashmap *links; diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in index a2885889246..3bd8389c888 100644 --- a/src/resolve/resolved.conf.in +++ b/src/resolve/resolved.conf.in @@ -17,3 +17,4 @@ #Domains= #LLMNR=yes #DNSSEC=@DEFAULT_DNSSEC_MODE@ +#Cache=yes -- 2.39.2