IPv6 DNS64

Aus Xinux Wiki
Zur Navigation springen Zur Suche springen

DNS64

Worum geht es?

Stell dir ein Netz vor, in dem die Clients nur noch IPv6 haben. Kein IPv4 mehr, keine privaten 192.168er-Adressen, nichts.

Das funktioniert wunderbar, solange das Ziel ebenfalls IPv6 kann. Ein großer Teil des Internets ist aber immer noch nur über IPv4 erreichbar. Ein reiner IPv6-Client kann mit einer IPv4-Adresse nichts anfangen: Er hat gar keinen IPv4-Stack, über den er das Paket schicken könnte.

Genau dieses Problem lösen DNS64 und NAT64 gemeinsam:

  • DNS64 sorgt dafür, dass der Client für ein reines IPv4-Ziel trotzdem eine IPv6-Adresse bekommt.
  • NAT64 sorgt dafür, dass Pakete an diese IPv6-Adresse tatsächlich beim IPv4-Ziel ankommen.

Keiner der beiden ist alleine sinnvoll. DNS64 ohne NAT64 liefert Adressen, die ins Leere führen. NAT64 ohne DNS64 hat keine Clients, die es benutzen.

Die Grundidee in einem Satz

Der DNS-Server versteckt die IPv4-Adresse in einer IPv6-Adresse, und das NAT64-Gateway holt sie wieder heraus.

Das Präfix 64:ff9b::/96

Eine IPv6-Adresse hat 128 Bit, eine IPv4-Adresse 32 Bit. Es bleiben also 96 Bit übrig. Diese 96 Bit werden mit einem festen Präfix gefüllt, die IPv4-Adresse kommt in die letzten 32 Bit.

Für diesen Zweck ist ein Präfix offiziell reserviert, das sogenannte Well-Known Prefix (RFC 6052):

  • 64:ff9b::/96
|<-------------- 96 Bit Präfix ------------->|<-- 32 Bit IPv4 -->|
  64:ff9b:0000:0000:0000:0000                     c000:020a

Man kann auch ein eigenes Präfix verwenden. Wichtig ist nur, dass DNS64 und NAT64 dasselbe Präfix kennen.

Umrechnung einer IPv4-Adresse

Beispiel: 192.0.2.10

Jedes Oktett wird in Hex umgerechnet:

192 -> c0
  0 -> 00
  2 -> 02
 10 -> 0a

Zusammengesetzt ergibt das c000:020a, verkürzt c000:20a. Die vollständige IPv6-Adresse lautet:

  • 64:ff9b::c000:20a

IPv6 erlaubt für genau solche Fälle auch eine gemischte Schreibweise. Diese Adresse ist identisch mit der oben:

  • 64:ff9b::192.0.2.10

Der Ablauf Schritt für Schritt

Ausgangslage:

  • Der Client hat nur IPv6.
  • Der Client benutzt einen DNS64-fähigen Resolver.
  • Der Webserver ipv4only.example hat nur einen A-Record: 192.0.2.10
  • Im Netz steht ein NAT64-Gateway mit einer öffentlichen IPv4-Adresse.
 +--------+        +--------+        +-------------+        +-----------+
 | Client |        | DNS64  |        | NAT64       |        | Webserver |
 | (v6)   |        | Server |        | Gateway     |        | (nur v4)  |
 +--------+        +--------+        +-------------+        +-----------+
     |                  |                   |                      |
     |-- AAAA? -------->|                   |                      |
     |                  |-- AAAA? ins Internet: keine Antwort      |
     |                  |-- A?    ins Internet: 192.0.2.10         |
     |<- AAAA ----------|                   |                      |
     |   64:ff9b::c000:20a                  |                      |
     |                                      |                      |
     |-- IPv6-Paket an 64:ff9b::c000:20a -->|                      |
     |                                      |-- IPv4-Paket ------->|
     |                                      |   an 192.0.2.10      |
     |                                      |<-- Antwort ----------|
     |<-- Antwort als IPv6 -----------------|                      |

1. Der Client fragt nach einer IPv6-Adresse

Der Client will ipv4only.example erreichen. Da er nur IPv6 kann, fragt er seinen Resolver nach dem AAAA-Record.

2. Der DNS64-Server findet keinen AAAA-Record

Der DNS64-Server fragt ganz normal im Internet nach. Ergebnis: Es gibt keinen AAAA-Record, der Server hat kein IPv6.

3. Der DNS64-Server holt sich den A-Record

Jetzt kommt der Trick: Statt dem Client einfach "gibt es nicht" zu antworten, fragt der DNS64-Server zusätzlich nach dem A-Record und bekommt 192.0.2.10.

4. Der DNS64-Server baut einen künstlichen AAAA-Record

Er setzt die IPv4-Adresse hinter das Präfix und schickt dem Client:

  • ipv4only.example AAAA 64:ff9b::c000:20a

Der Client weiß nicht, dass diese Adresse "erfunden" ist. Für ihn ist das eine ganz normale IPv6-Adresse.

5. Der Client schickt sein Paket los

Der Client schickt ein ganz normales IPv6-Paket an 64:ff9b::c000:20a. Im Netz gibt es eine Route, die dieses Präfix zum NAT64-Gateway führt.

6. Das NAT64-Gateway übersetzt nach IPv4

Das Gateway sieht das Präfix 64:ff9b::/96 und weiß: Die letzten 32 Bit sind eine IPv4-Adresse. Es baut ein neues IPv4-Paket:

  • Ziel: 192.0.2.10
  • Quelle: die eigene öffentliche IPv4-Adresse des Gateways

Es merkt sich in einer Tabelle, welcher IPv6-Client zu dieser Verbindung gehört. Das ist dasselbe Prinzip wie beim bekannten NAT mit IPv4.

7. Die Antwort kommt zurück

Der Webserver antwortet an die IPv4-Adresse des Gateways. Das Gateway schaut in seiner Tabelle nach, übersetzt das Paket zurück nach IPv6 und schickt es an den Client. Als Absender steht dort wieder 64:ff9b::c000:20a.

Was passiert, wenn das Ziel IPv6 kann?

Dann passiert gar nichts Besonderes. Findet der DNS64-Server einen echten AAAA-Record, gibt er nur diesen weiter und erfindet nichts. Der Client spricht direkt per IPv6 mit dem Ziel, das NAT64-Gateway wird nicht benutzt.

DNS64 greift also nur dann ein, wenn es wirklich nötig ist.

Wer macht was?

Baustein Aufgabe Fasst Datenpakete an?
DNS64 Erzeugt künstliche AAAA-Records aus A-Records Nein, nur DNS
NAT64 Übersetzt IPv6-Pakete in IPv4-Pakete und zurück Ja

Typische Software:

  • DNS64: BIND9, Unbound, PowerDNS Recursor
  • NAT64: Jool oder Tayga unter Linux, pf unter FreeBSD/OPNsense, viele Router und Firewalls

Konfiguration

BIND9

In /etc/bind/named.conf.options innerhalb von options
options {
    dns64 64:ff9b::/96 {
        clients { any; };
    };
};
Konfiguration prüfen und neu laden
  • named-checkconf
  • systemctl reload named

Unbound

In /etc/unbound/unbound.conf im Abschnitt server
server:
    module-config: "dns64 validator iterator"
    dns64-prefix: 64:ff9b::/96
Konfiguration prüfen und neu starten
  • unbound-checkconf
  • systemctl restart unbound

Testen

Funktioniert DNS64?

Für Tests gibt es den speziellen Namen ipv4only.arpa. Er hat absichtlich nur A-Records (192.0.0.170 und 192.0.0.171).

Ohne DNS64
keine AAAA-Antwort
Mit DNS64
eine künstliche Adresse mit dem Präfix
  • dig AAAA ipv4only.arpa @2001:db8:1::53
Erwartete Antwort
ipv4only.arpa.   IN  AAAA  64:ff9b::c000:aa
ipv4only.arpa.   IN  AAAA  64:ff9b::c000:ab

c000:aa ist 192.0.0.170, c000:ab ist 192.0.0.171.

Clients können über diese Abfrage auch selbst herausfinden, welches Präfix im Netz verwendet wird (RFC 7050).

Funktioniert NAT64?

Ein bekanntes IPv4-Ziel über das Präfix anpingen (hier 1.1.1.1)
  • ping -6 64:ff9b::1.1.1.1
Ein Name, der nur IPv4 hat

Grenzen und Stolperfallen

IPv4-Adressen direkt im Programm

DNS64 funktioniert nur, wenn ein Name aufgelöst wird. Ein Programm, das direkt 192.0.2.10 anspricht, stellt keine DNS-Anfrage, und der reine IPv6-Client kann die Adresse nicht benutzen.

Lösung: 464XLAT. Dabei läuft auf dem Client ein kleiner Übersetzer (CLAT), der dem Betriebssystem eine IPv4-Adresse vortäuscht und die Pakete selbst nach IPv6 übersetzt. So machen es Mobilfunknetze, Android und neuere Windows-, macOS- und iOS-Versionen.

DNSSEC

Ein künstlicher AAAA-Record hat keine gültige DNSSEC-Signatur. Validiert der Client selbst, verwirft er die Antwort. Validiert der DNS64-Resolver, funktioniert es, weil er vor der Synthese prüft.

Fremde DNS-Server

DNS64 funktioniert nur, wenn der Client den DNS64-Resolver tatsächlich benutzt. Ein fest eingetragener öffentlicher DNS-Server oder DNS-over-HTTPS im Browser umgeht ihn. Der Client bekommt dann keine künstlichen Adressen und erreicht IPv4-Ziele nicht mehr.

Private IPv4-Ziele

Das Well-Known Prefix 64:ff9b::/96 ist nur für öffentliche IPv4-Adressen gedacht. Sollen interne Server mit Adressen wie 10.0.0.0/8 oder 192.168.0.0/16 erreichbar sein, braucht man ein eigenes Präfix aus dem eigenen Adressbereich.

Zusammenfassung

  • DNS64 erfindet für reine IPv4-Ziele eine IPv6-Adresse, indem es die IPv4-Adresse hinter ein Präfix hängt.
  • NAT64 erkennt dieses Präfix, holt die IPv4-Adresse heraus und übersetzt das Paket.
  • Hat das Ziel einen echten AAAA-Record, wird DNS64 nicht aktiv.
  • Beide Bausteine müssen dasselbe Präfix verwenden, meistens 64:ff9b::/96.
  • Für Programme, die IPv4-Adressen direkt benutzen, braucht man zusätzlich 464XLAT.