Wer sich schon mit der Sicherheit vom DNS Protokoll auseinander gesetzt hat, musste feststellen, dass es ohne weitere Verbesserungen sehr einfach manipuliert, abgehört und zensiert werden kann. Diese Zensuren sind nicht nur Theorie, sondern werden schon von diversen Ländern umgesetzt.
Um diese Themen im DNS Protokoll abzudecken wurden verschiedene Erweiterungen spezifiziert, wie z.b DNSSEC mit DANE/TLSA um man-in-the-middle Angriffe zu erkennen. Die neusten Ansätze in diesem Bereich gehen noch einen Schritt weiter und verschlüsseln gleich den DNS ganzen Verkehr.

DNSCrypt und DNS-over-TLS sind 2 Implementierungen, welche den doch schon länger existierenden und nicht besonders etablierten DNSSEC-Standard ablösen sollten. Zu DNS-over-TLS gibt es mittlerweile einen verabschiedeten Standard im RFC7858, welchen ich hier mit den vorhandenen Mitteln aufsetzen möchte. Das bringt Nutzern den Vorteil, dass auch der Internetserviceprovider (ISP) keine Detailinformationen zu der Anfrage mehr bekommt, sondern lediglich sieht, dass der Nutzer einen bestimmen DNS Server anfragt. Eine vollständige Anonymisierung gibt es aber auch damit nicht.

Was und wer kann DNS-over-TLS

Kurz zusammengefasst, was DNS-over-TLS kann:

  • TLS-verschlüsselte TCP Kommunikation, Default-Port: 853
  • Der gesamte DNS-Traffic könnte verschlüsselt werden
  • Verifizierung der Server Zertifikate via CA

Da der Standard erst im May 2016 von der IETF freigegeben wurde, gibt es dementsprechend noch wenige funktionierende Implementierungen dieses Standards.
Auf DNSPrivacy.org gibt es eine aktuelle Übersicht den Implementationsstati:

(Stand: 29.10.2017)

DNS Server mit DNS-over-TLS Support:

  • Knot
  • Idns
  • Unbound

DNS Resolver (Client) mit DNS-over-TLS Support:

  • knot
  • stubby
  • digit

BIND mit TLS-Proxy

Eine sehr einfache Möglichkeit einen bestehenden DNS-Server dns-over-tls fähig zu machen, ist das nutzen eines TLS-Proxy wie z.B. mit HAProxy. Folgendes Setup habe ich auf meinem DNS-Server, welcher mit CentOS 7 läuft, durchgeführt.

Achtung! Die Clients denken sie sprechen einen dns-over-tls server an und halten dementsprechend die Idle-Verbindungen offen wenn kein EDNS0 Keepalive verwendet wird (RFC7858). Eventuell ist der Server nicht robust genug für lang lebende Verbindungen und daher nicht für den Produktionseinsatz geeignet!

HAProxy

Installation von HAProxy:

# yum -y install haproxy
# systemctl enable haproxy

Folgende Optionen setze ich:

  • BIND-Server hört zusätzlich lokal (127.0.0.2) auf Port 8853.
  • IP 127.0.0.2 auf externem Interface
  • HA-Proxy ist der verschlüsselte Endpunkt welcher gemäss RFC auf 853 hört.
  • Ein SSL Zertifikat von Letsencrypt

HAProxy möchte das TLS-Zertifikat und der Privatekey in einem PEM-File haben.

/etc/haproxy/haproxy.cfg

global
log /dev/log local0
chroot /var/lib/haproxy
user haproxy
group haproxy
maxconn 1024
pidfile /var/run/haproxy.pid
tune.ssl.default-dh-param 2048
ssl-default-bind-ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-options force-tlsv12

defaults
balance roundrobin
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout check 10s

listen dns
bind 0.0.0.0:853 ssl crt /var/lib/acme/live/certificates/<cert>.pem
mode tcp
server server1 127.0.0.2:8853
Bind

Bei der zusätzlichen BIND Konfiguration muss aufgepasst werden, dass nicht ausversehen der DNS Server rekursive Abfragen erlaubt, da der Client nun localhost ist (127.0.0.2:8853)

Die zusätzliche Lokale IP 127.0.0.2 habe ich (mit scope host) auf dem Interface eth1 konfiguriert. Somit werden nur Anfragen auf dem Host beantwortet, obwohl es ein geroutetes Interface ist. Die IP Adresse auf das Loopback Device zu konfigurieren hat bei mir nicht funktioniert, da im Bind das als 127.0.0.1-Client erkannt wird und daher voller Zugriff auf alle Zonen und rekursive Abfragen hat.

ip addr add 127.0.0.2/8 dev eth1 scope host

Nun füge ich den neuen Listen-Port für Bind hinzu, und markiere die neue IP-Adresse als "not trusted" in meinen bind acl, damit diese nicht auf interne Zonen zugreifen kann.

listen-on port 8853 { 127.0.0.2; };
acl "trusted" {
    127.0.0.1;
    !127.0.0.2;
};

Zum Schluss:

systemctl restart named-chroot
systemctl restart haproxy
Test

Da es noch nicht viele Integrationen gibt, könnte lokal ein DNS-Resolver wie Unbound oder Stubby installiert werden, welche das schon unterstützen. Ich möchte jedoch nur testen, ob Abfragen funktionieren, daher nehme ich für die Tests den DNS-Client Digit. Da dieser unter Fedora nicht in den Paketquellen vorhanden ist, habe ich diesen kurz selbst kompilliert.

sudo dnf install compat-openssl10-devel.x86_64
tar xvfz digit-1.4.3.tar.gz
aclocal && automake --add-missing && autoconf
./configure
make

Nun kann mit digit dns-over-tls getestet werden, indem ein File mit abzufragenden DNS-Querys angegeben wird.
Dazu habe ich meine 2 Domains, blog.sandchaschte.ch und www.sandchaschte.ch verwendet:

$ ./digit -f /tmp/names -r 159.100.252.246 -V
-----DNS Msg: len=367; response; id=19383-----
Que:
www.sandchaschte.ch A   IN
Ans:
www.sandchaschte.ch.    15M IN A    159.100.248.212
...
.           9h6m8s 4096 4096  4096 bytes
-----DNS Msg: len=685; response; id=19384-----
Que:
blog.sandchaschte.ch    A   IN
Ans:
blog.sandchaschte.ch.   15M IN CNAME    sandchaschte.ch.
...
sandchaschte.ch.    15M IN A    159.100.248.212
...

Der Versuch mit dig scheitert, da ja zuerst eine TLS-Verbindung aufgebaut werden muss:

dig +tcp @159.100.252.246 -p 853 www.sandchaschte.ch
;; communications error to 159.100.252.246#853: end of file

Bis die Implementierungen ausgereift sind oder in BIND dns-over-tls nativ unterstütz wird, ist dies eine funktionierende aber nicht die beste Lösung.
But It works!

Next Post Previous Post

Kommentar hinzufügen