Das Log, das Sie besser beschreibt als Ihr Browserverlauf
Bevor Ihr Rechner ein einziges verschlüsseltes Byte an eine Website senden kann, muss er jemanden fragen, wo diese Website lebt. Diese Frage reist im Klartext, zu einem Resolver, den Sie mit ziemlicher Sicherheit nicht selbst gewählt haben, und die Antwort auf die Frage, wer sie aufbewahrt, entscheidet, wie viel von Ihrem Leben aufgeschrieben wird. Ein Browserverlauf ist eine Liste von Seiten, die Sie bewusst behalten haben. Ein Resolver-Log ist alles: jede Site, jede App, die nach Updates sucht, jeder Cloud-Dienst, mit dem Ihr Telefon spricht, während Sie schlafen, jede Domain in jeder E-Mail, die Sie geöffnet haben, in der Reihenfolge, mit Zeitstempeln, ganz gleich, ob ein Mensch auf den Bildschirm geschaut hat oder nicht.
Lesen Sie eine Woche davon, und Sie können einen Menschen rekonstruieren. Die Bank, die er nutzt, die Fluggesellschaft, bei der er gerade gebucht hat, die Apotheke, die Dating-App, das Bewerbermanagementsystem des Recruiters, die Stunde, zu der er aufwacht, und die Stunde, zu der er aufhört. Nichts davon erfordert, irgendeine Verschlüsselung zu brechen. Die Namen allein tragen das alles, und die Namen sind der eine Teil der Transaktion, der in den meisten Konfigurationen noch immer, per Konstruktion, an einen Dritten übergeben wird.
Heute ist dieser Dritte, wer auch immer Ihr DHCP-Lease Ihnen zugewiesen hat — Ihr ISP, Ihr Arbeitgeber, das Café. Wer das bemerkt, wechselt meist zu einem öffentlichen Resolver, was ein echter Fortschritt bei der Integrität und eine seitliche Bewegung bei der Privatsphäre ist: Sie haben den Beobachter nicht entfernt, Sie haben nur geändert, welches Unternehmen es ist, und einen regulierten Telco gegen ein werbenahes CDN oder eine Non-Profit-Organisation getauscht, deren Richtlinie sich mit ihrer Finanzierung ändern könnte. Die guten unter ihnen veröffentlichen ehrliche Aufbewahrungsrichtlinien, und manche halten sich wirklich daran. Aber eine Richtlinie ist ein Versprechen über Verhalten, und eine Konfigurationsdatei ist eine Aussage über Fähigkeiten. Ein Versprechen können Sie nicht auditieren. Zwanzig Zeilen, die Sie selbst geschrieben haben, auf einer Box, die Sie mieten, in einem Land, das Sie gewählt haben, schon.
SP·02Forwarding verschiebt das Log. Rekursion zerstückelt es.
Fast jede Anleitung, die "betreiben Sie Ihren eigenen DNS-Server" verspricht, landet am Ende beim Bau eines Forwarders: ein kleiner Cache in Ihrem Netzwerk, der alles, was er nicht kennt, an 1.1.1.1 oder 9.9.9.9 weitergibt. Das ist eine wirklich nützliche Sache — sie ist schnell, sie ist fünf Zeilen lang, und sie hält Ihr lokales Netzwerk davon ab, Sie zu beobachten. Sie lässt aber das aggregierte Log exakt dort, wo es war. Jeder Name, den Sie nachschlagen, landet weiterhin bei demselben einen Unternehmen, jetzt praktischerweise mit der einzigen IP-Adresse Ihres Resolvers vorbeschriftet, was den Strom leichter zuordenbar macht statt schwerer.
Ein rekursiver Resolver erledigt die Arbeit selbst, statt sie zu delegieren. Bei einer Anfrage nach news.example.io fragt er zunächst einen Root-Server, wer .io betreibt, dann fragt er die .io-Server, wer example.io betreibt, und fragt dann diesen Betreiber direkt. Drei Gespräche mit drei voneinander unabhängigen Parteien, von denen keine im Geschäft der Aggregation ist, und — das ist der Teil, auf den es ankommt — keine einzige von ihnen sieht jemals Ihren vollständigen Abfragestrom. Die Root-Betreiber sehen ein Rinnsal von TLD-Anfragen. Verisign sieht, dass jemand von Ihrer Adresse etwas unter .com berührt hat. Der autoritative Server für eine Domain sieht den Traffic, den er ohnehin gesehen hätte, weil Sie sich sowieso gleich mit ihm verbinden werden.
QNAME-Minimierung schärft das erheblich, und modernes Unbound tut es standardmäßig. Statt jedem Server in der Kette den vollständigen Namen zu senden — was Resolver dreißig Jahre lang getan haben —, sendet es jedem Server nur das Label, das er zum Antworten braucht: io. an die Root, example.io. an die .io-Server, und erst dann den vollständigen Namen news.example.io. an den Betreiber, dem er zusteht. Die Hierarchie hört auf, eine Rundsendung Ihrer Absichten zu sein, und wird das, wozu sie gezeichnet wurde: eine Delegation.
Der Tausch ist real, und es lohnt sich, ihn offen auszusprechen. Eine kalte rekursive Abfrage braucht mehrere Umläufe, wo ein Forwarder mit einem auskommt, sodass der erste Besuch einer unbekannten Domain messbar langsamer ist. Sie erben die Verantwortung für einen Cache, der früher das Problem eines anderen war. Und Sie profitieren nicht mehr von einem gemeinsam genutzten Cache, der von Millionen anderer Menschen warmgehalten wird. Im Gegenzug hört die vollständige, geordnete, zeitgestempelte Aufzeichnung dessen, was Sie nachgeschlagen haben, auf, irgendwo außerhalb Ihrer eigenen Festplatte zu existieren.
SP·03Was das verbirgt, und was es klar nicht tut
Der ehrliche Geltungsbereich ist enger, als das Marketing rund um privates DNS suggeriert, und die Grenzen zu kennen ist es, was Sie davor bewahrt, eine schlechte Entscheidung auf der Kraft eines guten Gefühls zu treffen.
Es entfernt eine Sache: das aggregierte Namens-Log, das ein einzelner Beobachter hält. Das ist eine große Sache, denn das Aggregat ist es, was kommerziellen Wert hat und was in großen Mengen angefragt wird. Es ist nicht alles.
Es verbirgt nicht die Verbindung. Nachdem die Auflösung abgeschlossen ist, öffnet Ihr Gerät weiterhin eine Sitzung zu dieser Adresse, und jeder, der Ihre Uplink-Verbindung beobachtet, sieht die Ziel-IP. Für eine Site auf dedizierter Infrastruktur ist die IP die Identität. Ebenso wenig verbirgt es den Hostnamen auf der Leitung: Sofern nicht beide Enden Encrypted Client Hello unterstützen, trägt der TLS-Handshake den Servernamen weiterhin im Klartext — dieselbe Information, die Ihr Resolver ohnehin gehabt hätte.
Es verbirgt die Abfragen nicht vor Ihrem Hosting-Provider. Das ist der Punkt, bei dem die meisten sich irren, also verdient er es, ohne Beschönigung ausgesprochen zu werden: der Upstream-Traffic Ihres Resolvers — die Fragen, die er an die Root, die TLD und die autoritativen Server stellt — verlässt den VPS auf UDP-Port 53, unverschlüsselt, und das Netzwerk, in dem Ihr Server steht, kann das alles lesen. Es gibt kein DoT zur Root. Sie haben den Beobachter nicht gelöscht, sondern eher verschoben — von einem Endkunden-ISP, der Daten verkauft und in Ihrem eigenen Land Vorladungen beantwortet, zu einem Hosting-Netzwerk in einer Jurisdiktion, die Sie bewusst gewählt haben und die dank QNAME-Minimierung nur einen fragmentierten Strom sieht. Das ist ein echter Fortschritt, und es ist eine Frage darüber, welches Recht auf der Leitung gilt, und keine, die eine Konfigurationsdatei klären kann.
Und es verschafft Ihnen keine Menge. Ein Resolver, den ein einziger Haushalt nutzt, ordnet jede Abfrage darin diesem Haushalt zu, völlig ohne Zweifel. Gegen einen globalen passiven Angreifer ist ein stark frequentierter geteilter Resolver tatsächlich das bessere Versteck. Gegen Ihren ISP, Ihren Arbeitgeber, die Datenhändler, die Resolver-Telemetrie kaufen, und die routinemäßigen Massenanfragen, die gewöhnlichen Menschen tatsächlich widerfahren, ist Ihrer besser — vorausgesetzt, der letzte Hop von Ihren Geräten liegt innerhalb eines Tunnels. Betreiben Sie das mit Ihrem eigenen WireGuard-Tunnel, nicht anstelle davon. Für sich allein verlagert ein privater Resolver vor allem Ihre Metadaten. Hinter einem Tunnel schließt er den einen Kanal, den der Tunnel offen lässt.
SP·04Der Fehler, der Ihren Resolver zur Waffe eines Fremden macht
Es gibt genau eine Art, das gründlich falsch zu machen, sie passiert leicht aus Versehen, und die Folgen treffen Fremde, bevor sie Sie treffen.
Ein Resolver, der jedem antwortet, ist ein offener Resolver, und ein offener Resolver ist ein Verstärker. DNS läuft über UDP, UDP-Absenderadressen lassen sich trivial fälschen, und eine kleine Anfrage kann eine um ein Vielfaches größere Antwort erzeugen. Ein Angreifer sendet Ihrer Box eine 60-Byte-Frage mit der Adresse eines Opfers, gefälscht als Absender; Ihre Box sendet pflichtbewusst eine mehrere Dutzend Mal größere Antwort an das Opfer. Tun Sie das von einigen tausend offenen Resolvern gleichzeitig, und das Opfer ist vom Internet getrennt, weil es eine Flut erhalten hat, die — auf Paketebene korrekt — so aussieht, als käme sie von Ihnen. Sie sind nicht das Ziel. Sie sind die Waffe, und der Traffic im Incident-Report ist Ihrer.
Was folgt, ist wenig glamourös: Abuse-Reports von Netzwerken, von denen Sie nie gehört haben, ein Provider, der Ihre Adresse nullroutet, um sein eigenes Transit zu schützen, und ein Gespräch über Ihren Account, das Sie lieber nicht führen würden. Sie landen auf der verursachenden Seite genau des Vorfalls, der in unserem DDoS-Runbook für die erste Stunde beschrieben wird, und es gibt keine Version dieser Geschichte, in der Ihre Uptime das überlebt.
Zwei unabhängige Schlösser verhindern das, und Sie wollen beide, weil jedes den Ausfall des anderen abdeckt. Das erste ist Unbounds eigene access-control, die für das gesamte Internet auf beiden IP-Familien refuse und dann explizit für Loopback und Ihr Tunnel-Subnetz allow setzen sollte — eine Default-Deny-Liste, keine Allow-Liste mit einem großzügigen Nachsatz. Das zweite ist, wo der Daemon überhaupt lauscht: Binden Sie ihn an 127.0.0.1 und die Tunnel-Adresse, niemals an 0.0.0.0, und halten Sie Port 53 auf dem öffentlichen Interface an der Firewall geschlossen.
Die Falle besteht darin, nur das Erste zu tun. Eine access-control-Regel lässt den Port nicht verschwinden; eine verweigerte Abfrage ist immer noch ein empfangenes und ein gesendetes Paket, Ihre Adresse taucht weiterhin in den Scans auf, die offene Resolver kartieren, und eine spätere Bearbeitung der falschen Stanza macht aus einer Verweigerung eine Antwort. Binding und Firewalling machen den Fehler strukturell unmöglich, statt ihn nur eine Konfigurationszeile entfernt zu halten. Wenn die Box auch Container betreibt, lesen Sie noch einmal nach, wie Docker Ports an Ihrer Firewall vorbei veröffentlicht, bevor Sie davon ausgehen, dass die Regel, die Sie geschrieben haben, die Regel ist, die tatsächlich gilt.
Unbounds Standardeinstellungen sind vernünftig. Privat sind sie nicht.
Unbound wird werkseitig auf Korrektheit und Stabilität getrimmt ausgeliefert, was die richtige Voreinstellung für Software ist, die größtenteils von ISPs betrieben wird. Eine Handvoll Einstellungen verwandelt es in etwas, das für die Person gebaut ist, die es betreibt. Keine davon ist exotisch; sie sind schlicht ab Werk ausgeschaltet oder unentschieden gelassen.
Hören Sie auf, Fragen über sich selbst zu beantworten. Standardmäßig gibt ein Resolver bereitwillig seine Softwareversion und seinen Hostnamen über die CHAOS-Klasse preis — version.bind und hostname.bind —, was für jeden, der entscheidet, ob Ihre Box Aufmerksamkeit lohnt, kostenlose Aufklärung ist. hide-identity und hide-version kosten nichts und entfernen einen Fingerabdruck.
Geschlossen ausfallen, nicht offen. DNSSEC-Validierung ist der Unterschied zwischen einem Resolver, der eine gefälschte Antwort erkennt, und einem, der sie ausliefert. harden-dnssec-stripped verweigert die Annahme einer unsignierten Antwort für eine Zone, die signiert sein sollte, harden-glue und harden-below-nxdomain schließen zwei klassische Cache-Poisoning-Wege, und aggressive-nsec lässt den Resolver nicht existierende Namen direkt aus zwischengespeicherten Denial-Records beantworten, statt erneut zu fragen. use-caps-for-id fügt randomisierte Groß-/Kleinschreibung als zusätzliche Entropie gegen blindes Spoofing hinzu — billig, und gelegentlich inkompatibel mit einem schlecht gebauten autoritativen Server, was gut zu wissen ist, bevor Sie einen Nachmittag mit einer Domain verbringen, die sich nicht auflösen lässt.
Schreiben Sie nichts auf. Unbound protokolliert Abfragen nur, wenn man es dazu anweist, aber die Einstellungen, die das täten, sind nur eine unkommentierte Zeile entfernt, und manche Distributionspakete liefern eine geschwätzigere Voreinstellung aus. Setzen Sie verbosity: 0 und geben Sie log-queries: no explizit an, damit die Absicht in der Datei sichtbar ist, statt aus ihrer Abwesenheit erschlossen zu werden. Denken Sie dann an den Teil, der keine Einstellung ist: der Cache selbst ist eine Aufzeichnung. unbound-control dump_cache gibt auf einer laufenden Box eine jüngste Historie dessen aus, was diese Box nachgeschlagen hat, und das lebt im Arbeitsspeicher einer Maschine, die fremde Hände erreichen können. Es verfällt von selbst, was der ganze Grund ist, warum kurze Cache-Lebensdauern und Privatsphäre in leichter Spannung stehen, und es ist der Grund, keinen Resolver monatelang auf einem Host laufen zu lassen, dem Sie nicht vollständig vertrauen.
Cachen Sie bewusst. Jede aus dem Cache bediente Antwort ist eine Beobachtung, die upstream niemals stattfindet, also ist ein gesunder Cache ein Privacy-Feature und nicht nur ein Geschwindigkeits-Feature. prefetch erneuert populäre Records, bevor sie ablaufen, sodass der Normalfall das Netzwerk überhaupt nicht mehr berührt; serve-expired hält Sie online, wenn ein autoritativer Server kurz nicht erreichbar ist. Ein höheres cache-min-ttl reduziert das Upstream-Geschwätz weiter, überschreibt aber bewusste Entscheidungen der Domain-Betreiber — niedrige TTLs sind, wie CDNs und Failover funktionieren —, also ist eine Untergrenze von ein bis zwei Minuten sinnvoll, während eine Stunde Sie irgendwann auf einer toten Adresse stranden lässt.
Zwei Wege hinein: der Tunnel, oder DNS-over-TLS
Ihre Geräte müssen den Resolver irgendwie erreichen, und die Wahl zwischen den beiden vernünftigen Optionen ist vor allem eine Frage dessen, was Sie zu veröffentlichen bereit sind.
Der Tunnel ist für fast jeden die bessere Antwort. Wenn Ihr Laptop und Ihr Telefon bereits eine WireGuard-Sitzung zu diesem Server halten, kann der Resolver auf der Tunnel-Adresse lauschen und gewöhnliches DNS auf Port 53 sprechen. Der Traffic ist bereits verschlüsselt und bereits durch den Tunnel authentifiziert, also gibt es kein Zertifikat zu beschaffen, keinen neuen Port, der zum Internet offen steht, keinen TLS-Stack, der Fremden ausgesetzt ist, und — der unterschätzte Teil — nirgendwo einen Hostnamen. Der WireGuard-Guide auf dieser Site lässt Clients auf DNS = 9.9.9.9 zeigen, genau weil es bislang nichts Besseres gab, das man dort eintragen konnte. Das ist es, was statt dessen in diese Zeile kommt: die Tunnel-Adresse Ihres eigenen Servers.
DNS-over-TLS ist für das Gerät, das keinen Tunnel halten kann. Androids Feld für privates DNS ist das stärkste Argument dafür — es gilt systemweit, überlebt Neustarts und erfasst Apps, die Sie sonst nicht erreichen können. Der Preis ist ein Hostname mit einem gültigen Zertifikat, und ein Zertifikat bedeutet einen öffentlichen, dauerhaften Eintrag in den Certificate-Transparency-Logs, der diesen Namen an den Moment bindet, in dem Sie ihn erstellt haben. Passives DNS wird den Namen dann an die Adresse des Servers binden. Wenn der Sinn der Übung war, Ihren Namen von der Infrastruktur fernzuhalten, verwenden Sie einen Hostnamen, der nirgendwo in Ihre Nähe führt, und registrieren Sie ihn mit der Sorgfalt, die in Eine Domain anonym registrieren beschrieben wird — keine Subdomain der Domain, die Sie für alles andere verwenden, denn das verknüpft beide dauerhaft.
Es gibt einen zweiten, subtileren Preis. Ein DoT-Endpunkt, den roamende Telefone erreichen können, lässt sich nicht nach Quelladresse einschränken, ist also per Definition ein Resolver, den Fremde benutzen können, sobald sie den Namen kennen. Er ist kein Verstärker — TLS über TCP erfordert einen abgeschlossenen Handshake, sodass sich die Quelle nicht fälschen lässt und es nichts zu reflektieren gibt —, aber es ist Kapazität, die Sie verschenken, und ein Dienst, der es wert ist, danach zu scannen. Lassen Sie die Rate Limits pro IP aktiv, wählen Sie einen Hostnamen, den niemand erraten wird, und behandeln Sie es als bewusste Ausnahme für ein oder zwei Geräte, statt als Standardtür.
DNS-over-HTTPS ist eine dritte Option und hier meist die falsche. Es braucht einen Webserver vor dem Resolver, was mehr bewegliche Teile und eine größere Angriffsfläche für den einen Vorteil bedeutet, von Web-Traffic nicht zu unterscheiden zu sein. Dieser Vorteil ist entscheidend, wenn Sie ein Netzwerk umgehen, das DoT blockiert, und irrelevant, wenn nicht.
SP·07Blocking ist ein anderes Produkt; entscheiden Sie, bevor Sie es andocken
Früher oder später schlägt jemand vor, Blocklisten hinzuzufügen, und das Angebot ist wirklich attraktiv: Filtern am Resolver deckt jedes Gerät am Tunnel ab, einschließlich des Smart-TVs und der Handy-Apps, die keine Erweiterung erreicht. Besonders auf Mobilgeräten ist es die einzige praktikable Stelle zum Eingreifen. Es ist zugleich das Feature, das am ehesten dazu führt, dass Sie Ihrer eigenen Infrastruktur leise misstrauen, und es lohnt sich, das Warum zu verstehen, bevor es passiert, statt währenddessen.
Der erste Preis ist, dass Fehler nicht wie Fehler aussehen. Ein kaputter Resolver kündigt sich an; eine blockierte Domain präsentiert sich als Checkout-Button, der nichts tut, eine App, die in einem Spinner hängen bleibt, eine E-Mail, die nie ankommt. Das Symptom taucht Wochen nach der Installation der Liste auf, auf einem Gerät, an das Sie nicht gedacht haben, und nichts verbindet es mit einer DNS-Entscheidung, die Sie einen anderen Monat getroffen haben. Jede Blockliste, die Sie installieren, ist eine von einem Fremden geschriebene Richtlinie, die still auf Ihrem Haushalt durchgesetzt wird. Wenn Sie eine hinzufügen, schreiben Sie auf, dass Sie es getan haben, halten Sie sie klein und seriös, und behalten Sie einen Ein-Befehl-Weg, sie abzuschalten — der erste Debugging-Schritt für alles Unerklärliche in Ihrem Netzwerk wird zu "Filter umgehen und erneut versuchen", und dieser Schritt muss billig sein.
Der zweite Preis ist, dass es nicht tut, was man sich davon erhofft. Eine Anwendung mit einer hartcodierten Resolver-Adresse, oder einem eigenen eingebauten DoH-Client, fragt Ihren Resolver nie irgendetwas; sie öffnet eine Verbindung zu einer hartcodierten IP und ist verschwunden. Browser lösen zunehmend über ihr eigenes DoH auf, sofern man ihnen nichts anderes sagt. DNS-Blocking ist eine Hygiene-Schicht, die viel mühelos anfallendes Tracking- und Werbe-Rauschen entfernt, und es ist keine Sicherheitskontrolle, denn alles Feindliche umgeht es per Konstruktion.
Wenn Sie es trotzdem wollen, bevorzugen Sie eine kleine lokale Zone in Unbound gegenüber einem zweiten Daemon — local-zone: "tracker.example." always_nxdomain braucht keine zusätzliche Software, kein Web-UI auf einem Port, den Sie dann verteidigen müssen, und keinen neuen Dienst, der abstürzen und Ihre Namensauflösung mit sich reißen kann. Beschränken Sie die Jobbeschreibung der Maschine auf eine Zeile: Sie löst Namen auf. Jede zusätzliche Verantwortung, die Sie ihr geben, ist ein weiterer Weg, wie alles gleichzeitig aufhören kann zu funktionieren.
Ein Resolver, den Sie betreiben, ist eine Abhängigkeit, die Ihnen gehört
Wenn eine Website, die Sie hosten, ausfällt, können manche Leute etwas nicht lesen. Wenn Ihr Resolver ausfällt, funktioniert nichts — nicht der Browser, nicht E-Mail, nicht der Paketmanager, nicht die App, die Ihnen eigentlich sagen sollte, dass der Server down ist. Es ist der am stärksten tragende Dienst, den Sie auf eine billige Box stellen können, und er versagt auf Arten, die nicht nach DNS aussehen.
Es lohnt sich, die realistischen Ausfallmuster vorab zu kennen, denn jedes hat eine andere Signatur. Der VPS startet neu, und Unbound wurde nie für den Boot aktiviert, also funktioniert alles, bis zum ersten ungeplanten Neustart. Eine große Blockliste drängt den Cache auf einer 1-GB-Instanz ins Swap, und der OOM-Killer wählt den Resolver aus. Irgendeine Zone bricht ihre eigenen DNSSEC-Signaturen, und Ihr korrekt konfigurierter Resolver verweigert die Antwort, während alle mit einem nicht validierenden Resolver weiter browsen — Ihre Box hat recht, und die Site sieht für Sie trotzdem kaputt aus, was fünf verwirrende Minuten sind, falls Sie vergessen haben, dass Sie validieren. Oder der Tunnel fällt weg, und weil DNS = 10.66.0.1 nur innerhalb des Tunnels existiert, hat das Gerät überhaupt keinen Resolver und meldet, dass es offline ist.
Die Abhilfen sind zum Glück billig. Aktivieren Sie den Dienst beim Boot und testen Sie es tatsächlich mit einem Neustart, statt es nur anzunehmen. Geben Sie Clients einen sekundären Resolver, sodass ein toter Tunnel sich verschlechtert statt zu stoppen — ein öffentlicher Resolver an dieser Stelle ist ein kleiner, expliziter Privacy-Kompromiss, der nur gilt, während Ihr eigener nicht erreichbar ist, und meist ist es der richtige Tausch. Lassen Sie serve-expired aktiviert, damit ein kurzer Upstream-Ausfall nicht zu Ihrem Ausfall wird. Prüfen Sie den Resolver von woanders, nicht von der Maschine selbst, denn nur so merken Sie den Unterschied zwischen "down" und "unreachable".
Und bewahren Sie eine Kopie der Konfiguration auf. Das Ganze sind ein paar Dutzend Zeilen, für die Sie einen Nachmittag gebraucht haben, um sie richtig hinzubekommen, und die Sie in einem Jahr nicht mehr im Kopf haben werden; sie gehört in Ihre verschlüsselten Backups außerhalb der Maschine, neben die WireGuard-Schlüssel, damit der Wiederaufbau zwanzig Minuten dauert statt einen zweiten Nachmittag. Das ist die ehrliche Zusammenfassung dieser ganzen Übung: eine kleine Box, die einen Job macht, zum Preis des billigsten Plans auf der Liste, die ein Versprechen über Aufbewahrung durch eine Anordnung ersetzt, bei der die Aufzeichnung schlicht niemals entsteht.
SP·09Schritt für Schritt
-
01
Beginnen Sie mit einer Box, die schon abgesichert ist
Ein Resolver ist ein kleiner, stiller Dienst, was es verlockend macht, ihn auf irgendetwas zu installieren, das gerade herumsteht. Tun Sie das nicht — diese Box wird jeden Namen sehen, den jedes Gerät an Ihrem Tunnel nachschlägt, also verdient sie dieselbe Behandlung wie alles andere, das Secrets hält. Setzen Sie den kleinsten Plan ein, den Sie mögen; 1 GB RAM reicht für einen Haushalt völlig aus, da die Cache-Größen unten in zweistelligen Megabyte-Bereichen liegen. Arbeiten Sie die erste Stunde nach dem Deploy durch, bevor Sie irgendetwas anderes tun: ein benannter Benutzer, ausschließlich schlüsselbasiertes SSH, Default-Deny auf beiden IP-Familien, unbeaufsichtigte Sicherheitsupdates.
Installieren Sie dann Unbound. Das Distributionspaket liefert die Root Hints und den DNSSEC-Root-Trust-Anchor mit und richtet den automatischen Rollover des Ankers ein, was einer der wenigen Fälle ist, in denen die paketierte Version Sie wirklich vor einer ganzen Klasse künftiger Probleme bewahrt.
sudo apt update && sudo apt install -y unbound dnsutils unbound -V | head -n 3 # the packaged trust anchor the resolver will validate against sudo ls -l /var/lib/unbound/root.key
Falls
root.keyfehlt, hat Ihr Paketunbound-anchornicht ausgeführt, und die Validierung wird bei allem fehlschlagen und geschlossen ausfallen. Erzeugen Sie sie einmalig mitsudo -u unbound unbound-anchor -a /var/lib/unbound/root.key, bevor Sie fortfahren. -
02
Nehmen Sie Port 53 von systemd-resolved zurück
Auf den meisten aktuellen Distributionen gehört Port 53 schon jemandem:
systemd-resolvedbetreibt einen Stub-Listener auf127.0.0.53, und/etc/resolv.confist ein Symlink, der darauf zeigt. Unbound wird sich weigern zu starten, oder es startet und bindet nichts Brauchbares, bis das gelöst ist. Schauen Sie nach, bevor Sie etwas ändern.ss -ulpn 'sport = :53' ls -l /etc/resolv.conf
Lesen Sie diesen Absatz, bevor Sie den nächsten Block ausführen: Zwischen dem Deaktivieren des Stubs und dem Start von Unbound hat diese Maschine überhaupt kein funktionierendes DNS. Erledigen Sie Schritt 3 und 4 in derselben Sitzung, und starten Sie nicht zuerst in einem anderen Fenster eine
apt-Operation — sie wird bei einer Namensauflösung hängen bleiben, und Sie werden es fälschlich dem Resolver zuschreiben, den Sie noch gar nicht gestartet haben.# stop resolved from holding the port (appends inside the [Resolve] section) printf 'DNSStubListener=no\n' | sudo tee -a /etc/systemd/resolved.conf sudo systemctl restart systemd-resolved # point the host at the resolver it is about to run sudo rm -f /etc/resolv.conf printf 'nameserver 127.0.0.1\noptions edns0 trust-ad\n' | sudo tee /etc/resolv.conf # the port should now be free ss -ulpn 'sport = :53'
-
03
Schreiben Sie eine Konfiguration, die rekursiv arbeitet und vergisst
Lassen Sie die paketierte Konfiguration unangetastet und fügen Sie Ihre eigene Datei im Drop-in-Verzeichnis hinzu, damit ein Paket-Upgrade Ihre Entscheidungen niemals stillschweigend zurücksetzt. Jede Zeile unten dreht sich entweder darum, Fremde abzuweisen, von der Root aus rekursiv zu arbeiten, oder keine Aufzeichnungen zu führen. Ersetzen Sie
10.66.0.1und10.66.0.0/24durch die Tunnel-Adresse und das Subnetz Ihres eigenen WireGuard-Servers, falls diese abweichen.sudo tee /etc/unbound/unbound.conf.d/private-resolver.conf > /dev/null <<'EOF' server: # listen for the host itself and for the tunnel — never on 0.0.0.0 interface: 127.0.0.1 interface: 10.66.0.1 port: 53 # default-deny: refuse the internet, then allow what you trust access-control: 0.0.0.0/0 refuse access-control: ::/0 refuse access-control: 127.0.0.0/8 allow access-control: 10.66.0.0/24 allow # recurse from the root and send each server only the label it needs qname-minimisation: yes harden-dnssec-stripped: yes harden-below-nxdomain: yes harden-glue: yes aggressive-nsec: yes use-caps-for-id: yes # answer nothing about the software or the host hide-identity: yes hide-version: yes # keep no query log, and say little to the journal verbosity: 0 log-queries: no log-replies: no # a warm cache is an upstream observation that never happens cache-min-ttl: 120 cache-max-ttl: 86400 prefetch: yes prefetch-key: yes serve-expired: yes # belt and braces if a rule above is ever loosened ratelimit: 1000 ip-ratelimit: 100 # sizing for a small instance num-threads: 2 so-reuseport: yes msg-cache-size: 32m rrset-cache-size: 64m EOFBeachten Sie, was nicht in der Datei steht: Es gibt keine
forward-zone. Ihre Abwesenheit ist es, was daraus einen rekursiven Resolver macht statt eines Caches vor dem eines anderen. Wenn Sie später einen Snippet aus einem Tutorial einfügen, das eine hinzufügt, haben Sie stillschweigend den ganzen Sinn der Übung zunichtegemacht. -
04
Starten Sie ihn, und beweisen Sie dann, dass DNSSEC wirklich validiert
Prüfen Sie die Syntax, bevor Sie irgendetwas neu starten — auf einer Box, deren eigene
resolv.confjetzt auf Unbound zeigt, bedeutet ein Konfigurationsfehler keine Namensauflösung, während Sie ihn debuggen.sudo unbound-checkconf sudo systemctl enable --now unbound systemctl --no-pager status unbound | head -n 5
Verifizieren Sie jetzt die beiden Verhaltensweisen, auf die es ankommt, denn ein Resolver, der antwortet, ist nicht dasselbe wie ein Resolver, der validiert. Ein signierter Name muss mit dem
ad-Flag zurückkommen — authenticated data —, und ein Name mit absichtlich kaputten Signaturen muss geschlossen ausfallen, mitSERVFAIL, statt aufgelöst zu werden.# should show: flags: qr rd ra ad dig @127.0.0.1 example.com +dnssec | grep -E '^;; flags' # should show: status: SERVFAIL (not NOERROR, not an address) dig @127.0.0.1 dnssec-failed.org | grep -E '^;; ->>HEADER' # and a normal name should simply work dig @127.0.0.1 +short cloudflare.com
Wenn die kaputte Zone auf eine Adresse aufgelöst wird, läuft die Validierung nicht: Prüfen Sie, dass
/var/lib/unbound/root.keyexistiert und für den Benutzerunboundlesbar ist. Wenn allesSERVFAIList, liegt die übliche Ursache in einer stark falschgehenden Uhr — Signaturen haben Gültigkeitsfenster, und eine Box, die mehrere Stunden aus der Synchronisation ist, weist das gesamte Internet zurück. -
05
Schließen Sie die öffentliche Tür, öffnen Sie nur den Tunnel
Die Konfiguration weist Fremde bereits zurück. Dieser Schritt sorgt dafür, dass es für einen Fremden von vornherein nichts zu erreichen gibt — das zweite der beiden Schlösser, und dasjenige, das eine künftige Bearbeitung des ersten überlebt.
# DNS is reachable from the tunnel interface only sudo ufw allow in on wg0 to any port 53 proto udp sudo ufw allow in on wg0 to any port 53 proto tcp sudo ufw status verbose
Verifizieren Sie es dann auf die einzige Art, die zählt, von einer anderen Maschine aus. Vom Server selbst zu testen beweist überhaupt nichts — Loopback ist absichtlich erlaubt. Führen Sie das von Ihrem Laptop aus, mit dem Tunnel down, oder von jedem anderen Host, den Sie haben.
# must time out. an answer here means you are running an open resolver. dig @SERVER_PUBLIC_IP example.com +time=3 +tries=1 # same question over IPv6, which is the half people forget dig -6 @SERVER_IPV6 example.com +time=3 +tries=1
Falls eines von beiden eine Antwort liefert, stoppen Sie und beheben Sie es jetzt, statt erst nach dem Abuse-Report. Die üblichen Ursachen sind ein
interface: 0.0.0.0, das in einer paketierten Konfigurationsdatei übrig geblieben ist, eine Firewall-Regel, die 53 global aus einem früheren Experiment heraus erlaubt, oder Docker, das einen Container-Port veröffentlicht, derufwvollständig umgeht. -
06
Richten Sie Ihre Geräte darauf aus
Auf der Client-Seite ist das eine Änderung von einer Zeile. In der WireGuard-Client-Konfiguration wird die
DNS-Zeile zur Tunnel-Adresse Ihres Servers statt zu einem öffentlichen Resolver — das ist die Änderung, dieDNS = 9.9.9.9aus dem WireGuard-Guide in den Ruhestand schickt.[Interface] PrivateKey = <paste client.key> Address = 10.66.0.2/32, fd86:ea04:1115::2/128 DNS = 10.66.0.1 [Peer] PublicKey = <paste server.pub> Endpoint = YOUR_SERVER_IP:51820 AllowedIPs = 0.0.0.0/0, ::/0 PersistentKeepalive = 25
Bringen Sie den Tunnel hoch und bestätigen Sie zwei getrennte Dinge vom Client aus: dass Antworten von Ihrem Resolver kommen, und dass die Rekursion tatsächlich von Ihrem VPS ausgeht und nicht von irgendwo anders. Die zweite Prüfung ist die nützliche —
whoami.akamai.netgibt die Adresse des jeweils anfragenden Resolvers zurück, also sollte es die öffentliche IP Ihres Servers ausgeben und nichts sonst.# answers should come from the tunnel address dig example.com | grep -E 'SERVER:' # should print your VPS public IP — this is the leak test dig +short whoami.akamai.net # and the ad flag should still be there, end to end dig example.com +dnssec | grep -E '^;; flags'
-
07
Fügen Sie DNS-over-TLS nur für ein Gerät hinzu, das keinen Tunnel halten kann
Überspringen Sie diesen Schritt, außer Sie haben ein bestimmtes Gerät — meist ein Android-Telefon, über dessen systemweite Einstellung für privates DNS —, das Sie ohne permanenten Tunnel abdecken wollen. Es braucht einen Hostnamen und ein Zertifikat, und dieser Hostname wird zu einem dauerhaften öffentlichen Eintrag in den Certificate-Transparency-Logs, also wählen Sie einen, der nirgendwo in die Nähe Ihrer anderen Identitäten führt.
sudo apt install -y certbot sudo ufw allow 80/tcp comment 'certbot, temporarily' sudo certbot certonly --standalone -d dns.example.net sudo ufw delete allow 80/tcp # unbound must be able to read the key sudo usermod -a -G ssl-cert unbound 2>/dev/null || true sudo chgrp -R ssl-cert /etc/letsencrypt/live /etc/letsencrypt/archive sudo chmod -R g+rX /etc/letsencrypt/live /etc/letsencrypt/archive
Fügen Sie den TLS-Listener als eigene Drop-in-Datei hinzu, damit Sie ihn mit einer Aktion löschen können, falls Sie es sich anders überlegen.
# NOTE: drop-in files are read in alphabetical order and the last # access-control line for a given prefix wins — so this file must # sort AFTER private-resolver.conf, or its refuse rule overrides # the allow below and every DoT client gets REFUSED. sudo tee /etc/unbound/unbound.conf.d/zz-dot.conf > /dev/null <<'EOF' server: interface: 0.0.0.0@853 interface: ::0@853 tls-service-key: "/etc/letsencrypt/live/dns.example.net/privkey.pem" tls-service-pem: "/etc/letsencrypt/live/dns.example.net/fullchain.pem" # roaming clients have no fixed address, so this endpoint must accept any. # safe only because port 53 stays bound to loopback + wg0 and blocked at # the firewall — TLS over TCP cannot be spoofed, so it cannot be reflected. access-control: 0.0.0.0/0 allow access-control: ::/0 allow EOF sudo ufw allow 853/tcp sudo unbound-checkconf && sudo systemctl restart unboundTesten Sie es von außerhalb des Tunnels, bevor Sie ihm vertrauen, und tragen Sie den Hostnamen dann in das Feld für privates DNS des Telefons ein. Die Erneuerung ist der Teil, der drei Monate später lautlos kaputtgeht — certbot ersetzt das Zertifikat, aber Unbound hält das alte weiterhin im Speicher, also fügen Sie einen Deploy-Hook hinzu, der ihn neu lädt.
kdig -d @dns.example.net +tls-ca +tls-host=dns.example.net example.com echo 'systemctl reload unbound' | sudo tee /etc/letsencrypt/renewal-hooks/deploy/unbound.sh sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/unbound.sh


