OPNsense – DNS Anfragen an eigenen Resolver umleiten

[PROLOG]
Ohne DNS kämen wir Menschen im Internet nicht klar, das wurde an dieser Stelle: https://www.heimnetz.de/anleitungen/theorie/netzwerk/dns/ gut beschrieben. Viele machen sich dennoch kaum Gedanken über die Namensauflösung, doch dahinter verbirgt sich etwas mehr als nur „Eine Webadresse in eine IP umwandeln“.

Neben vielen Sicherheits- und Datenschutzaspekten die es bei der Auswahl des DNS Servers zu beachten gilt, eignet sich DNS auch besonders gut um Werbung oder andere unerwünschte Inhalte von seinen Geräten fern zu halten. Wer also nicht „irgendwelche“ DNS Server verwenden mag, sondern nur ganz bestimmte mit seinem eigenen DNS-Resolver auf z.B. der Firewall oder einem RaspberryPi, hat großes Interesse daran, dass diese nicht einfach umgangen werden. Leider kommt dies in der Praxis ständig vor, nicht jedoch etwa weil der Sohnemann auf diese Weise die Sperre der Erwachsenenseiten aktiv umgehen will, sondern vielmehr weil manche Geräte oder dessen Programme schlichtweg die DNS-Server verwenden die vom Entwickler vorgegeben sind.

Im Folgenden beschreibe ich wie man die OPNsense so einrichtet, dass stets der gewünschte bzw. die gewünschten DNS-Server verwendet werden. Doch direkt vorab: Aufgrund „neuerer“ DNS-Varianten wie DoH und DoT (später mehr dazu) ist dies leider nicht immer zu 100% möglich.


[VORAUSSETZUNGEN]
Es wird vorausgesetzt, dass der eigene DNS-Resolver eingerichtet und funktionsfähig ist. Auf der OPNsense bietet sich hier zumeist unbound und/oder AdGuardHome (Anleitung AdGuard folgt) oder PiHole auf einem RaspberryPi an. Davon benötigen wir die IP Adresse(n) (IPv4 und ggf. IPv6) sowie die Ports, auf denen der Resolver lauscht (meist Port 53). Sollte ein eigener Resolver nicht gewünscht sein, kann man im Folgenden auch direkt einen öffentlichen DNS Server verwenden.

[EINRICHTUNG FÜR IPv4]
Normales DNS - Port 53
Wir beginnen mit der Einrichtung für IPv4 auf der OPNsense unter Firewall / NAT / Port Foward und erstellen eine neue Regel durch Klick auf das Plus-Symbol. Hier werden folgende Einstellungen getätigt:
Portweiterleitung IPv4 erstellen (1/2)
Bei „Destination“ muss die IP des Resolvers (oder öffentlichen DNS Servers) eingegeben werden. In meinem Fall ist es die OPNsense selbst. Der Port bei „Destination“ ist in jedem Fall 53, unabhängig davon auf welchem Port der Resolver lauscht.
Portweiterleitung IPv4 erstellen (2/2)
Bei „Redirect target IP“ wird ebenfalls die IP des Resolvers (oder öffentlichen DNS-Servers) angegeben, der „Redirect target port“ ist der Port auf dem der Resolver lauscht. Dann wird nur noch eine Beschreibung hinzugefügt. Zu Testzwecken sollte zunächst noch das Logging aktiviert werden. Anschließend wird die Regel gespeichert und die Änderungen anschließend übernommen.

Diese Regel sorgt dafür, dass alle IPv4-DNS Anfragen (normales DNS auf Port 53) die nicht an den gewünschten Resolver gehen an eben diesen umgeleitet werden, sodass dieser die Namensauflösung durchführt. Sollte man mehrere Netze (z.B. Gäste WLAN oder VPN) betreiben, für die diese Regel ebenfalls gelten soll, kann man bei „Interface“ die entsprechenden Netze wählen. In der Praxis mache ich dies aber für jedes Interface separat.

Leider ist das „normale“ DNS auf Port 53 längst nicht mehr der einzige Standard der heutigen Zeit, daneben existieren existieren noch die häufig verwendeten Protokolle DoT (DNS over TLS) und DoH (DNS over HTTPS) sowie das derzeit noch sehr rar verwendete DoQ (DNS over QUIC). Da diese Protokolle nicht auf dem Port 53 arbeiten, würden Geräte die diese Protokolle verwenden einfach an unserem Resolver vorbeisprechen und diesen übergehen. Leider ist es bei diesen Protokollen nicht möglich einfach eine entsprechende Regel zu erstellen, die dies an unseren Resolver umleitet, denn ein wesentliches Merkmal dieser Protokolle ist, dass nur Antworten von dem Server akzeptiert werden, der auch angefragt wurde.

Kurzum: Wer nicht möchte, dass man damit die gewünschten DNS Resolver umgehen kann, muss derartige Anfragen blockieren.

DNS over TLS - Port 853
Um DoT zu blockieren, muss eine Firewallregel erstellt werden. Sollte die Regel auf mehrere Interfaces angewendet werden, empfiehlt sich der Einsatz von Floating Rules. Die Regel sollte wie folgt aussehen:
DoT Anfragen abweisen
Bei „Action“ verwende ich hier „Reject“, ein „Block“ wäre genau so gut möglich, allerdings ist ein „Reject“ für die heimischen, vertrauenswürdigen Geräte angemessener. Da diese Regel für IPv4 und IPv6 gleichzeitig verwendet werden kann, wähle ich hier auch direkt beide Versionen, das geht aber nur, wenn der eigene Resolver auf der OPNsense selbst läuft, andernfalls muss für v4 und v6 je eine separate Regel erstellt werden. Bei „Source“ habe ich „This Firewall“ drin, hier gehört ansonsten die IP des Resolvers rein. „This Firewall“ deckt in meinem Fall allerdings sowohl v4 als auch v6 ab. Ähnlich verhält es sich bei „Destination“, auch mit dieser Einstellung wird wieder v4 und v6 gleichzeitig abgedeckt; man könnte auch die IP des Resolvers angeben, allerdings ist man mit „LAN address“ gut bedient finde ich. Der Port ist 853, außerdem wollen wir dass die Ereignisse geloggt werden. Dazu gibt es noch eine Beschreibung und dann wird gespeichert. Die Regel sorgt also dafür, dass alle DoT Anfragen, die nicht an ein Gerät im LAN gestellt werden, blockiert werden.

DNS over QUIC - Port 853
Zugegeben habe ich die Sperrung von DoQ bei mir noch nicht vorgenommen, denn das Protokoll wurde kürzlich (05/2022) erst standardisiert und wird derzeit nur experimentell verwendet. Für die Umsetzung ist jedoch nicht viel erforderlich, da der Standardport ebenfalls 853 ist, wie bei DoT. DoQ nutzt dabei allerdings UDP statt TCP, sodass die gerade erstellte DoT Regel lediglich angepasst werden muss: Bei „Protokoll“ wird nun TCP/UDP angegeben und das war es dann auch schon. Alternativ kann man die Regel natürlich neu erstellen und nur UDP angeben.

DNS over HTTPS - Port 443
Hier wird es kompliziert, denn der Port 443 wird für nahezu jeden Aufbau von Webseiten verwendet, sodass wir diesen nicht einfach sperren können. Das macht unser Vorhaben nicht nur komplizierter, sondern sorgt auch dafür, dass ganz schnell mal was an unserem eigenen Resolver vorbeischlüpft. Ziel ist es nun, alle Anfragen auf Port 443 zu blockieren, die an öffentliche DNS-Server gerichtet sind. Dazu bedienen wir uns öffentlich zugänglichen Listen, die die IP Adressen von DNS-Servern enthalten, die wir sperren wollen. Befindet sich ein DNS-Server jedoch nicht in dieser Liste, kann ein Gerät leider die Namensauflösung darüber abwickeln lassen und unseren Resolver übergehen. Diese Maßnahme bietet also keine absolute Sicherheit, aber ist besser als nichts.

Zunächst erstellen wir einen neuen Alias unter Firewall / Aliases und machen folgende Einstellungen:
Alias für DNS-Server-Listen erstellen
Der Link https://public-dns.info/nameservers-all.txt führt zu einer Liste mit einigen Tausend öffentlichen DNS Servern, deren IPs später gesperrt werden. Die Einstellungen werden gespeichert, anschließend wird genauso mit weiteren Listen verfahren, z.B. mit https://raw.githubusercontent.com/neargle/public-dns-list/master/all.txt. Anschließend fassen wir all diese Listen in einem Alias zusammen indem wir einen weiteren Alias wie folgt erstellen und alle gewünschten Aliase wählen:
Mehrere Aliase in einem Alias zusammenfassen
Nach dem Speichern müssen die Einstellungen nochmal unten links in der Übersicht übernommen werden, dann geht es weiter bei den Firewallregeln. Hier wird eine neue Regel erstellt:
DoH Anfragen abweisen
Hier gilt bis auf für „Destination“ das Gleiche, das ich bereits bei DoT beschrieben habe. Nach dem Speichern der Regel müssen die soeben erstellten Regeln noch angeordnet werden, sodass diese über der „Default allow“ Regel stehen, danach werden die Ändeurngen übernommen.
Übersicht Firewallregeln
Damit wäre die Einrichtung für IPv4 und in Teilen für IPv6 abgeschlossen.

[EINRICHTUNG FÜR IPv6]
Normales DNS - Port 53
Für IPv6 ist die Einrichtung nahzu identisch zu der von v4, allerdings benötigen wir eine ULA-Adresse auf dem Gerät, das der Resolver ist. Ist das die OPNsense prüfen wir zunächst für das LAN Interface unter Interfaces / Overview ob eine IPv6 Adresse zugewiesen wurde, die mit „fd00“ beginnt. Ist dies der Fall wird diese Adresse notiert und es geht zur Einrichtung der Portweiterleitung, andernfalls legen wir gleich eine virtuelle IP unter Interfaces / Virtual IPs an.

Ist der Resolver ein anderes Gerät, muss dem Gerät eine ULA zugewiesen werden, was leider zu gerätespezifisch ist um es hier allgemeingültig beschreiben zu können. Diese ULA wird insbesondere bei wechselnden IPv6 Prefixes benötigt um die OPNsense mit einer statischen Adresse aus dem LAN erreichen zu können… eine Krücke die wir leider anwenden müssen, da unsere deutschen Provider kaum statische Präfixes vergeben.

Bei Interfaces / Virtual IPs klicken wir auf das Plus-Symbol und machen folgende Angaben, wobei „Address“ natürlich frei gewählt werden kann, Hauptsache die Adresse ist nicht schon anderweitig vergeben.
ULA als virtuelle IP anlegen
Sind mehrere Interfaces vorhanden, würde grundsätzlich eine virtuelle IP auf dem LAN ausreichen, allerdings müsste der Zugriff dann mit entsprechenden Regeln eingeschränkt werden, andernfalls muss für jedes Interface eine eigene virtuelle IP angelegt und später bei der Weiterleitung verwendet werden, beides würde hier aber den Rahmen sprengen.

Egal ob Resolver auf der Sense oder einem anderen Gerät, nun geht es weiter bei Firewall / NAT / Port Forward. Hier klonen wir einfach die Regel von IPv4 und passen diese wie folgt an:
Portweiterleitung IPv6 erstellen
Dann speichern wir das Ganze und übernehmen die Einstellungen anschließend. Zum Abschluss muss die dadurch erstellte Firewallregel nochmal über die „Default allow v6“ Regel verschoben werden und die Einrichtung ist abgeschlossen.

[EINSCHRÄNKUNGEN]
Die Umleitung von „normalen“ DNS Anfragen auf Port 53 sollten keinerlei Probleme bereiten, die Sperrung der anderen DNS Protokolle kann jedoch durchaus Probleme hervorrufen. Dies ist meiner Erfahrung nach abhängig davon, wie der Client (das Betriebssytem oder die jeweilige App) reagiert. Die meisten Clients fallen unverzüglich auf normales DNS zurück, wenn es über die anderen Protokolle nicht funktioniert (deshalb nimmt man übrigens „Reject“ statt „Block“), manche jedoch tun das nicht, sodass die Anfrage in ein Timeout läuft. In diesen Fällen müsste man prüfen, ob über die Einstellungen etwas verändert werden kann, sodass nur normales DNS verwendet wird. Aus diesem Grund sollte man dies nicht für ein Gäste WLAN einrichten.

Dadurch, dass für DoH nur Server blockiert werden, die auch auf einer der Listen stehen, ist es wie schon angesprochen durchaus möglich, dass ein Client / eine App einen Server verwendet, der dort nicht aufgeführt ist. Dies zu testen und herauszufinden stellt sich besonders bei DoH als sehr mühsam, fast unmöglich dar. Auch ist denkbar, dass andere Ports verwendet werden als hier angegeben wurde, sprich dass nicht standardisierte Ports verwendet werden. Auch dies ausfindig zu machen dürfte sich sehr mühsam gestalten. Ebenso ist denkbar, dass ein Server fälschlicherweise auf der Liste steht, der unter dem Port 443 kein DNS, sondern einen anderen Dienst wie eine Webseite bereitstellt, die somit nicht aufgerufen werden könnte.

Unterm Strich habe ich allerdings noch keine Probleme bemerkt, auch dass sämtliche Werbung durch meine DNS Blocklisten blockiert wird zeigt, dass im Alltagsgebrauch kaum etwas an meinem Resolver vorbeigeht. Selbst wenn es nicht 100% sind, die Masse der Namen wird so aufgelöst wie ich es möchte.

[FUNKTIONSTEST]
Selbstredend muss das Konstrukt zum Abschluss einmal getestet werden. Die Umleitung des normalen DNS testen wir einfach in Windows über die Befehlszeileneingabe mit „nslookup google.de 8.8.8.8“. Damit soll google.de von einem Google DNS Server (8.8.8.8) aufgelöst werden, was unsere Einstellungen nun verhindern sollen.
Portumleitung mit nslookup testen
Ein zeitgleicher Blick in das Firewall-Log zeigt, dass die Anfrage umgeleitet wurde. Im Log unseres Resolvers kann außerdem nachvollzogen werden, dass die Anfrage bei ihm eingegangen ist und von ihm beantwortet wurde.
Portumleitung im Firewall Log überprüfen
Gleichermaßen kann mit dem Test für IPv6 verfahren werden, unter Umständen bekommt man hier allerdings keine Antwort von nslookup ausgewiesen.

Als nächstes testen wir unsere Sperren von DoT und DoH. Dazu nehmen wir einen Internetbrowser und aktivieren hier in den Einstellungen „Sicheres DNS“ (die Bezeichnung kann variieren). Je nach Browser wird hier meist DoH verwendet, der Aufruf einer Seite sollte sich im Firewall Log dann wie folgt darstellen:
DoH Abweisung im Firewall Log überprüfen
Ist dem nicht der Fall ist entweder etwas falsch konfiguriert, oder der verwendete DNS Server (bei den meisten Browser einstellbar) ist nicht in der Blockliste enthalten, wie es heute (06/22) z.B. für den Anbieter NextDNS der Fall ist. Für solche Fälle (sollte ich davon überhaupt zufällig etwas mitbekommen) habe ich einen weiteren Alias angelegt und in dem zusammengeführten Alias eingebunden; hier schreibe ich manuell entsprechende Server rein, den 100% Schutz gibt es hier nunmal nicht.


[EPILOG]
Wir haben es also zumindest geschafft den Großteil der DNS Anfragen so auflösen zu lassen, wie wir es möchten, die Situation ist durch DoH aber alles andere als befriedigend und wir müssen gespannt sein, wie sich das gesamte Thema in der Zukunft weiterentwickelt. Das Thema „DNS umleiten“ wird immer häufiger diskutiert, doch leider fällt das Thema DoH/DoT in diesem Zusammenhang immer noch in den Hintergrund. Ich befürchte es wird noch ein bisschen dauern, bis auch diese Thematik so präsent ist, dass aktiv und in größerem Stil an Lösungen geforscht wird. Hauptaugenmerkt liegt dabei auf den einzusetzenden DNS-Server-Listen, diese müssen so vollständig wie möglich sein, werden es aber niemals zu 100% sein können. Eine Alternative wäre es, „das HTTPS aufzubrechen“ und durch eine Software analysieren zu lassen, um festzustellen ob es sich hierbei um eine DNS Anfrage handelt. Der Aufwand wäre allerdings immens und aus Sicht des Datenschutz auch nicht wirklich akzeptabel. Aber wie schon erwähnt: In der Praxis macht sich das doch ganz gut, zumindest solange man nicht aktiv versucht die Umleitung oder Blockade zu umgehen.

---

Vielen Dank an den User tiermutter für diese Anleitung!

Wenn Du Fragen zu dieser Anleitung hast, dann schau doch einfach mal bei uns im vorbei!