Vor einiger Zeit habe ich bei mir Zuhause ein Pi-hole auf einem Raspberry installiert, um unerwünschte Werbung zu filtern. Dieser funktioniert nach einigen Startschwierigkeiten (selbstgemachte Firewall Probleme) sehr gut. Damit wird nun sämtlicher Netzwerkverkehr in meinem Netzwerk gefiltert, was auch z.B. Fernseher oder Smartphones, Tablets usw. betrifft.
Gerade Geräte wie Smartphones, bei denen häufig In-App Werbung eingeblendet wird, profitieren von der Filterung der DNS-Anfragen direkt beim DNS-Server. Es wird nicht nur Werbung gefiltert, sonder z.B. auch Tracker von Samsung TV, Google Analytics oder Sonos (was nicht deaktiviert werden kann).

Mehr über das Pi-hole und eine Anleitung zur Installation findest du hier:

Neulich wurde ein neuer DNS-Dienst Quad9 in Betrieb genommen. Quad9 unterscheidet sich von ähnlichen Diensten wie Google Public DNS durch die Fokussierung auf Benutzerfreundlichkeit, Skalierbarkeit, Sicherheit und Datenschutz. Ein interessantes und scheinbar undokumentiertes Feature ist, dass der Dienst DNS-over-TLS anbietet. Dadurch wird die Kommunikation zwischen dem Client und dem DNS-Server mit TLS verschlüsselt und die Privatsphäre (bis und mit DNS-Server) geschützt. Bisher verspricht Quad9 keine personenbezogene Daten zu sammeln.

Ich möchte nun das Pi-Hole so einrichten, damit DNS Queries an Quad9 gehen und mit TLS verschlüsselt übertragen werden.

Stubby

Dafür benötigen wir einen DNS-Client der DNS-over-TLS fähig ist. Der wohl fortschrittlichste (experimentelle) Client ist momentan Stubby von getdns.

Update: Es gibt stubby nun in den Paketquellen von Debian Buster. Mein Raspberry Pi läuft momentan mit Debian Stretch, daher kompiliere ich den Client von der Source.

Build

Auf dem Raspberry Pi:

# Dependencies installieren für Build und Run
sudo apt-get install build-essential libssl-dev libtool m4 autoconf automake libyaml-dev libev4 libuv1

Nun das Git-Repo auschecken und die Git-Submodules aktualisieren

git clone https://github.com/getdnsapi/getdns.git
cd getdns
sed -i 's#git://#https://#g' .gitmodules # fix for git checkout
git submodule update --init
libtoolize -ci
autoreconf -fi
mkdir -v build && cd build
../configure --prefix=/usr/local --without-libidn --without-libidn2 --enable-stub-only --with-stubby

Zeit für ein Kaffee:

make && sudo make install
Konfiguration

Soweit ist Stubby kompiliert und installiert. Nun erstellen wir noch die Stubby Konfiguration und integrieren diesen in Systemd, damit er zuverlässig verwaltet werden kann:

cd ../stubby
sudo useradd stubby
sudo /usr/bin/install -Dm644 stubby.yml.example /etc/stubby.yml

Achtung! Per default ist der Strict-Mode aktiv, daher kein Fallback auf tcp oder udp dns.

Die Transportoptionen im Strict-Mode beschränkt die Kommunikation auf TLS und zusätzlich wird eine Authentifizierung des Upstream DNS gefordert.

dns_transport_list:
  - GETDNS_TRANSPORT_TLS
#  - GETDNS_TRANSPORT_TCP   # disabled, cleartext queries
#  - GETDNS_TRANSPORT_UDP   # disabled, cleartext queries

# For Strict use        GETDNS_AUTHENTICATION_REQUIRED
# For Opportunistic use GETDNS_AUTHENTICATION_NONE
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED

Wir editieren die Stubby Konfiguration und tragen unter listen_addresses auf welche Adresse und Port der Client hören soll. Da der Client vom Pi-hole genutzt wird, muss Stubby nur lokal erreichbar sein. Zusätzlich benötigen wir einen anderen Port, da das Pi-hole ja selbst einen DNS-Dienst auf dem Standardport 53 betreibt.
Ich habe 127.0.2.2 als lokale IP verwendet um im Log und der Graphen von Pi-Hole unterscheiden zu können, wohin die Abfragen eventuell weitergeleitet werden. Somit ist klar, dass diese an Stubby gestellt werden.

# sudo vi /etc/stubby.yml
listen_addresses:
  - 127.0.2.2@5353
  - 0::2@5353

Als Upstream Servers (an welche die DNS-Abfragen weitergeleitet werden), habe ich nun ein bisschen weiter unten Quad9 eingetragen. Das kann natürlich ein beliebiger DNS-Dienst sein, der TLS unterstützt. Zusätzlich verifiziere ich die Authenizität des Servers über den tls_auth_name damit sich nicht jemand anderes als dns.quad9.netausgeben kann.

upstream_recursive_servers:
  - address_data: 9.9.9.9
    tls_auth_name: "dns.quad9.net"
  - address_data: 2620:fe::fe
    tls_auth_name: "dns.quad9.net"

Alternativ könnte die Authentifizierung mit Public-Key-Pinning (SPKI) für TLS verwendet werden (RFC7858) (tls_pubkey_pinset), was aber eine manuelle anpassung der Konfiguration bedingt, wenn das Zertifikat erneuert wird. Die pubkey digest value kann selbst abgefragt werden (funktioniert für jeden TLS-DNS-Server):

echo | openssl s_client -connect '9.9.9.9:853' 2>/dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64

Und da haben wir die Antwort für Quad9: MujBQ+U0p2eZLTnQ2KGEqs+fPLYV/1DnpZDjBDPwUqQ=

Das Quad9 Zertifikat ist von Let's Encrypt, daher ist zu vermuten, dass nach dem erneuern des Zertifikats sich der Digest ändert und die Authentifizierung nicht mehr funktioniert. Es empfiehlt sich daher nur tls_auth_name zu verwenden.

Hier ist mein finales Stubby-Konfigfile /etc/stubby.yml:

resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
  - GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 256
edns_client_subnet_private: 1
idle_timeout: 10000
round_robin_upstreams: 0

listen_addresses:
  - 127.0.2.2@5353
  - 0::2@5353
upstream_recursive_servers:
  - address_data: 9.9.9.9
    tls_auth_name: "dns.quad9.net"

Installation des Systemd-Services

sudo vi /lib/systemd/system/stubby.service 

[Unit]
Description=stubby DNS resolver
Wants=network-online.target
After=network-online.target

[Service]
ExecStart=/usr/local/bin/stubby -C /etc/stubby.yml
Restart=on-abort
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
User=stubby

[Install]
WantedBy=multi-user.target

Als letzter Schritt für den TLS-DNS-Client Teil starten und testen wir nun Stubby:

sudo systemctl daemon-reload
sudo systemctl enable stubby
sudo systemctl start stubby
pi@raspberrypi:~/ $ dig @127.0.2.2 -p 5353 quad9.net

; <<>> DiG 9.10.3-P4-Raspbian <<>> @127.0.2.2 -p 5353 quad9.net
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12094
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; CLIENT-SUBNET: 9.9.0.0/20/0
;; QUESTION SECTION:
;quad9.net.         IN  A

;; ANSWER SECTION:
quad9.net.      120 IN  A   216.21.3.77

;; Query time: 142 msec
;; SERVER: 127.0.2.2#5353(127.0.2.2)
;; WHEN: Sun Jan 14 11:49:22 UTC 2018
;; MSG SIZE  rcvd: 74

Hooray!

Pi-hole mit Stubby

Damit Pi-hole nun unseren lokalen DNS-Resolver Stubby verwendet, konfigurieren wir die Forwarding DNS Server vom Pi-hole um.

Das Pi-hole Webgui lässt keine DNS-Server mit Port konfigurieren, daher muss dies manuell angepasst werden

Dazu erstelle ich eine neues Konfigfile /etc/dnsmasq.d/02-stubby.conf und trage die Stubby-Adressen als Upstream ein:

server=127.0.2.2#5353

Die Anpassung am Pi-hole, damit die Server nicht doppelt oder falsch konfiguriert sind:

  • server= aus dem /etc/dnsmasq.d/01-pihole.conf löschen.
  • PIHOLE_DNS_1 aus /etc/pihole/setupVars.conf löschen.

Und als letztes den Pi-hole DNS-Dienst neu starten:

sudo systemctl restart dnsmasq

Test

Im Pi-hole log /var/log/pihole.log oder im Webgui sollte nun ersichtlich sein, dass die Anfragen an Stubby forwarded werden:

forwarded maps.googleapis.com to 127.0.2.2
forwarded fedoraproject.org to 127.0.2.2

Mit tcpdump habe ich auf dem Router die gesendeten und empfangenen Pakete mitgeschnitten und in Wireshark ausgewertet.
Wie zu erwarten ist der DNS Verkehr jetzt verschlüsselt:

Wireshark Segment

Next Post Previous Post

Kommentar hinzufügen

Kommentare

Awesome! works great.
geschrieben am Thu, 12 Apr 2018 05:40:27 von jm