WireGuard DNS DNAT: den Antwortweg am Laufen halten
DNAT schreibt das Ziel um, nicht die Quelle. Entscheiden Sie, wie der vorgelagerte Resolver antworten kann, bevor Sie die Regel hinzufügen, und halten Sie jede Übereinstimmung eng gefasst.
Die DNS-Anfrage eines WireGuard-Clients auf einen anderen Resolver zu richten, sieht wie eine Regel aus und verhält sich wie drei Entscheidungen. Das Ziel muss umgeschrieben, das Paket muss weitergeleitet werden, und die Antwort muss ihren Weg zurück durch den Übersetzungszustand finden, den das Gateway angelegt hat. Lassen Sie das Dritte aus, verlässt die Anfrage sauber den Rechner, während der Client ewig wartet.
Nehmen Sie das Beispiel autorisierter Clients in 10.77.0.0/24, die über wg0 eintreffen, die angekündigte Adresse 10.77.0.1 abfragen und einen Resolver unter 203.0.113.53 benötigen. Die vorgelagerte Adresse ist ein Platzhalter für die Dokumentation und kein funktionierender Dienst.
Eine Anfrage umzuleiten ändert nur ihr Ziel
Eine Ziel-NAT-Regel in PREROUTING schreibt die Adresse um, bevor die Routing-Entscheidung fällt, sodass das Paket anschließend zum neuen statt zum alten Ziel geroutet wird. Die Quelladresse des Clients bleibt von diesem Vorgang unberührt. Deshalb kann eine vollständig wirkende Regel trotzdem Stille erzeugen: Die Anfrage reist nun zu einem Resolver, der vom privaten Bereich des Clients noch nie gehört hat. Das Gateway übersetzte ein Feld und erbte ein zweites Problem.
Beide DNS-Transporte brauchen passende Regeln, weil ein Client auf TCP zurückfällt, wenn eine Antwort gekürzt wird.
Die folgenden Regeln wählen eine eingehende Schnittstelle, einen Clientbereich und eine ursprüngliche Zieladresse. Nichts anderes auf dem Gateway ist betroffen, und eine Anfrage des Gateways selbst passt überhaupt nicht.
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p udp --dport 53 -j DNAT --to-destination 203.0.113.53:53
iptables -t nat -A PREROUTING -i wg0 -s 10.77.0.0/24 -d 10.77.0.1 -p tcp --dport 53 -j DNAT --to-destination 203.0.113.53:53
Der Antwortweg ist eine eigene Entscheidung
Zwei Anordnungen lassen die Antwort zurückkehren, und wer sich früh für eine entscheidet, spart eine Debugging-Sitzung. Entweder hat der vorgelagerte Resolver eine Route zurück zu 10.77.0.0/24 über dieses Gateway, oder das Gateway übersetzt die Quelle beim Verlassen, sodass die Antwort an einer Adresse ankommt, die die Gegenstelle bereits kennt. Beides funktioniert; nur eines passt zu der Kontrolle, die Sie über die Gegenstelle haben.
Routing verdient den ersten Versuch, weil es die Adresse des Clients für den Resolver sichtbar hält und eine zweite Übersetzungsschicht vermeidet. Liegt die Gegenstelle außerhalb Ihrer Kontrolle, ist die Quellübersetzung auf der jeweiligen Ausgangsschnittstelle die praktische Wahl.
Fassen Sie diese Übersetzung so eng wie die Umleitung, sonst wird die Regel ein Allzweck-NAT für alles, was zufällig passt:
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p udp --dport 53 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.77.0.0/24 -d 203.0.113.53 -o eth0 -p tcp --dport 53 -j MASQUERADE
Die Verbindungsverfolgung hält die Zuordnung gepaart, sodass die Antwort auf dem Rückweg wieder auf das ursprüngliche Tupel des Clients umgeschrieben wird. Ohne die Ausgangsregel schickt der Resolver seine Antwort an eine private Adresse, die er nicht erreichen kann, und der Client sieht einen Timeout statt eines Fehlers.
Schreiben Sie die Regeln enger, als die Aufgabe aussieht
Die Weiterleitungserlaubnis gehört zum selben Bereich. Erlauben Sie den Fluss vom Client zum Resolver und den Rückverkehr, den conntrack bereits erkennt, statt jede DNAT-Verbindung auf der Maschine anzunehmen. Eine pauschale Annahme genehmigt auch Portweiterleitungen, die nichts mit DNS zu tun haben.
Der eigene Resolver des Gateways ist ein anderer Codepfad. Eine lokal gestellte Anfrage geht durch OUTPUT, daher übt ein Test aus der Gateway-Shell weder die PREROUTING-Regel noch die Weiterleitungsrichtlinie. Deshalb kann ein lokaler Test bestehen, während jeder Client scheitert, und das Umgekehrte ist genauso häufig.
Nichts hier deckt DNS über HTTPS auf Port 443 oder DNS über TLS auf Port 853 ab, und nichts deckt IPv6 ab. Ein Client mit einem konfigurierten IPv6-Resolver ignoriert die ganze Anordnung vergnügt.
Was eine frische Anfrage beweist
Die Verbindungsverfolgung erinnert sich an frühere Zuordnungen, daher kann eine vor einer Regeländerung gesendete Anfrage aus dem alten Zustand beantwortet werden und die neue Regel kaputt aussehen lassen. Beginnen Sie mit einem neuen Quellport und, wo der Client Antworten zwischenspeichert, mit einem neuen Namen.
dig @10.77.0.1 example.com A +short
conntrack -L -p udp --dport 53 | head
Der erste Befehl zeigt, ob der Clientpfad überhaupt auflöst, und der zweite zeigt die Übersetzung, die das Gateway tatsächlich installiert hat, einschließlich beider Richtungen des Tupels. Eine Zuordnung zum richtigen Resolver mit einem bei null klebenden Antwortzähler ist ein Problem des Rückwegs und kein Filterproblem.
Bestätigen Sie, dass der Resolver die erwarteten Namen kennt, bevor Sie etwas umleiten. Ein Ersatz, der öffentliche Namen beantwortet, aber nicht Ihre private Zone verwandelt eine funktionierende Auflösung in ein NXDOMAIN, das wie ein defekter Tunnel aussieht. Testen Sie den Resolver direkt vom Gateway aus, bevor der Clientpfad beteiligt ist. Und Referenz zu den iptables-Erweiterungen dokumentiert die DNAT- und Masquerade-Semantik, auf der diese Regeln beruhen.