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.
This commit is contained in:
Martin Pitt 2016-06-24 07:54:28 +02:00 committed by GitHub
parent a2c28c6451
commit ceeddf79b8
7 changed files with 33 additions and 0 deletions

8
NEWS
View File

@ -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

View File

@ -202,6 +202,23 @@
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Cache=</varname></term>
<listitem><para>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.</para>
<para>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 <emphasis>very</emphasis> high with DNSSEC.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -46,6 +46,7 @@ struct Manager {
ResolveSupport llmnr_support;
ResolveSupport mdns_support;
DnssecMode dnssec_mode;
bool enable_cache;
/* Network */
Hashmap *links;

View File

@ -17,3 +17,4 @@
#Domains=
#LLMNR=yes
#DNSSEC=@DEFAULT_DNSSEC_MODE@
#Cache=yes