Ich beschreibe euch wie ihr einen eigenen DNS Resolver inklusive DoT und DoH für die Namensauflösung im Internet aufsetzen könnt.
So wurde auch der adminForge Service: dnsforge.de konfiguriert.
Aufbau des Setups:
- dnsdist – DNS Loadbalancer: DNS Port 53, DoT Port 853, DoH Port 443
- Pi-hole – Werbeblocker: 127.0.0.1:53
- PowerDNS Recursor – auflösender Nameserver: 127.0.0.1:5300
Punkt 1: PowerDNS Repositories hinzufügen
Zuerst fügen wir die beiden Repositories von dnsdist und PowerDNS Recursor hinzu: https://repo.powerdns.com/
Beispiel Debian 11:
apt-get update
apt-get install gnupg
curl https://repo.powerdns.com/FD380FBB-pub.asc | apt-key add -
cat <<EOF > /etc/apt/sources.list.d/powerdns.list
deb [arch=amd64] http://repo.powerdns.com/debian bullseye-dnsdist-17 main
deb [arch=amd64] http://repo.powerdns.com/debian bullseye-rec-47 main
EOF
Punkt 2: Pakete installieren
Wir installieren die beiden Pakete.
apt-get update
apt-get install dnsdist pdns-recursor
Punkt 3: Pi-hole installieren
Wir starten mit der Installation des Werbeblockers Pi-hole.
curl -sSL https://install.pi-hole.net | bash
Wenn ihr die eine vollständige Pi-hole Installation haben möchtet, mit Webserver und Webinterface, dann drückt die Installation mit ENTER durch.
Das Pi-hole Admin Interface ist dann unter http://YOUR-IP/admin/ zu erreichen. Ich empfehle eine zusätzliche Absicherung des Webinterfaces!
Punkt 4: dnsdist konfigurieren
Kopiert diesen Text in die Konsole um eine dnsdist Konfiguration zu erstellen.
cat <<EOF > /etc/dnsdist/dnsdist.conf
setLocal('YOUR-IPv4:53')
addLocal('[YOUR-IPv6]:53')
setACL({'0.0.0.0/0', '::/0'})
--addDOHLocal('YOUR-IPv4', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
--addDOHLocal('YOUR-IPv6', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
--addTLSLocal('YOUR-IPv4', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
--addTLSLocal('YOUR-IPv6', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
newServer({address='127.0.0.1:53', pool='recursor', checkInterval='300', checkTimeout='5', maxCheckFailures='3'})
-- Block hosts that exceeded 100 queries in 10 seconds for 30 minutes
function maintenance()
addDynBlocks(exceedQRate(100, 10), "Exceeded query rate", 1800)
end
addAction(AllRule(), PoolAction('recursor'))
EOF
Ersetzt dann eure IPv4 und IPv6 Adressen in den markieten Zeilen.
Für einen öffentlichen Resolver könnt ihr diese Befehle verwenden:
IPV4=$(curl -s 4.ipwho.de/ip); sed -i 's/YOUR-IPv4/'$IPV4'/g' /etc/dnsdist/dnsdist.conf
IPV6=$(curl -s 6.ipwho.de/ip); sed -i 's/YOUR-IPv6/'$IPV6'/g' /etc/dnsdist/dnsdist.conf
Punkt 5: Let’s Encrypt
Für Let’s Encrypt verwende ich gerne acme.sh, ihr könnt aber auch gerne eigene Zertifikate oder andere Let’s Encrypt Scripte verwenden.
apt-get install socat
curl https://get.acme.sh | sh
Einen Ordner für die Zertifikate legen wir in folgender Datei fest, ich empfehle den bereits vorhandenen Ordner /etc/ssl/private.
CERT_HOME="/etc/ssl/private"
Nun holen wir uns ein Zertifikat.
WICHTIG: Eure Domain sollte bereits jetzt einen A-Record mit der IP-Adresse eures Servers haben und auflösen!
Variante 1 (Pi-hole mit Webserver):
/root/.acme.sh/acme.sh --issue -k ec-384 -w /var/www/html -d domain.de --reloadcmd "systemctl restart dnsdist.service"
Variante 2 (Pi-hole ohne Webserver):
/root/.acme.sh/acme.sh --issue -k ec-384 --standalone -d domain.de --reloadcmd "systemctl restart dnsdist.service"
Punkt 6: dnsdist DoT und DoH aktivieren
In der /etc/dnsdist/dnsdist.conf entfernen wir die -- und ersetzen domain.de mit unserer Domain YOUR-DOMAIN.de aus dem Schritt zuvor.
sed -i 's/--add/add/g' /etc/dnsdist/dnsdist.conf
sed -i 's/domain.de/YOUR-DOMAIN.de/g' /etc/dnsdist/dnsdist.conf
Änderungen sollten in etwa so ausschauen:
setLocal('YOUR-IPv4:53')
addLocal('[YOUR-IPv6]:53')
setACL({'0.0.0.0/0', '::/0'})
addDOHLocal('YOUR-IPv4', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
addDOHLocal('YOUR-IPv6', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
addTLSLocal('YOUR-IPv4', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
addTLSLocal('YOUR-IPv6', '/etc/ssl/private/domain.de_ecc/fullchain.cer', '/etc/ssl/private/domain.de_ecc/domain.de.key')
newServer({address='127.0.0.1:53', pool='recursor', checkInterval='300', checkTimeout='5', maxCheckFailures='3'})
-- Block hosts that exceeded 100 queries in 10 seconds for 30 minutes
function maintenance()
addDynBlocks(exceedQRate(100, 10), "Exceeded query rate", 1800)
end
addAction(AllRule(), PoolAction('recursor'))
Punkt 7: Pi-hole anpassen
Wir erweitern die Adlist.
cat <<EOF > /etc/pihole/adlists.list
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
https://s3.amazonaws.com/lists.disconnect.me/simple_malvertising.txt
https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt
https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt
https://justdomains.github.io/blocklists/lists/easylist-justdomains.txt
https://justdomains.github.io/blocklists/lists/easyprivacy-justdomains.txt
https://justdomains.github.io/blocklists/lists/adguarddns-justdomains.txt
https://justdomains.github.io/blocklists/lists/nocoin-justdomains.txt
https://adaway.org/hosts.txt
https://gitlab.com/quidsup/notrack-blocklists/raw/master/notrack-blocklist.txt
https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt
https://dbl.oisd.nl/basic/
https://blocklistproject.github.io/Lists/malware.txt
https://blocklistproject.github.io/Lists/phishing.txt
https://blocklistproject.github.io/Lists/ransomware.txt
https://blocklistproject.github.io/Lists/tracking.txt
EOF
Passen /etc/pihole/setupVars.conf unseren Wünschen an: Lokale IP-Adresse, Loopback Interface, deaktivieren Querry logging, stellen Pihole DNS auf unseren PowerDNS Recursor.
sed -i 's/IPV4_ADDRESS=.*/IPV4_ADDRESS=127.0.0.1/' /etc/pihole/setupVars.conf
sed -i 's/IPV6_ADDRESS=.*/IPV6_ADDRESS=::1/' /etc/pihole/setupVars.conf
sed -i 's/QUERY_LOGGING=.*/QUERY_LOGGING=false/' /etc/pihole/setupVars.conf
sed -i '$ a\DNSSEC=true' /etc/pihole/setupVars.conf
sed -i 's/PIHOLE_DNS_1=.*/PIHOLE_DNS_1=127.0.0.1#5300/' /etc/pihole/setupVars.conf
sed -i '/PIHOLE_DNS_2=.*/d' /etc/pihole/setupVars.conf
Um sicher zu gehen, dass Pi-hole bei einem Update diese Variable nicht löscht, erstellen wir eine neue Datei um das Interface lo zu binden.
cat <<EOF > /etc/dnsmasq.d/02-bind.conf
interface=lo
bind-interfaces
EOF
Punkt 8: PowerDNS Recursor konfigurieren
Jetzt gehen wir das letzte Element der Kette an – dem Recursor von PowerDNS. Das kleine Programm schickt sämtliche DNS-Anfragen direkt an die DNS-Rootserver und behilft sich der vorinstallierten DNS-Rootserver Datei /usr/share/dns/root.hints.
sed -i 's/# dnssec=.*/dnssec=validate/' /etc/powerdns/recursor.conf
sed -i 's/local-address=.*/local-address=127.0.0.1/' /etc/powerdns/recursor.conf
sed -i 's/# local-port=.*/local-port=5300/' /etc/powerdns/recursor.conf
sed -i 's/# query-local-address6=.*/query-local-address6=::/' /etc/powerdns/recursor.conf
Punkt 9: Dienste starten
Nun ist es an der Zeit die Pi-hole Konfiguration zu übernehmen
pihole -r
und die Dienste neu zu starten.
systemctl restart pihole-FTL.service pdns-recursor.service dnsdist.service
WICHTIG: dnsdist zuletzt starten da wir ein checkInterval von 5 Minuten eingestellt haben! Ansonsten ist der downstream Server 127.0.0.1:53 nicht direkt up.
Punkt 10: DNS Auflösung testen
Zu guter Letzt überprüfen wir ob alle Dienste auf den korrekten Ports lauschen.
netstat -ntupl | egrep "dnsdist|pdns|pihole"
Soll:
dnsdist/tcp: 53, 443, 853
dnsdist/udp: 53
pihole/tcp+udp: 127.0.0.1:53, ::1:53
pdns_recursor/tcp+udp: 127.0.0.1:5300
Wenn alles stimmt können wir die ersten Namensauflösungen testen.
DNS:
Das Tool dig ist unter Debian vorinstalliert. Tragt hinter dem @ die öffentliche IP-Adresse des Servers ein.
dig adminforge.de @xxx.xxx.xx.xx
; <<>> DiG 9.11.5-P4-5.1-Debian <<>> adminforge.de @xxx.xxx.xx.xx
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17240
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;adminforge.de. IN A
;; ANSWER SECTION:
adminforge.de. 277 IN A 5.9.68.168
;; Query time: 0 msec
;; SERVER: xxx.xxx.xx.xx#53(xxx.xxx.xx.xx)
;; WHEN: Mon Jan 27 15:32:16 CET 2020
;; MSG SIZE rcvd: 58
DNS over TLS:
Da PHP dank Pi-hole bereits installiert ist, nutzen wir am einfachsten dnstls zum testen. Anstelle domain.de nehmt bitte eure Domain.
wget https://raw.githubusercontent.com/dcid/dns-over-tls-php-client/master/dnstls.php
php dnstls.php adminforge.de domain.de
adminforge.de has address 5.9.68.168
DNS over HTTPS:
Über einen kleinen curl Aufruf kann man prüfen ob DoH funktioniert. Angefragt wird hier example.com (verschlüsselt dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE).
curl -I "https://domain.de/dns-query?ct&dns=q80BAAABAAAAAAAAB2V4YW1wbGUDY29tAAABAAE"
HTTP/2 200
server: h2o/dnsdist
date: Mon, 27 Jan 2020 15:12:00 GMT
content-type: application/dns-message
content-length: 45
Das Betreiben der Dienste, Webseite und Server machen wir gerne, kostet aber leider auch Geld.Unterstütze unsere Arbeit mit einer Spende. |
