Domain Name Service: bescherm zelf je privacy
Domain Name Service: databeveiliging zelf maken
Als je op internet rond surft, laat je sporen achter. Bij alle netwerkknooppunten kun je bijvoorbeeld eenvoudig uitlezen wie welke websites bezoekt. Er zijn echter middelen om je privacy te waarborgen en je surfdoelen te beschermen tegen nieuwsgierige blikken. We laten zien hoe je dat doet met de kleine DNSresolver Unbound.
Alle gebruikers laten talrijke sporen na over hun interesses bij hun internetactiviteiten. De name-resolving van het Domain Name System (DNS) is daarbij een hoofdbron, want dat werkt doorgaans zonder versleuteling. Internetproviders, exploitanten 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 verschillende manieren om de inkijk in het DNS-verkeer in te dammen en je persoonlijke gegevens daarmee te beschermen. Je kunt bijvoorbeeld externe DNS-resolvers van externe aanbieders gebruiken die garanderen dat ze de langskomende data niet loggen – maar dat helpt niet tegen eventueel afluisteren onderweg. Een voorbeeld daarvoor staat in onze basisconfiguratie voor een lokaal te installeren DNS-resolver Unbound [1]. Dat opensourceprogramma is beschikbaar voor alle gangbare Linux-distributies en voor Windows. Bij macOS kun je een actuele versie krijgen met de optionele pakketmanagers MacPorts en Homebrew. In dit artikel gaan we in op uitbreidingen van het concept. Daarbij reduceren we de hoeveelheid metadata die de Unboundresolver bij DNS-requests produceert (QNAME minimisation). Omdat dat alleen helpt tegen sniffers bij de root- en top-leveldomeinen, laten we bovendien zien hoe je Unbound op drie manieren kunt inrichten voor een versleutelde communicatie met andere DNS-servers (upstream-forwardresolvers). Daarbij gaat het om DNSCrypt, DNSTor en het nieuwe DNS-over-TLS.
We gaan daarbij uit van de basisconfiguratie in een vorige c't voor de Linuxdistribute Debian – zie www.ct.nl/softlink/1707138. Je kunt Unbound ook op Windows en macOS gebruiken, en zelfs op de beperkte hardware van bijvoorbeeld een energiezuinige Raspberry Pi. Het grootste deel van het instellen gebeurt met het intypen van commando's op een commandline. We hebben echter een handvol configuratiebestanden gemaakt, zodat je niet alles zelf helemaal in hoeft te typen. Het archief met uitgebreide informatie over dit onderwerp en de downloadlinks voor alle gebruikte tools staan bij de link onderaan dit artikel.
Het bewaken van het internetverkeer is voor een groot deel gebaseerd op het analyseren van metadata – bijvoorbeeld 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 traditionele configuratie 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 internetverkeer over de hele wereld.
De Internet Engineering Task Force heeft met de RFC 7816 over QNAME minimisation (waarbij QNAME een samentrekking is van Query Name) een specificatie uitgebracht waarmee dit gedrag is uit te zetten [2]. Als QNAME minimisation ingeschakeld is, krijgen de servers alleen nog de requests waarvoor ze zelf verantwoordelijk zijn en niet voor alle delen van de domeinnamen. Daardoor krijgt een resolver eerst van een root-server het adres van de DNS-server die verantwoordelijk is voor .nl. Vervolgens krijgt hij daarvan het adres van de server die verantwoordelijk is voor ct.nl, enzovoort.
Bij het testen met QNAME minimisation hebben deelnemers van de IETF geconstateerd dat de name-resolving bij reguliere domeinen (zoals ct.nl) sneller gebeurt dan op de traditionele manier. Alleen bij heel diepe DNS-hiërarchieën die zelden voorkomen, zoals camera01.videostudio. beneden.redactie.ct.nl, treedt er snelheidsverlies op omdat daarvoor meer requests moeten worden verzonden dan nodig.
De RFC-specificatie 7816 heeft op dit moment nog een experimentele status. Er zijn nog problemen met DNS-load-balancers die bij domeinonderdelen zonder DNS-records abusievelijk NXDomain in de DNS-reply's leveren. Daarom is QNAME minimisation bij Unbound in eerste instantie uitgeschakeld. Deze configuratieregel is echter voldoende om de techniek te activeren:
server: qname-minimisation: yes
QNAME minimisation 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-configuratie), dan is de instelling ongeldig. Om dat uit te proberen, moet je in de basisconfiguratie de forwarding naar DNS Watch, Xiala en censurfridns uitschakelen. Open daarvoor een terminal en bewerk het bestand 01_ CacheForwarder.conf:
sudo pico /etc/unbound/unbound.d/—
01_CacheForwarder.conf
Zet commentaartekens voor de regels vanaf forwardzone: tot en met de regel forwardaddr:89.233.43.71 # censurfridns.dk en sla het bestand op met Ctrl+X en Yes.
Download het archief met de configuratieuitbreidingen bij de link aan het eind van dit artikel, pak het uit op de desktop en ga in de terminal naar de archiefdirectory. Zet qname-Minimisation.conf in de juiste directory: cd ~/Desktop/1712-124 cp qname-minimisation.conf
/etc/unbound/unbound.d
Kijk met unbound-checkconf of de configuratiesyntaxis geen fouten heeft en start Unbound dan opnieuw op:
sudo service unbound restart
DNS-versleuteling
We gaan aan de hand van drie voorbeelden met DNS-over-TLS, DNSCrypt en DNSTor laten zien hoe je Unbound redelijk direct of indirect voor versleutelde DNS-requests kunt instellen. De drie configuraties sluiten elkaar uit, er kan er altijd maar één van de drie actief zijn. Bovendien sluiten alle drie het gebruik uit van andere openbare DNSresolvers, zoals bijvoorbeeld Xiala. Als je
verschillende configuraties wilt uitproberen, zet je de configuratiebestanden in aparte subdirectory's, bijvoorbeeld 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 configuratie in de directory dnsovertls gezet hebt:
include: "/opt/local/etc/unbound/—
dnsovertls/*.conf"
DNS over TLS
DNS-over-TLS is een protocoluitbreiding van de IETF-werkgroep DPRIVE [3]. Daarbij stuurt een client zijn DNS-requests niet zoals gebruikelijk via het snelle User Datagram Protocol (UDP) naar een resolver, maar versleuteld met TLS (Transport Layer Security). Dat betekent wel meer protocoloverhead, maar op die manier zijn DNSrequests 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 DPRIVEwerkgroep op hun website. Daar staat ook óf en in welke omvang de serverexploitanten de toegang loggen.
We gebruiken in het configuratievoorbeeld twee servers van SurfNET. De ip-adressen van de beide servers staan in het configuratiebestand 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 configuratie worden alle DNS-requests via TLS naar de upstream-forwarder gestuurd. In RFC 7858 is daar poort 853 voor gespecificeerd. Poort 53 blijft aan de gebruikelijke onversleutelde DNS-requests via UDP voorbehouden (of TCP, als de DNS-reply te groot is voor een UDP-pakket).
Het ip-adres en poortnummer moet je met een @ scheiden. De optie forwardfirst: no sluit onversleutelde DNS-requests uit. De regel forward-ssl-upstraem: yes bepaalt dat de Unbound-server de requests met TLS versleutelt. Het bestand tls-forward.conf moet in de directory /etc/ nbound/dnsovertls staan. Zorg ervoor dat je configuratiesyntaxis klopt (unboundcheckconf ) en herstart Unbound.
Om te testen of Unbound de data zoals gewenst versleutelt, kun je het commando iftop of netwerksniffers als tcpdump of Wireshark gebruiken. De computer waar Unbound op draait, moet TCP-verbindingen 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 waarschijnlijk aan een firewall die het verkeer via poort 853 blokkeert. In dergelijke gevallen kun je resolvers bij de configuratie toevoegen die met TLS versleutelde requests via poort 443 kunnen ontvangen (bijvoorbeeld 199.58.81.218). Zet na het ipadres en het @-teken dan 443. Die poort is normaal aan het HTTPS-verkeer voorbehouden en wordt door firewalls nauwelijks geblokkeerd.
Versie 1.6.0 tot en met 1.6.5 van Unbound is niet geoptimaliseerd op snelheid. Hij gebruikt bijvoorbeeld bijvoorbeeld 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 vergelijkbaar snelle DNS-reply's als bij het gewone DNS via UDP. Een voorbeeldconfiguratie voor dnsfwd staat in het bestand dnsfwd-dns-over-tls.conf.
Als je als administrator een openbare resolver op poort 443 wilt draaien en op een internetaansluiting een webserver die die poort al gebruikt, kun je de door Daniel K. Gilmore ontwikkelde hddemux gebruiken. Dat is een protocol-demultiplexer voor ipverkeer op poort 443. Dan is hddemux bijvoorbeeld 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 tunnelprotocol ontwikkeld voor het versturen van DNS-data tussen de client (dnscrypt-proxy) en een resolver. De resolver wordt met een cryptografische sleutel geauthenticeerd om man-in-the-middleaanvallen af te weren.
DNSCrypt is opensource en de client dnscrypt-proxy kun je met de pakketmanager van de meeste Linux- en BSD-systemen installeren. 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 alternatieve 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-configuratie 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 versleuteld aan een DNSCrypt-resolver door. Hij communiceert met de resolver via poort 443 met het eigen DNSCryptprotocol.
Als je de client installeert, 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-configuratie (normaal gesproken
in /etc/systemd/resolved.conf) op het adres 127.0.2.1. Voeg bij de configuratie 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 overschreven. 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 alternatieve DNS-root-zone 'opennic.glue' gebruikt. Of dat het geval is, kun je achterhalen met het dig-commando:
dig ns .
Als DNSCrypt ingesteld is, levert het commando bij het deel 'Answer section' niet de gebruikelijke 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 geselecteerde DNSCrypt-resolver. Als de DNS-resolver niet beschikbaar is, mislukt de name-resolving. Je kunt de beschikbaarheid 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 DNSCryptresolver mocht uitvallen. Om dat in te stellen, stop en maskeer je de DNSCryptservice 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 beschikbare resolvers een willekeurige pikt, die in elk geval via IPv4 bereikbaar moet zijn, ondertekende DNS-reply's valideert en volgens de exploitant zelf geen DNSrequests 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 instantievariabele %i noodzakelijk: 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-configuratie 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 DNSrequests 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 ondertekende DNS-requests lokaal tegen het vertrouwensanker (trust anchor) van de IANA-root-zone. Bij DNSCrypt komt het voor dat er resolvers geselecteerd 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 vertrouwensanker van de afzonderlijke root-zones ook in de Unboundconfiguratie. 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-configuratie met het sleutelwoord trust-anchor: "<KSK>". Vervang <KSK> daarbij door de informatie van de dig-request. Zijn er verschillende DNSroot-KSK's, dan voeg je het sleutelwoord meerdere malen toe.
Als je daarentegen alleen bepaalde DNSCrypt-resolvers wilt gebruiken, kopieer dan het bestand /usr/share/dnscryptproxy/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 configuratiebestand in /etc/dnscrypt-proxy/dnscrypt-proxy.conf en start je de service onnieuw op:
ResolversList /etc/dnscrypt-proxy/—
dnscrypt-resolvers.csv
DNS via Tor
Het anonimiseringsnetwerk 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 versleuteld verbonden computers (Tor-circuit). Data van Tor-clients worden versleuteld via meerdere tussencomputers (Tor-relay-nodes) verstuurd om de herkomst van het communicatie-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 gebruikelijke 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 voornamelijk geschikt om te surfen, maar niet om servers te laten draaien. Ook kun je geen DNSSEC-requests gebruiken, zodat Unbound ondertekende reply's niet kan valideren. De exploitanten van kwaadwillende Tor-exit-nodes kunnen DNS-reply's dus ongemerkt vervalsen.
Om DNS-requests via Tor te laten lopen, moet de Tor-service geïnstalleerd en gestart zijn: sudo apt install tor. Schakel in de Tor-configuratie /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 AutomapHostsOnResolve 1 AutomapHostsSuffixes .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 terugleveren. DNS-requests zijn met een lokale DNScache sneller te maken. Voor Tor stel je Unbound net zo in als bij de forwardingvoorbeelden voor DNS-over-TLS of DNSCrypt. Een kant-en-klaar bestand met de naam tor-forward.conf staat in het downloadarchief. Zet dat in de map /etc/ unbound/tordns.
Performance
De snelheid van de DNS-resolving is belangrijk voor de totale snelheid van een internethost omdat DNS de basis is voor alle netwerkcommunicatie. Websites zijn opgebouwd uit veel afzonderlijke elementen die van verschillende servers moeten komen, en voor elk element is dan een DNS-request nodig. Daarom zijn zelfs de kleinste latenties van belang en is een vergelijking tussen de gangbare DNS-techniek en die met versleutelde methoden van belang.
Bij de resultaten moet je er rekening mee houden dat niet alle nieuwe implementaties geoptimaliseerd zijn. Maar bij de gangbare DNS-requests is te zien dat DNS-over-TLS ondanks versleuteling en TCP-verbindingen mee kan met het klassieke DNS.
Bij een eerste test moesten de verschillende Unbound-configuraties 1000 domeinen van de Alexa-toplijst omzetten naar de bijbehorende IPv4-adressen. Om cache-effecten uit te sluiten, hebben we vóór elke meting de Unbound-cache leeggemaakt. De test levert daarom alleen de snelheden van de verschillende transportprotocollen en versleutelingen.
Bij een tweede test hebben we 1000 DNS-requests van een typisch kantoornetwerk afgespeeld en met tcpdump geregistreerd. In dat scenario werd de cache alleen voor het starten van de 1000 requests leeggemaakt, zodat daar van geprofiteerd kan worden – en de getallen laten zien dat dit loont. (nkr)