Versleutelde DNS-requests met Pi-hole

Alieke van Sommeren
9

Inhoudsopgave

Het grootste deel van het internetverkeer is inmiddels versleuteld. DNS-requests gaan echter nog steeds gewoon als leesbare tekst via de kabels – en daardoor kunnen derden inzicht krijgen in je internetgedrag. Met een Raspberry Pi, Pi-hole en Stubby kun je ook dat privacylek dichten.

In c’t 7-8/2018 pagina 126 hebben we laten zien hoe je de Raspberry Pi als DNS-filter gebruikt om malware, reclame en trackers uit je hele netwerk te houden. Daar hebben we het totaalpakket Pi-hole bij gebruikt, dat makkelijk te installeren is en via zijn webinterface eenvoudig geconfigureerd kan worden.

De Raspberry Pi loopt met enkel die taak zeker niet tegen zijn grenzen aan, dus dat biedt mooi gelegenheid om hem ook te gebruiken voor DNS over TLS (DoT). Dat is nog een effectieve maatregel ter bescherming van je privacy. Hiermee worden je DNSrequests versleuteld verzonden in plaats van als leesbare tekst. In c’t 10/2018 gaan we wat meer in op de achtergronden daarvan, nu richten we ons op de praktijk.


Stubby op de client

Het is mogelijk om Stubby zoals hier beschreven te gebruiken op een Raspberry Pi in combinatie met het trafficfilter Pi-hole, zodat alle clients in je netwerk beveiligd zijn. Je kunt Stubby echter ook stand-alone op een computer installeren om de DNS-requests daarvan te versleutelen. De ontwikkelaars bieden kant-en-klaar gecompileerde versies voor Windows, Linux en macOS (zie de link rechtsonder). Die laatste is zelfs al met een grafische gebruikersinterface te besturen. Stubby luistert op de lokale netwerkinterface van de client, je moet bij de netwerkconfiguratie 127.0.0.1 als DNS-server opgeven.


We gaan er vanuit dat je al een Raspberry Pi met Pi-hole hebt draaien. Als dat nog niet het geval is, volg dan eerst het artikel uit de c’t 7-8/2018, waar het installeren stap voor stap wordt behandeld. Wil je niet een Raspberry Pi als DNS-filter gebruiken, dan kun je met het concept dat we hier beschrijven ook Windows-, Linux- en macOS-clients instrueren om zelf de DNS-requests te versleutelen (zie het kader ‘Stubby op de client’).

Pi-hole gebruikt daarbij de DNSserver dnsmasq om de DNS-requests uit het lokale netwerk te beantwoorden. Die stuurt het request uiteindelijk ook alleen maar door naar een andere nameserver – en dat in leesbare tekst. Om ervoor te zorgen dat de via Pi-hole afgehandelde communicatie met de nameserver op internet versleuteld wordt, heb je wat extra hulp nodig.

Handige hulp

Daar blijkt Stubby goede diensten te kunnen bewijzen. Die tool van het DNS Privacy Project beantwoordt DNSrequests lokaal via UDP-poort 53, maar communiceert naar buiten via DoT met DNS-servers op internet (via TCP-poort 853). De dnsmasq van Pi-hole stuurt zijn requests dan niet meer naar een externe nameserver, maar naar de lokale Stubby.

Daardoor filtert Pi-hole de DNS-requests van clients in het lokale netwerk in eerste instantie net als voorheen, voordat ze naar Stubby worden gestuurd. Die stuurt ze versleuteld door naar nameservers op internet. Als je niet met een nieuwe Raspbian-installatie start, moet je een image van de sd-kaart in de Pi maken voordat je begint. Bij Windows kan dat bijvoorbeeld met Win32 Disk Imager, onder Linux en macOS met het commando dd.

Dan kun je later altijd nog de oude situatie herstellen als er iets misloopt of als je niet tevreden bent met de name-resolving via DoT.

Stubby installeren

Toen we aan dit artikel begonnen, zat Stubby nog niet in de Raspbian-repository – het goede nieuws is dat je de broncode die op Github staat makkelijk op de Raspberry Pi kunt compileren. Daarmee zorg je ervoor dat je altijd de laatste versie krijgt. Voor het compileren heb je maar een paar commando’s nodig.

Maak eerst via SSH verbinding met de Raspberry Pi en installeer de benodigde pakketten met het volgende commando:

sudo apt-get install libtool autoconf m4 libssl-dev libyaml-dev

Vervolgens download je de code van Github en begin je met het compileren:

git clone https://github.com/getdnsapi/getdns.git

cd getdns

git submodule update --init

libtoolize -ci

autoreconf -fi

mkdir build

cd build

../configure --prefix=/usr/local --without-libidn --without-libidn2 --enable-stub-only --with-stubby

make

Daarna start je het installeren met sudo make install en werk je de bibliotheekcache bij met sudo /sbin/ldconfig. Dan wordt het tijd alles te gaan configureren. Open het configuratiebestand met sudo nano /usr/local/etc/stubby/stubby.yml en verander bij ‘LISTEN ADDRESS’ het poortnummer waar Stubby lokaal mee moet werken.

Standaard gebruikt de tool de DNS-poort 53 – maar die wordt al gebruikt door de DNS-server van Pi-hole. In plaats daarvan kun je bijvoorbeeld poort 5353 gebruiken:

listen_addresses:

- 127.0.0.1@5353 

- 0::1@5353

Daarna geef je bij ‘UPSTREAMS’ nog aan naar welke DNS-server Stubby de DNS-requests via DoT moet sturen. Een groot aantal servers is al geactiveerd, een aantal andere is uit gecommentarieerd door een hekje (#) aan het begin van de regel en daardoor niet actief. Het aanbod is groot: op de lijst staan onder meer commerciele aanbieders als Cloudflare (1.1.1.1) en Google (8.8.8.8), waarvan je een hoge snelheid en beschikbaarheid mag verwachten.

Zij geven aan de informatie die tot personen te herleiden is, dus met name het ip-adres van een gebruiker, na hoogstens 48 uur te verwijderen. Andere data zoals het opgevraagde domein en het gebruikte verbindingsprotocol worden daarentegen langer opgeslagen en geanalyseerd.

Alternatief

Als je die bedrijven niet vertrouwt, zijn er ook talrijke niet-commerciële DNS-resolvers die al met DoT overweg kunnen. Een daarvan is getdnsapi.net, die net als Stubby bij het DNS Privacy Project hoort. Een ander data beschermingsvriendelijk alternatief is securedns.eu. De exploitant daarvan geeft aan geen data in combinatie met DNS te loggen. Verwijder in het configuratiebestand de hekjes bij de servers die je wilt gebruiken, en zet juist wel een hekje bij servers waarvan je niet wilt dat Stubby die gebruikt.

Met de parameter round_robin_ upstreams onder ‘CONNECTION SETTINGS’ kun je instellen of Stubby de requests over meerdere DNS-servers moet verspreiden. Die optie is standaard ingeschakeld. Als je die waarde op 0 zet, dan gebruikt Stubby de eerste DNS-server op de lijst. Is die niet bereikbaar, dan wordt er automatisch doorgeschakeld naar de tweede op de lijst.

Zodra je klaar bent met het configuratiebestand, sla je de veranderingen op met Ctrl+O en Enter en beëindig je de teksteditor nano met Ctrl+X. Test daarna met sudo stubby of het installeren gelukt is. Vervolgens beëindig je de tool weer met Ctrl+C.


DNS-requests Pi-Hole Stubby


Stubby is daarna een essentiële component in je netwerkinfrastructuur – als die tool niet draait, dan kan Pi-hole geen name-resolving meer uitvoeren en is het internet dood voor je netwerk. Omdat het programma dus altijd actief moet zijn, moet je het instellen als systemd-service. Door de Git-checkout heb je al een passend sjabloon voor de dienst, namelijk het bestand stubby.service in het pad /home/pi/getdns/stubby/ systemd/.

Open dat bestand met nano:

nano /home/pi/getdns/stubby/systemd/stubby.service

en verander daarin de waarde met de naam ‘ExecStart’ van /usr/bin/stubby naar /usr/local/bin/stubby. Sla de verandering weer op met Ctrl+O, Enter en Ctrl+X. Vervolgens kopieer je het sjabloon nog naar de juiste plek op het systeem:

sudo cp /home/pi/getdns/stubby/systemd/stubby.service /lib/systemd/system/

Voordat je de dienst start, moet je met sudo useradd stubby een nieuwe gebruiker aanmaken omdat Stubby anders als root uitgevoerd zou kunnen worden. Bovendien moet je nog de cache-directory aanmaken. Dat doe je met het commando sudo mkdir /var/cache/stubby. Dan zijn alle benodigde voorbereidingen zo’n beetje klaar.

Activeer en start de Stubbyservice met de volgende commando’s:

sudo systemctl enable stubby

sudo systemctl start stubby

Met het volgende commando kun je verifiëren of Stubby daadwerkelijk op poort 553 op DNS-requests staat te wachten:

dig @127.0.0.1 -p 5353 ct.nl

Als alles goed is gegaan, dan antwoordt de tool met het ip-adres van de c’t-server. Stubby is dan gestart – en jij bent bijna bij je doel. Je moet er namelijk nog wel even voor zorgen dat Pi-hole de binnenkomende DNS-requests van het lokale netwerk naar Stubby doorstuurt.

Andere tak

De op dit moment actuele versie 3.3.1 van Pi-hole staat bij het invoeren van een DNS-server echter niet toe dat je een poortnummer meegeeft, zodat je alleen de standaardpoort voor DNS (53) kunt gebruiken. Dat probleem is het eenvoudigst op te lossen door over te stappen van de stabiele master-versie naar de nog in ontwikkeling zijnde FTLDNS-branch.

Die werkte bij ons op meerdere apparaten zonder problemen bij het dagelijks gebruik. Met de volgende commando’s schakel je over naar die branch:

echo "FTLDNS" | sudo tee /etc/pihole/ftlbranch

pihole checkout core FTLDNS

pihole checkout web FTLDNS

Na de twee checkout-commando’s bevestig je telkens met y van yes dat je die overstap daadwerkelijk wilt maken. De installer bekommert zich om de rest van het verhaal. De huidige configuratie wordt daarbij overgenomen. Als je terug wilt naar de master-branch, staan de bijbehorende commando’s in een blogpost van de Pi-hole-ontwikkelaar.

DNS-requests Pi-hole Stubby

Na het installeren van Stubby stel je die DNS-tool in als DNS-server in de webinterface van Pi-hole.

Na het wisselen van versie open je de Pi-hole-webinterface (http://pi.hole/ admin) en log je in met je wachtwoord. Daarna ga je links in het menu naar ‘Settings / DNS’ en deactiveer je de tot dan toe gebruikte DNS-server door het vinkje ernaast simpelweg te verwijderen. Activeer in plaats daarvan ‘Custom 1 (IPv4)’ en geef als ip-adres 127.0.0.1#5353 op.

Bij die gelegenheid kun je ook meteen ‘Use DNSSEC’ inschakelen om het valideren van cryptografische signatures door Pi-hole in te schakelen. Met een klik op ‘Save’ wordt de nieuwe configuratie dan overgenomen.

Vertrouwen is goed …

Je Pi-hole wikkelt de DNS-requests dan dankzij Stubby af via DNS over TLS. Om jezelf daarvan te verzekeren, kun je een blik werpen op het dataverkeer van de Raspberry Pi. Daar heb je de packet-sniffer tcpdump voor nodig, die je heel makkelijk installeert met sudo apt-get install tcpdump. Kijk eerst eens naar het DNS-verkeer op UDPpoort 53:

sudo tcpdump -A -i eth0 udp and port 53

Als de Raspberry Pi via wifi met het netwerk verbonden is, moet je de interface eth0 vervangen door wlan0. Als je dan internet opgaat met een client waarbij Pihole als DNS-server is ingesteld, kun je de DNS-requests meelezen als gewone tekst – en dat voor zowel de aangevraagde domeinen als de antwoordpakketten met de ip-adressen.

Dat is echter geen reden tot ongerustheid, want als alles goed geconfigureerd is dan duiken daar alleen pakketten op die de Raspberry Pi en de clients binnen het lokale netwerk uitwisselen (met bijvoorbeeld ip-adressen in de vorm van 192.168.x.y). Die leesbare pakketten halen het internet niet meer.

Dat zie je als je het DNS-over-TLS-verkeer van de Raspberry Pi laat weergeven:

sudo tcpdump -A -i eth0 tcp and port 853

In plaats van leesbare tekst zie je nu alleen nog maar cryptische datapakketten die aan de ingestelde DoT-server gericht zijn. De versleutelde pakketten geven geen uitsluitsel over de opgevraagde domeinen –het DNS-datalek is daarmee succesvol gedicht.

Performance

Stubby is nu wel het tweede tussen station waar de DNS-requests langs moeten op hun weg naar het doel. Dat betekent automatisch dus wel dat de pakketten wat langer onderweg zijn. Bovendien wordt in plaats van het onbeveiligde UDP nu het door TLS beveiligde TCP gebruikt. Dat betekent natuurlijk ook nog extra overhead.

We hebben de snelheid gemeten met de benchmarktool DNSBench om te achterhalen hoe groot de extra latentie is die je krijgt door DNS over TLS. We hebben eerst gemeten hoe lang Pi-hole nodig heeft voor requests naar de snelle DNS-service van Cloudflare (1.1.1.1).

DNS-requests voor domeinen die zich niet in de cache bevinden, duurden gemiddeld 97 milliseconden. Met DNS over TLS steeg de latentie naar 160 milliseconden – een toename van 60 procent. Dat lijkt heel veel, maar bij het testen was er van dat verschil weinig te merken.

Pi-hole haalt veel requests bovendien uit zijn cache, wat aanzienlijk sneller gaat. Een herhaald request naar het ip-adres van ct.nl leidt dan ook alleen de eerste keer naar de DNS-server op internet.

(Ronald Eikenberg, Noud van Kruysbergen)

Meer workshops voor de Raspberry Pi in: Het Ultieme Raspberry Pi Handboek 2019

Deel dit artikel

Alieke van Sommeren
Alieke van SommerenTypen geleerd op een 8086 met DOS 5.0 en al vroeg zelf aan het pc-(ver)bouwen geslagen. Speelt graag pc-games, houdt van gadgets en klikt ook wat rond op een MacBook.

Lees ook

Let’s Encrypt gratis SSL-certificaat voor IIS instellen

Microsoft biedt met Internet Information Services de enige grote niet-opensource webserver. Het heeft even geduurd voordat de certificaten van Let's E...

Digitale vrije meningsuiting per Raspberry Pi

Er kleven risico's aan vrije meningsuiting. Het kan zelfs gevaarlijk zijn. Moderne dissidenten verspreiden hun pamfletten digitaal via internet, maar ...

9 Praat mee
avatar
  Abonneer  
nieuwsteoudste
Laat het mij weten wanneer er
Andreotti
Lezer
Andreotti

Bij mij is het niet gelukt. De opdracht “/bin/ldconfig” bestaat niet. Daarvoor ging het allemaal goed.

sudo nano /usr/local/etc/stubby/ stubby.yml moet dat niet zijn:
sudo nano /usr/local/etc/stubby/stubby.yml

Andreotti
Lezer
Andreotti

Het commando word niet herkend.
Kan zijn omdat ik raspbian stretch lite gebruik?

Ben
Lezer
Ben

sudo /bin/ldconfig werkt inderdaad niet. Maar als je ‘which ldconfig’ doet, zie je dat het in de sbin directory staat. Het commando moet dus zijn: ‘sudo /sbin/ldconfig’. Althans op de meest recente versie van Raspbian.

Andreotti
Lezer
Andreotti

Slordig hoor!

Gunkelaar
Lezer
Gunkelaar

Dedankt voor dit leuke artikel. Kan dit ook werken met IPv6?

Noud van Kruysbergen
Admin
Noud van Kruysbergen
Gunkelaar
Lezer
Gunkelaar

Bedankt voor de reactie, het is gelukt. Nu probeer ik de Pihole als DHCP server in te stellen ipv mijn Fritzbox 7581. Vorige keer ging dat niet goed met mijn IPTV kastjes.