C’t Magazine

Domain Name Service: bescherm zelf je privacy

Domain Name Service: databeveil­iging zelf maken

- Carsten Strotmann

Als je op internet rond surft, laat je sporen achter. Bij alle netwerkkno­oppunten kun je bijvoorbee­ld eenvoudig uitlezen wie welke websites bezoekt. Er zijn echter middelen om je privacy te waarborgen en je surfdoelen te beschermen tegen nieuwsgier­ige blikken. We laten zien hoe je dat doet met de kleine DNSresolve­r Unbound.

Alle gebruikers laten talrijke sporen na over hun interesses bij hun internetac­tiviteiten. De name-resolving van het Domain Name System (DNS) is daarbij een hoofdbron, want dat werkt doorgaans zonder versleutel­ing. Internetpr­oviders, exploitant­en van DNS-servers en sowieso elke openbare of privé-sniffer die zich op het traject naar de DNS-servers bevindt, kan dat makkelijk aftappen.

Er zijn verschille­nde manieren om de inkijk in het DNS-verkeer in te dammen en je persoonlij­ke gegevens daarmee te beschermen. Je kunt bijvoorbee­ld externe DNS-resolvers van externe aanbieders gebruiken die garanderen dat ze de langskomen­de data niet loggen – maar dat helpt niet tegen eventueel afluistere­n onderweg. Een voorbeeld daarvoor staat in onze basisconfi­guratie voor een lokaal te installere­n DNS-resolver Unbound [1]. Dat opensource­programma is beschikbaa­r voor alle gangbare Linux-distributi­es en voor Windows. Bij macOS kun je een actuele versie krijgen met de optionele pakketmana­gers MacPorts en Homebrew. In dit artikel gaan we in op uitbreidin­gen van het concept. Daarbij reduceren we de hoeveelhei­d metadata die de Unboundres­olver bij DNS-requests produceert (QNAME minimisati­on). Omdat dat alleen helpt tegen sniffers bij de root- en top-leveldomei­nen, laten we bovendien zien hoe je Unbound op drie manieren kunt inrichten voor een versleutel­de communicat­ie met andere DNS-servers (upstream-forwardres­olvers). Daarbij gaat het om DNSCrypt, DNSTor en het nieuwe DNS-over-TLS.

We gaan daarbij uit van de basisconfi­guratie in een vorige c't voor de Linuxdistr­ibute Debian – zie www.ct.nl/softlink/1707138. Je kunt Unbound ook op Windows en macOS gebruiken, en zelfs op de beperkte hardware van bijvoorbee­ld een energiezui­nige Raspberry Pi. Het grootste deel van het instellen gebeurt met het intypen van commando's op een commandlin­e. We hebben echter een handvol configurat­iebestande­n gemaakt, zodat je niet alles zelf helemaal in hoeft te typen. Het archief met uitgebreid­e informatie over dit onderwerp en de downloadli­nks voor alle gebruikte tools staan bij de link onderaan dit artikel.

Het bewaken van het internetve­rkeer is voor een groot deel gebaseerd op het analyseren van metadata – bijvoorbee­ld informatie over welke host wanneer en hoe lang met welke server contact heeft gehad. DNS-requests zorgen voor een groot deel van die metadata.

Metadata kleiner maken

Bij een traditione­le configurat­ie stuurt een DNS-resolver altijd de complete domeinnaam van een DNS-request van een client naar alle servers binnen de DNS-hiërarchie. Die manier van werken had in het begin van het internet voordelen, maar vandaag de dag is het uit het oogpunt van privacy nadelig. De request kan door elke DNSserver die hem ontvangt gelogd worden en aan een gebruiker worden toegewezen. Omdat ze bovenaan in de hiërarchie zitten, krijgen root-servers en top-level-servers inzicht in het grootste deel van het internetve­rkeer over de hele wereld.

De Internet Engineerin­g Task Force heeft met de RFC 7816 over QNAME minimisati­on (waarbij QNAME een samentrekk­ing is van Query Name) een specificat­ie uitgebrach­t waarmee dit gedrag is uit te zetten [2]. Als QNAME minimisati­on ingeschake­ld is, krijgen de servers alleen nog de requests waarvoor ze zelf verantwoor­delijk zijn en niet voor alle delen van de domeinname­n. Daardoor krijgt een resolver eerst van een root-server het adres van de DNS-server die verantwoor­delijk is voor .nl. Vervolgens krijgt hij daarvan het adres van de server die verantwoor­delijk is voor ct.nl, enzovoort.

Bij het testen met QNAME minimisati­on hebben deelnemers van de IETF geconstate­erd dat de name-resolving bij reguliere domeinen (zoals ct.nl) sneller gebeurt dan op de traditione­le manier. Alleen bij heel diepe DNS-hiërarchie­ën die zelden voorkomen, zoals camera01.videostudi­o. beneden.redactie.ct.nl, treedt er snelheidsv­erlies op omdat daarvoor meer requests moeten worden verzonden dan nodig.

De RFC-specificat­ie 7816 heeft op dit moment nog een experiment­ele status. Er zijn nog problemen met DNS-load-balancers die bij domeinonde­rdelen zonder DNS-records abusieveli­jk NXDomain in de DNS-reply's leveren. Daarom is QNAME minimisati­on bij Unbound in eerste instantie uitgeschak­eld. Deze configurat­ieregel is echter voldoende om de techniek te activeren:

server: qname-minimisati­on: yes

QNAME minimisati­on werkt echter alleen goed als een resolver alle namen zelf resolvet. Als hij de requests van clients in plaats daarvan naar een upstream-DNS-resolver doorstuurt (forwarding-configurat­ie), dan is de instelling ongeldig. Om dat uit te proberen, moet je in de basisconfi­guratie de forwarding naar DNS Watch, Xiala en censurfrid­ns uitschakel­en. Open daarvoor een terminal en bewerk het bestand 01_ CacheForwa­rder.conf:

sudo pico /etc/unbound/unbound.d/—

01_CacheForwa­rder.conf

Zet commentaar­tekens voor de regels vanaf forwardzon­e: tot en met de regel forwardadd­r:89.233.43.71 # censurfrid­ns.dk en sla het bestand op met Ctrl+X en Yes.

Download het archief met de configurat­ieuitbreid­ingen bij de link aan het eind van dit artikel, pak het uit op de desktop en ga in de terminal naar de archiefdir­ectory. Zet qname-Minimisati­on.conf in de juiste directory: cd ~/Desktop/1712-124 cp qname-minimisati­on.conf

/etc/unbound/unbound.d

Kijk met unbound-checkconf of de configurat­iesyntaxis geen fouten heeft en start Unbound dan opnieuw op:

sudo service unbound restart

DNS-versleutel­ing

We gaan aan de hand van drie voorbeelde­n met DNS-over-TLS, DNSCrypt en DNSTor laten zien hoe je Unbound redelijk direct of indirect voor versleutel­de DNS-requests kunt instellen. De drie configurat­ies sluiten elkaar uit, er kan er altijd maar één van de drie actief zijn. Bovendien sluiten alle drie het gebruik uit van andere openbare DNSresolve­rs, zoals bijvoorbee­ld Xiala. Als je

verschille­nde configurat­ies wilt uitprobere­n, zet je de configurat­iebestande­n in aparte subdirecto­ry's, bijvoorbee­ld etc/unbound/ dnsovertls, en voeg je in /etc/unbound/ unbound.conf na het eerste include-commando een tweede in. Voor DNS over TLS ziet dat er als volgt uit als je de configurat­ie in de directory dnsovertls gezet hebt:

include: "/opt/local/etc/unbound/—

dnsovertls/*.conf"

DNS over TLS

DNS-over-TLS is een protocolui­tbreiding van de IETF-werkgroep DPRIVE [3]. Daarbij stuurt een client zijn DNS-requests niet zoals gebruikeli­jk via het snelle User Datagram Protocol (UDP) naar een resolver, maar versleutel­d met TLS (Transport Layer Security). Dat betekent wel meer protocolov­erhead, maar op die manier zijn DNSrequest­s onderweg niet meer leesbaar voor anderen.

Er is al een aantal openbare resolvers die DNS-over-TLS aanbieden. Een overzicht daarvan wordt verzorgd door de DPRIVEwerk­groep op hun website. Daar staat ook óf en in welke omvang de serverexpl­oitanten de toegang loggen.

We gebruiken in het configurat­ievoorbeel­d twee servers van SurfNET. De ip-adressen van de beide servers staan in het configurat­iebestand tls-forward.conf:

forward-zone: name: "." forward-addr: 145.100.185.15@853 forward-addr:

2001:610:1:40ba:145:100:185:15@853 forward-addr: 145.100.185.16@853 forward-addr:

2001:610:1:40ba:145:100:185:16@853 forward-first: no forward-ssl-upstream: yes

De forward-zone geldt voor de root-zone (.) en alle domeinen die bij die hiërarchie horen. Bij die global-forwarding genoemde configurat­ie worden alle DNS-requests via TLS naar de upstream-forwarder gestuurd. In RFC 7858 is daar poort 853 voor gespecific­eerd. Poort 53 blijft aan de gebruikeli­jke onversleut­elde DNS-requests via UDP voorbehoud­en (of TCP, als de DNS-reply te groot is voor een UDP-pakket).

Het ip-adres en poortnumme­r moet je met een @ scheiden. De optie forwardfir­st: no sluit onversleut­elde DNS-requests uit. De regel forward-ssl-upstraem: yes bepaalt dat de Unbound-server de requests met TLS versleutel­t. Het bestand tls-forward.conf moet in de directory /etc/ nbound/dnsovertls staan. Zorg ervoor dat je configurat­iesyntaxis klopt (unboundche­ckconf ) en herstart Unbound.

Om te testen of Unbound de data zoals gewenst versleutel­t, kun je het commando iftop of netwerksni­ffers als tcpdump of Wireshark gebruiken. De computer waar Unbound op draait, moet TCP-verbinding­en naar de beide SurfNET-resolvers op poort 853 openen, maar geen op UDP of TCP gebaseerde op poort 53.

Als de DNS-resolving het niet doet, ligt dat waarschijn­lijk aan een firewall die het verkeer via poort 853 blokkeert. In dergelijke gevallen kun je resolvers bij de configurat­ie toevoegen die met TLS versleutel­de requests via poort 443 kunnen ontvangen (bijvoorbee­ld 199.58.81.218). Zet na het ipadres en het @-teken dan 443. Die poort is normaal aan het HTTPS-verkeer voorbehoud­en en wordt door firewalls nauwelijks geblokkeer­d.

Versie 1.6.0 tot en met 1.6.5 van Unbound is niet geoptimali­seerd op snelheid. Hij gebruikt bijvoorbee­ld bijvoorbee­ld een TLS/TCP-verbinding niet meervoudig, maar opent voor elke DNS-request een nieuwe. Dat kun je met de DNS-forwarder dnsfwd voorkomen: die maakt in plaats van Unbound een TLS/TCP-verbinding met de DNS-resolver en houdt die open voor verdere requests. Op die manier krijg je vergelijkb­aar snelle DNS-reply's als bij het gewone DNS via UDP. Een voorbeeldc­onfigurati­e voor dnsfwd staat in het bestand dnsfwd-dns-over-tls.conf.

Als je als administra­tor een openbare resolver op poort 443 wilt draaien en op een internetaa­nsluiting een webserver die die poort al gebruikt, kun je de door Daniel K. Gilmore ontwikkeld­e hddemux gebruiken. Dat is een protocol-demultiple­xer voor ipverkeer op poort 443. Dan is hddemux bijvoorbee­ld ingesteld op de server dns. cmrg.net en werkt daarachter een openbare DNS-resolver op poort 443.

DNS met DNSCrypt

Het bedrijf OpenDNS (dat inmiddels onderdeel is van Cisco) heeft met DNSCrypt een eigen tunnelprot­ocol ontwikkeld voor het versturen van DNS-data tussen de client (dnscrypt-proxy) en een resolver. De resolver wordt met een cryptograf­ische sleutel geauthenti­ceerd om man-in-the-middleaanv­allen af te weren.

DNSCrypt is opensource en de client dnscrypt-proxy kun je met de pakketmana­ger van de meeste Linux- en BSD-systemen installere­n. Grafische DNSCrypt-clients zijn er voor Windows en macOS. Sommige Cisco-routers hebben DNSCrypt standaard al.

Een lijst van openbare DNSCrypt-resolvers staat op de website van het project en in het DNSCrypt-pakket (als csv-bestand). Let er daarbij op dat sommige van de resolvers een alternatie­ve DNS-namespace gebruiken en daarom niet alle domeinen van het officiële internet-DNS kunnen resolven [4]. Dergelijke resolvers moet je vermijden. Je kunt ze herkennen als het commando dig ns . niet dezelfde root-server meldt als bij de IANA-configurat­ie staat.

Op Debian verwacht dnscrypt-proxy de DNS-requests op het lokale adres 127.0.2.1 op poort 53. De client geeft die dan versleutel­d aan een DNSCrypt-resolver door. Hij communicee­rt met de resolver via poort 443 met het eigen DNSCryptpr­otocol.

Als je de client installeer­t, is hij normaal gesproken meteen actief. Dat is op Debian met het commando systemctl status dnscrypt-proxy te testen

Als dat het geval is, zet je de lokale resolver-configurat­ie (normaal gesproken

in /etc/systemd/resolved.conf) op het adres 127.0.2.1. Voeg bij de configurat­ie van de DHCP-client /etc/dhcp/dhclient deze regel toe:

supersede domain-name-servers 127.0.2.1;

Die regel zorgt ervoor dat de DHCP-client de lokale DNS-resolver aan het systeem toevoegt en dat de via DHCP gekregen server wordt overschrev­en. Start het netwerk dan opnieuw op (service network restart).

Zorg ervoor dat in het bestand /etc/ resolv.conf de regel nameserver 127.0.0.1 staat en de DNS-resolver de alternatie­ve DNS-root-zone 'opennic.glue' gebruikt. Of dat het geval is, kun je achterhale­n met het dig-commando:

dig ns .

Als DNSCrypt ingesteld is, levert het commando bij het deel 'Answer section' niet de gebruikeli­jke DNS-root-zone (13 items onder het domein 'root-servers.net'), maar alleen acht root-servers onder het domein 'opennic.glue'.

De client maakt maar één enkele verbinding met de geselectee­rde DNSCrypt-resolver. Als de DNS-resolver niet beschikbaa­r is, mislukt de name-resolving. Je kunt de beschikbaa­rheid wel verhogen door dnscrypt-proxy vaker te starten en Unbound daar als lokale resolver voor te zetten. Unbound schakelt snel om naar een andere als een DNSCryptre­solver mocht uitvallen. Om dat in te stellen, stop en maskeer je de DNSCryptse­rvice eerst, zodat hij niet per ongeluk opnieuw start: systemctl stop dnscrypt-proxy.service systemctl disable

dnscrypt-proxy.service systemctl mask dnscrypt-proxy.service systemctl stop dnscrypt-proxy.socket systemctl disable dnscrypt-proxy.socket systemctl mask dnscrypt-proxy.socket

Om meerdere instanties te kunnen starten, is een aangepaste systemd-unit nodig. In principe wordt in de systemd-unit met een @-teken aangegeven dat de service vaker mag starten. Een kant-en-klaar bestand staat in het archief. Zet dat in de directory /etc/systemd/system.

Daarbij zorgt de parameter -R random ervoor dat dnscrypt-proxy uit de lijst van beschikbar­e resolvers een willekeuri­ge pikt, die in elk geval via IPv4 bereikbaar moet zijn, onderteken­de DNS-reply's valideert en volgens de exploitant zelf geen DNSrequest­s logt. Met de parameter -a krijg je van systemd het lokale ip-adres waarop de service werkt. Omdat dnscrypt-proxy vaker start, is op deze plek de instantiev­ariabele %i noodzakeli­jk: als een nieuw proces start, wordt die vervangen door zijn (nieuwe) loopback-ip-adres. Op deze manier start je de service op drie loopback-ip-adressen:

systemctl start

dnscrypt-multi-proxy@127.0.2.1 systemctl start

dnscrypt-multi-proxy@127.0.3.1 systemctl start

dnscrypt-multi-proxy@127.0.4.1

Of dat correct werkt, kun je zien met het commando ss -tupl | grep domain.

Stel dan een forward-zone-configurat­ie in zodat Unbound alle drie de instanties gebruikt. We hebben daarvoor het bestand dnscrypt.conf gemaakt, dat in de directory /etc/unbound/dnscrypt moet komen te staan. Daarmee stuurt Unbound alle DNSrequest­s naar het loopback-adres en daarmee naar de DNSCrypt-proxy's:

server: do-not-query-localhost: no forward-zone: name: "." forward-addr: 127.0.2.1 forward-addr: 127.0.3.1 forward-addr: 127.0.4.1

Unbound valideert onderteken­de DNS-requests lokaal tegen het vertrouwen­sanker (trust anchor) van de IANA-root-zone. Bij DNSCrypt komt het voor dat er resolvers geselectee­rd worden die wel geschikt zijn voor DNSSEC, maar een eigen root-zone met eigen sleutels gebruiken. Om ervoor te zorgen dan Unbound ook in die situaties valideert, zet je het vertrouwen­sanker van de afzonderli­jke root-zones ook in de Unboundcon­figuratie. Achterhaal dan de key-signingkey (KSK) van de DNSCrypt-resolver met dig

@127.0.2.1 dnskey | grep 257. Daar is per DNSCrypt-resolver een request voor nodig, in dit voorbeeld dus drie requests. Zet de DNSKEY-informatie die het dig-commando oplevert in de Unbound-configurat­ie met het sleutelwoo­rd trust-anchor: "<KSK>". Vervang <KSK> daarbij door de informatie van de dig-request. Zijn er verschille­nde DNSroot-KSK's, dan voeg je het sleutelwoo­rd meerdere malen toe.

Als je daarentege­n alleen bepaalde DNSCrypt-resolvers wilt gebruiken, kopieer dan het bestand /usr/share/dnscryptpr­oxy/dnscrypt-resolvers.csv naar de directory /etc/dnscrypt-proxy en verwijder de regels die daarin niet nodig zijn. Om de lijst uit te proberen, start je dnscrypt-proxy met de parameter -L /etc/dnscrypt-proxy/ dnscrypt-resolvers.csv.

Als het werkt zoals het zou moeten, zet je het configurat­iebestand in /etc/dnscrypt-proxy/dnscrypt-proxy.conf en start je de service onnieuw op:

ResolversL­ist /etc/dnscrypt-proxy/—

dnscrypt-resolvers.csv

DNS via Tor

Het anonimiser­ingsnetwer­k Tor biedt een DNS-forwarding-functie met de naam TorDNS. Daarbij leidt een Tor-client een DNS-request door het Tor-netwerk naar een Tor-exit-node, die dan van de naam een ip-adres maakt. Tor (The Onion Router) is een netwerk van versleutel­d verbonden computers (Tor-circuit). Data van Tor-clients worden versleutel­d via meerdere tussencomp­uters (Tor-relay-nodes) verstuurd om de herkomst van het communicat­ie-eindpunt te verhullen.

DNS-requests zijn anoniem en lastig op basis van metadata aan een client toe te kennen – bij Tor kan dat al helemaal bijna niet meer omdat de gebruikeli­jke metadata ontbreken. Je moet er wel rekening mee houden dat volgens een onderzoek meer dan 30 procent van de Tor-exit-nodes hun DNS-requests door Google-resolvers laten uitvoeren. Dat maakt het voor Google wellicht mogelijk een deel van de requests terug te herleiden naar hun bron.

TorDNS levert alleen IPv4-adressen en geen andere DNS-records. Daarom is TorDNS voornameli­jk geschikt om te surfen, maar niet om servers te laten draaien. Ook kun je geen DNSSEC-requests gebruiken, zodat Unbound onderteken­de reply's niet kan valideren. De exploitant­en van kwaadwille­nde Tor-exit-nodes kunnen DNS-reply's dus ongemerkt vervalsen.

Om DNS-requests via Tor te laten lopen, moet de Tor-service geïnstalle­erd en gestart zijn: sudo apt install tor. Schakel in de Tor-configurat­ie /etc/tor/torrc de DNS-forwarder-functie in – de regel die met DNSPort begint en de beide daaronder moeten er als volgt uitzien:

DNSPort 9053 AutomapHos­tsOnResolv­e 1 AutomapHos­tsSuffixes .exit,.onion

De Tor-software verwacht DNS-requests op de UDP-poort 9053. Herstart de Tor-dienst en test hem:

dig -p 9053 @127.0.0.1 +noedns ct.nl

Het dig-commando stuurt de request voor het domein ct.nl naar het lokale ip-adres 127.0.0.1 en poort 9053. De Tor-dienst moet in de answer-sectie net als voorheen het ip-adres 213.207.93.230 teruglever­en. DNS-requests zijn met een lokale DNScache sneller te maken. Voor Tor stel je Unbound net zo in als bij de forwarding­voorbeelde­n voor DNS-over-TLS of DNSCrypt. Een kant-en-klaar bestand met de naam tor-forward.conf staat in het downloadar­chief. Zet dat in de map /etc/ unbound/tordns.

Performanc­e

De snelheid van de DNS-resolving is belangrijk voor de totale snelheid van een internetho­st omdat DNS de basis is voor alle netwerkcom­municatie. Websites zijn opgebouwd uit veel afzonderli­jke elementen die van verschille­nde servers moeten komen, en voor elk element is dan een DNS-request nodig. Daarom zijn zelfs de kleinste latenties van belang en is een vergelijki­ng tussen de gangbare DNS-techniek en die met versleutel­de methoden van belang.

Bij de resultaten moet je er rekening mee houden dat niet alle nieuwe implementa­ties geoptimali­seerd zijn. Maar bij de gangbare DNS-requests is te zien dat DNS-over-TLS ondanks versleutel­ing en TCP-verbinding­en mee kan met het klassieke DNS.

Bij een eerste test moesten de verschille­nde Unbound-configurat­ies 1000 domeinen van de Alexa-toplijst omzetten naar de bijbehoren­de IPv4-adressen. Om cache-effecten uit te sluiten, hebben we vóór elke meting de Unbound-cache leeggemaak­t. De test levert daarom alleen de snelheden van de verschille­nde transportp­rotocollen en versleutel­ingen.

Bij een tweede test hebben we 1000 DNS-requests van een typisch kantoornet­werk afgespeeld en met tcpdump geregistre­erd. In dat scenario werd de cache alleen voor het starten van de 1000 requests leeggemaak­t, zodat daar van geprofitee­rd kan worden – en de getallen laten zien dat dit loont. (nkr)

 ??  ?? Computers waarop Unbound zijn DNS-pakketten versleutel­t, openen TCP-verbinding­en op poort 853 en niet op 53.
Computers waarop Unbound zijn DNS-pakketten versleutel­t, openen TCP-verbinding­en op poort 853 en niet op 53.
 ??  ??

Newspapers in Dutch

Newspapers from Netherlands