Ein IP-Adressgenerator für Tests hat eine Aufgabe: Adressen zurückgeben, die für den Bereich gültig sind, den das Fixture angibt, ohne versehentlich auf einen Rechner zu zeigen, der eine Rolle spielt. Genau hier scheitern die meisten Generatoren. Eine syntaktisch öffentliche Adresse kann trotzdem einer Bank, einem Cloud-Anbieter oder dem eigenen Büro-Uplink gehören.
Dieser Leitfaden behandelt die vom Generator unterstützten Bereiche, die Spezialbereiche, die jeder Validator kennen sollte, den Unterschied zwischen einer syntaktisch öffentlichen und einer routbaren Adresse sowie den Aufbau von Fixture-Sets, die nicht mit einem echten Netzwerk kollidieren können. Er behandelt außerdem IPv6, wo die Bereichsregeln so anders sind, dass ein übertragenes IPv4-Denkmodell fehlerhafte Tests erzeugt.
Was der Generator zurückgibt
Für IPv4 erzeugt der Generator Werte in vier Bereichen: öffentlich, privat, Loopback und Link-Local. Für IPv6 erzeugt er ebenfalls vier Bereiche: global, Unique Local (ULA), Link-Local und Loopback. Der Bereich ist Teil der Anfrage und nicht etwas, das man aus der Ausgabe errät, denn dasselbe Dotted Quad kann in einem Kontext privat und in einem anderen ein gültiger Host in einem privaten Netz sein.
Der Bereich ist ein Fixture-Label, keine Erreichbarkeitsaussage. Eine generierte Adresse im öffentlichen Bereich liegt außerhalb der privaten und Spezialblöcke, kann aber trotzdem mit einer echten Zuweisung irgendwo im Internet übereinstimmen. Senden Sie keinen Traffic an generierte Adressen. Wenn ein Test sicherstellen muss, dass nichts Echtes kontaktiert wird, verwenden Sie die unten beschriebenen Dokumentationsbereiche statt der Ausgabe im öffentlichen Bereich.
- IPv4-Bereiche: öffentlich, privat, Loopback, Link-Local
- IPv6-Bereiche: global, Unique Local, Link-Local, Loopback
- Kein Bereich bedeutet, dass es sicher ist, Traffic an die Adresse zu senden
- Für harte Isolation die Dokumentationsbereiche verwenden, nicht die Ausgabe im öffentlichen Bereich
IPv4-Spezialbereiche
Die folgenden Blöcke muss ein Validator oder Fixture-Builder explizit behandeln. Privater Adressraum ist 10.0.0.0/8, 172.16.0.0/12 und 192.168.0.0/16, was etwa 17,8 Millionen Adressen ergibt. Loopback ist der gesamte Block 127.0.0.0/8, nicht nur 127.0.0.1, und Link-Local ist 169.254.0.0/16, bekannt als APIPA-Bereich, wenn DHCP fehlschlägt.
Darüber hinaus sind mehrere Blöcke für Tests relevant. 100.64.0.0/10 ist Carrier-Grade-NAT-Adressraum und verhält sich in vielen Netzen wie privater Adressraum. 192.0.2.0/24, 198.51.100.0/24 und 203.0.113.0/24 sind für Dokumentation reserviert, was sie ideal für Fixtures macht, die niemals einen echten Host erreichen dürfen. 198.18.0.0/15 ist für Benchmarks reserviert. 0.0.0.0/8 bedeutet „dieser Host“, 224.0.0.0/4 ist Multicast und 240.0.0.0/4 ist reserviert.
| Bereich | CIDR | Adressanzahl | Typische Verwendung |
|---|---|---|---|
| Privat | 10.0.0.0/8 | 16.777.216 | Große private Netze |
| Privat | 172.16.0.0/12 | 1.048.576 | Docker und mittelgroße Netze |
| Privat | 192.168.0.0/16 | 65.536 | Heim- und kleine Büro-LANs |
| Loopback | 127.0.0.0/8 | 16.777.216 | Nur lokaler Host |
| Link-Local | 169.254.0.0/16 | 65.536 | APIPA, wenn DHCP fehlschlägt |
| Carrier-NAT | 100.64.0.0/10 | 4.194.304 | Gemeinsamer Adressraum von ISPs |
| Dokumentation | 192.0.2.0/24 | 256 | Sicherer Fixture-Bereich (TEST-NET-1) |
| Benchmark | 198.18.0.0/15 | 131.072 | Netzwerk-Testgeräte |
| Multicast | 224.0.0.0/4 | 268.435.456 | Gruppenzustellung |
Privater Adressraum und die 10/8-Frage
Die drei privaten Blöcke sind in RFC 1918 definiert und im öffentlichen Internet nicht routbar. Welchen man verwendet, ist eine Frage von Größe und Konvention: 10/8 bietet einen einzigen flachen Raum, der für alles groß genug ist, 172.16/12 ist in Container-Netzen üblich und 192.168/16 ist der Standard bei Consumer-Routern. Die Blöcke überlappen sich nicht, daher liegt ein Test, der annimmt, jede private Adresse beginne mit 10, bei zwei Dritteln des Raums falsch.
Eine Feinheit, die Tests bricht: Private Adressen sind innerhalb des privaten Netzes gewöhnliche Adressen. Wenn Ihr CI-Runner in 10.0.0.0/8 sitzt, kann eine generierte private Adresse in diesem Block auf einen echten internen Host zeigen, einschließlich eines Metadatendienstes oder eines Admin-Panels. Generieren Sie aus dem Bereich 192.168.0.0/16 oder, besser, aus den Dokumentationsbereichen, wenn der Test isoliert sein muss.
- RFC-1918-Blöcke: 10/8, 172.16/12, 192.168/16
- Einen Bereich wählen, der sich nicht mit dem Netz überschneidet, in dem der Test läuft
- Cloud-Metadaten-Endpunkte liegen an bekannten privaten Adressen
- Ein interner Host ist genauso real wie ein externer
Loopback, Link-Local und wohin sie gehören
Loopback-Adressen verlassen niemals den Host. 127.0.0.1 ist die gängige, aber der gesamte Block 127.0.0.0/8 ist auf den meisten Stacks Loopback, und 127.0.0.53 wird von systemd-resolved für lokales DNS verwendet. Ein Test, der 127.0.0.1 fest als Serveradresse einträgt, kollidiert mit allem anderen auf dem Rechner, das denselben Port verwendet, weshalb parallele Testläufe Ports dynamisch vergeben sollten.
IPv4-Link-Local-Adressen in 169.254.0.0/16 werden automatisch vergeben, wenn kein DHCP-Server antwortet. Eine solche Adresse in Produktionslogs bedeutet fast immer, dass DHCP fehlgeschlagen ist, nicht dass ein Kunde in einem seltsamen Netz ist. Bei IPv6 ist das Äquivalent fe80::/10, und es verhält sich anders: Jede IPv6-Schnittstelle hat eine Link-Local-Adresse, sie ist für die Nachbarschaftserkennung erforderlich, und sie kann nicht ohne Zonenindex verwendet werden, weil dieselbe Adresse auf jedem Link existiert.
| Adresse | Bereich | Kann den Host verlassen? | Häufiger Fehler |
|---|---|---|---|
| 127.0.0.1 | IPv4-Loopback | Nein | Annehmen, nur diese sei Loopback |
| 127.0.0.53 | IPv4-Loopback | Nein | Kollision mit dem lokalen Resolver |
| 169.254.1.1 | IPv4-Link-Local | Nur derselbe Link | Sie als öffentliche Adresse behandeln |
| ::1 | IPv6-Loopback | Nein | ::1/128 als Host-Bereich schreiben |
| fe80::1 | IPv6-Link-Local | Nur derselbe Link | Den Zonenindex weglassen |
IPv6-Bereiche ohne IPv4-Denkmodell
IPv6 hat keinen Broadcast und keine NAT-Anforderung, und seine Bereichsregeln stecken im Präfix. Global Unicast liegt derzeit in 2000::/3, also im gesamten Bereich von 2000:: bis 3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff. Unique-Local-Adressen liegen in fc00::/7 und werden üblicherweise aus fd00::/8 generiert. Link-Local ist fe80::/10, und ::1/128 ist Loopback, wobei ::/128 die unspezifizierte Adresse ist.
Der Generator gibt Adressen in diesen vier Bereichen zurück. Zwei Details sind für Tests wichtig: Eine ULA-Adresse ist nicht global routbar und muss als privat behandelt werden, und eine Link-Local-Adresse ist nur mit einer Zonenkennung sinnvoll, zum Beispiel fe80::1%eth0. Wenn Ihr Code eine IPv6-Adresse speichert, speichern Sie die Zone getrennt statt in den Text geklebt, denn ein Prozentzeichen in einer URL hat eine andere Bedeutung.
| Bereich | Präfix | Routbar | Beispiel |
|---|---|---|---|
| Global Unicast | 2000::/3 | Ja, grundsätzlich | 2001:db8::1 |
| Unique Local | fc00::/7 | Nein, privat | fd12:3456::1 |
| Link-Local | fe80::/10 | Nur derselbe Link | fe80::1 |
| Loopback | ::1/128 | Nein | ::1 |
| Dokumentation | 2001:db8::/32 | Für Dokumentation reserviert | 2001:db8::1 |
Übergangsadressen und andere Fallstricke
IPv4-gemappte IPv6-Adressen haben die Form ::ffff:192.0.2.1 und erscheinen, wenn ein Dual-Stack-Socket einen IPv4-Peer als IPv6 meldet. Sie sind keine Allzweck-IPv6-Adressen, und ihre Behandlung als solche erzeugt Fehler in Rate Limitern und Zugriffsregeln, die Präfixe vergleichen. 6to4-Adressen in 2002::/16 und Teredo-Adressen in 2001::/32 sind Übergangsmechanismen mit eigener Struktur; generieren Sie sie nicht, als wären sie gewöhnliche globale Adressen.
Andere Fallstricke sind älter, aber noch vorhanden. Eine führende Null in einem IPv4-Oktett wie 010.1.1.1 wird von manchen Parsern als Oktal interpretiert und von anderen abgelehnt, daher sollte man sie in einem Fixture niemals akzeptieren. Die abgekürzte Form 127.1 wird von manchen Stacks als 127.0.0.1 akzeptiert. Ports sind ein separates Feld und dürfen niemals an den Adresswert angehängt werden.
- ::ffff:0:0/96 ist IPv4-gemappt, kein normaler IPv6-Bereich
- 2001:db8::/32 ist Dokumentationsraum und der sichere Standard für Fixtures
- Oktette mit führenden Nullen ablehnen, statt die Basis zu raten
- Formen wie 127.1 ablehnen, die auf stack-spezifischer Expansion beruhen
- Den Port aus dem Adressfeld heraushalten; ihn als separate Ganzzahl validieren
Ein Fixture-Set aufbauen, das nicht kollidieren kann
Für Unit-Tests, die nie einen Socket öffnen, verwenden Sie Dokumentationsbereiche: 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24 für IPv4 und 2001:db8::/32 für IPv6. Diese sind genau deshalb reserviert, damit Beispiele und Tests keinen echten Host erreichen können. Ein Parser sollte sie als syntaktisch gültige Adressen im öffentlichen Bereich akzeptieren, was sie auch zu einem guten Test der Klassifizierungslogik macht.
Für Integrationstests, die Sockets öffnen, binden Sie an Loopback und lassen Sie den Port vom Betriebssystem vergeben, statt 8080 fest einzutragen. Für Tests, die einen plausiblen Remote-Peer benötigen, verwenden Sie die Dokumentationsbereiche und lassen Sie jeden Client die Verbindung dorthin verweigern. Diese Kombination liefert realistische Werte und die harte Garantie, dass eine Fehlkonfiguration keinen Traffic an eine unerwartete Stelle senden kann.
| Bedarf | Verwenden | Warum |
|---|---|---|
| Parsen und Formatieren | 192.0.2.0/24, 2001:db8::/32 | Reserviert, kann keinen Host erreichen |
| Logik für privaten Bereich | 192.168.0.0/16 | Überschneidet sich wahrscheinlich nicht mit CI-Netzen |
| Loopback-Server | 127.0.0.1 mit vom Betriebssystem vergebenem Port | Keine festen Portkollisionen |
| Link-Local-Logik | 169.254.0.0/16 und fe80::/10 | Löst die richtigen Zweige aus |
| Bereichsklassifizierung | Alle vier Bereiche in einer Tabelle | Fängt eine falsche Maske oder ein falsches Präfix |
Ausgabe validieren, bevor sie einen Test erreicht
Jede generierte Adresse sollte denselben Validator bestehen, den die Anwendung verwendet. Das ist der Sinn des Generierens. Stellen Sie sicher, dass die Familie zum angeforderten Bereich passt, dass die Adresse im erwarteten Block liegt und dass die Textform zurück zu denselben Bits parst. Ein Roundtrip fängt Fehler bei der Nullkompression in IPv6 ab, wo 2001:db8:0:0:0:0:0:1 ausschließlich zu 2001:db8::1 normalisiert werden darf.
Stellen Sie außerdem sicher, was die Adresse nicht ist. Ein Fixture im privaten Bereich darf nicht in einem öffentlichen Block liegen, ein Loopback-Fixture muss in 127.0.0.0/8 oder genau ::1 liegen, und kein Fixture sollte jemals Multicast, Broadcast oder die unspezifizierte Adresse sein, es sei denn, der Test behandelt genau diese Fälle. Diese negativen Zusicherungen sind billig und fangen die peinlichsten Generatorfehler ab.
- Roundtrip: parsen, formatieren, parsen, Bits vergleichen statt Strings
- Familienprüfung: Der Wert parst als die angeforderte IP-Version
- Bereichsprüfung: Enthaltensein im Block, kein Präfix-String-Vergleich
- Negativprüfung: kein Multicast, kein Broadcast, nicht unspezifiziert
- Normalisierung: IPv6-Ausgabe verwendet die kanonische komprimierte Form
Fragen
- IPv4 öffentlich, privat, Loopback und Link-Local; IPv6 global, Unique Local, Link-Local und Loopback. Der Bereich wird explizit gewählt und nicht aus der Ausgabe abgeleitet.
- Nein. Öffentlicher Bereich bedeutet außerhalb der privaten und Spezialblöcke, nicht unzugewiesen. Verwenden Sie die Dokumentationsbereiche 192.0.2.0/24 und 2001:db8::/32, wenn ein Test keinen echten Host erreichen darf.
- 100.64.0.0/10. Er ist kein privater Adressraum nach RFC 1918, aber auch nicht global routbar, daher sollte er in der Klassifizierungslogik als privat behandelt werden.
- Der Bereich fe80::/10 existiert auf jedem Link separat, daher kann dieselbe Adresse auf verschiedene Hosts verweisen. Die Zonenkennung, etwa ein Prozentzeichen gefolgt von einem Schnittstellennamen, gibt an, welchen Link Sie meinen.
- Er erzeugt die vier dokumentierten IPv6-Bereiche. IPv4-gemappte Formen wie ::ffff:192.0.2.1 sind eine Übergangsdarstellung und sollten von Ihrem Parser behandelt und nicht als gewöhnliche Fixtures verwendet werden.
Welche Bereiche kann der Generator erzeugen?+
Ist es sicher, eine generierte öffentliche IP-Adresse zu kontaktieren?+
Welcher IPv4-Block ist Carrier-Grade-NAT?+
Warum braucht meine IPv6-Link-Local-Adresse einen Zonenindex?+
Kann der Generator IPv4-gemappte IPv6-Adressen erzeugen?+
Beispiele sind synthetisch. Verwenden Sie eine generierte Adresse nicht für Identitätsprüfungen, Kontoregistrierungen oder Lieferungen.