Un generador de direcciones IP para pruebas tiene una sola misión: devolver direcciones válidas para el ámbito que declara el fixture, sin apuntar por accidente a una máquina que importa. La segunda parte es donde fallan la mayoría de los generadores. Una dirección sintácticamente pública puede pertenecer a un banco, a un proveedor de nube o al enlace de tu propia oficina.
Esta guía cubre los ámbitos que admite el generador, los rangos de uso especial que todo validador debería conocer, la diferencia entre una dirección sintácticamente pública y una enrutable, y cómo construir conjuntos de fixtures que no puedan colisionar con una red real. También cubre IPv6, donde las reglas de ámbito son lo bastante distintas como para que copiar el modelo mental de IPv4 produzca pruebas rotas.
Qué devuelve el generador
Para IPv4, el generador produce valores en cuatro ámbitos: público, privado, loopback y link-local. Para IPv6 también produce cuatro ámbitos: global, unique local (ULA), link-local y loopback. El ámbito forma parte de la solicitud, no se deduce de la salida, porque el mismo cuarteto con puntos puede ser privado en un contexto y un host válido en una red privada en otro.
El ámbito es una etiqueta del fixture, no una afirmación de alcanzabilidad. Una dirección generada con ámbito público queda fuera de los bloques privados y de uso especial, pero aun así puede coincidir con una asignación real en algún punto de internet. No envíes tráfico a direcciones generadas. Si una prueba debe tener la certeza de que no se contacta nada real, usa los rangos de documentación descritos más abajo en lugar de la salida de ámbito público.
- Ámbitos IPv4: público, privado, loopback, link-local
- Ámbitos IPv6: global, unique local, link-local, loopback
- Ningún ámbito implica que sea seguro enviar tráfico a la dirección
- Para aislamiento estricto, usa los rangos de documentación, no la salida de ámbito público
Rangos IPv4 de uso especial
Los bloques siguientes son los que un validador o un constructor de fixtures debe tratar de forma explícita. El espacio privado es 10.0.0.0/8, 172.16.0.0/12 y 192.168.0.0/16, lo que da aproximadamente 17,8 millones de direcciones. Loopback es todo el bloque 127.0.0.0/8, no solo 127.0.0.1, y link-local es 169.254.0.0/16, conocido como el rango APIPA cuando falla DHCP.
Además de esos, varios bloques importan para las pruebas. 100.64.0.0/10 es espacio de NAT de nivel de operador y se comporta como espacio privado en muchas redes. 192.0.2.0/24, 198.51.100.0/24 y 203.0.113.0/24 están reservados para documentación, lo que los hace ideales para fixtures que nunca deben alcanzar un host real. 198.18.0.0/15 está reservado para benchmarking. 0.0.0.0/8 significa «este host», 224.0.0.0/4 es multicast y 240.0.0.0/4 está reservado.
| Ámbito | CIDR | Cantidad de direcciones | Uso típico |
|---|---|---|---|
| Privado | 10.0.0.0/8 | 16.777.216 | Redes privadas grandes |
| Privado | 172.16.0.0/12 | 1.048.576 | Redes de Docker y de tamaño medio |
| Privado | 192.168.0.0/16 | 65.536 | LAN domésticas y de pequeña oficina |
| Loopback | 127.0.0.0/8 | 16.777.216 | Solo el host local |
| Link-local | 169.254.0.0/16 | 65.536 | APIPA cuando falla DHCP |
| NAT de operador | 100.64.0.0/10 | 4.194.304 | Espacio de direcciones compartido del ISP |
| Documentación | 192.0.2.0/24 | 256 | Rango seguro para fixtures (TEST-NET-1) |
| Benchmark | 198.18.0.0/15 | 131.072 | Equipos de prueba de red |
| Multicast | 224.0.0.0/4 | 268.435.456 | Entrega en grupo |
Espacio privado y la cuestión de 10/8
Los tres bloques privados están definidos por RFC 1918 y no son enrutables en la internet pública. Cuál usar es cuestión de escala y convención: 10/8 ofrece un único espacio plano lo bastante grande para cualquier cosa, 172.16/12 es común en redes de contenedores y 192.168/16 es el valor por defecto en los routers domésticos. Los bloques no se solapan, así que una prueba que asume que toda dirección privada empieza por 10 se equivoca en dos tercios del espacio.
Una sutileza que rompe pruebas: las direcciones privadas son direcciones ordinarias dentro de la red privada. Si tu runner de CI está en 10.0.0.0/8, una dirección privada generada en ese bloque puede apuntar a un host interno real, incluido un servicio de metadatos o un panel de administración. Genera desde el rango 192.168.0.0/16 o, mejor, desde los rangos de documentación cuando la prueba deba estar aislada.
- Bloques RFC 1918: 10/8, 172.16/12, 192.168/16
- Elige un rango que no se solape con la red que ejecuta la prueba
- Los endpoints de metadatos de la nube viven en direcciones privadas conocidas
- Un host interno es tan real como uno externo
Loopback, link-local y dónde corresponden
Las direcciones loopback nunca salen del host. 127.0.0.1 es la habitual, pero todo el bloque 127.0.0.0/8 es loopback en la mayoría de las pilas, y 127.0.0.53 lo usa systemd-resolved para DNS local. Una prueba que fija 127.0.0.1 como dirección de servidor colisionará con cualquier otra cosa de la máquina que use el mismo puerto, por lo que las ejecuciones de prueba en paralelo deberían asignar puertos de forma dinámica.
Las direcciones IPv4 link-local de 169.254.0.0/16 se asignan automáticamente cuando ningún servidor DHCP responde. Ver una en logs de producción casi siempre significa que DHCP falló, no que un cliente esté en una red extraña. En IPv6 el equivalente es fe80::/10 y se comporta distinto: toda interfaz IPv6 tiene una dirección link-local, es necesaria para el descubrimiento de vecinos y no puede usarse sin un índice de zona, porque la misma dirección existe en cada enlace.
| Dirección | Ámbito | ¿Puede salir del host? | Error común |
|---|---|---|---|
| 127.0.0.1 | Loopback IPv4 | No | Asumir que solo esta es loopback |
| 127.0.0.53 | Loopback IPv4 | No | Colisionar con el resolutor local |
| 169.254.1.1 | Link-local IPv4 | Solo el mismo enlace | Tratarla como dirección pública |
| ::1 | Loopback IPv6 | No | Escribir ::1/128 como rango de hosts |
| fe80::1 | Link-local IPv6 | Solo el mismo enlace | Omitir el índice de zona |
Ámbitos IPv6 sin un modelo mental de IPv4
IPv6 no tiene broadcast ni requiere NAT, y sus reglas de ámbito van en el prefijo. La unidifusión global vive actualmente en 2000::/3, que es todo el rango de 2000:: a 3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff. Las direcciones unique local viven en fc00::/7 y convencionalmente se generan desde fd00::/8. Link-local es fe80::/10, y ::1/128 es loopback, con ::/128 como dirección no especificada.
El generador devuelve direcciones en esos cuatro ámbitos. Dos detalles importan para las pruebas: una dirección ULA no es enrutable globalmente y debe tratarse como privada, y una dirección link-local solo tiene sentido con un identificador de zona, por ejemplo fe80::1%eth0. Si tu código almacena una dirección IPv6, guarda la zona por separado en lugar de pegarla al texto, porque el signo de porcentaje en una URL tiene otro significado.
| Ámbito | Prefijo | Enrutable | Ejemplo |
|---|---|---|---|
| Unidifusión global | 2000::/3 | Sí, en principio | 2001:db8::1 |
| Unique local | fc00::/7 | No, privada | fd12:3456::1 |
| Link-local | fe80::/10 | Solo el mismo enlace | fe80::1 |
| Loopback | ::1/128 | No | ::1 |
| Documentación | 2001:db8::/32 | Reservado para docs | 2001:db8::1 |
Direcciones de transición y otras trampas
Las direcciones IPv6 mapeadas de IPv4 tienen la forma ::ffff:192.0.2.1 y aparecen cuando un socket de doble pila informa un par IPv4 como IPv6. No son direcciones IPv6 de uso general, y tratarlas como tales produce errores en limitadores de tasa y reglas de acceso que comparan prefijos. Las direcciones 6to4 de 2002::/16 y las de Teredo de 2001::/32 son mecanismos de transición con su propia estructura; no las generes como si fueran direcciones globales ordinarias.
Otras trampas son más antiguas pero siguen presentes. Un cero inicial en un octeto IPv4, como 010.1.1.1, lo interpretan algunos analizadores como octal y otros lo rechazan, así que nunca lo aceptes en un fixture. La forma abreviada 127.1 la aceptan algunas pilas como 127.0.0.1. Los puertos son un campo aparte y nunca deben concatenarse al valor de la dirección.
- ::ffff:0:0/96 es mapeada de IPv4, no un rango IPv6 normal
- 2001:db8::/32 es espacio de documentación y es el valor seguro por defecto para fixtures
- Rechaza octetos con ceros iniciales en lugar de adivinar la base
- Rechaza formas como 127.1 que dependen de la expansión específica de la pila
- Mantén el puerto fuera del campo de dirección; valídalo como un entero aparte
Construir un conjunto de fixtures que no pueda colisionar
Para pruebas unitarias que nunca abren un socket, usa rangos de documentación: 192.0.2.0/24, 198.51.100.0/24 y 203.0.113.0/24 para IPv4, y 2001:db8::/32 para IPv6. Están reservados precisamente para que los ejemplos y las pruebas no puedan alcanzar un host real. Un analizador debería aceptarlos como direcciones sintácticamente válidas de ámbito público, lo que también los convierte en una buena prueba de la lógica de clasificación.
Para pruebas de integración que sí abren sockets, enlaza a loopback y asigna el puerto desde el sistema operativo en lugar de fijar 8080. Para pruebas que necesitan un par remoto verosímil, usa los rangos de documentación y haz que cualquier cliente se niegue a marcar hacia ellos. Esa combinación te da valores realistas y la garantía firme de que una mala configuración no puede enviar tráfico a un lugar inesperado.
| Necesidad | Usa | Por qué |
|---|---|---|
| Análisis y formato | 192.0.2.0/24, 2001:db8::/32 | Reservados, no pueden alcanzar un host |
| Lógica de ámbito privado | 192.168.0.0/16 | Poco probable que se solape con redes de CI |
| Servidor loopback | 127.0.0.1 con un puerto asignado por el SO | Sin colisiones de puerto fijo |
| Lógica link-local | 169.254.0.0/16 y fe80::/10 | Activa las ramas correctas |
| Clasificación de ámbito | Los cuatro ámbitos en una tabla | Detecta una máscara o prefijo incorrectos |
Validar la salida antes de que llegue a una prueba
Toda dirección generada debería pasar el mismo validador que usa la aplicación. Ese es el objetivo de generarla. Comprueba que la familia coincide con el ámbito solicitado, que la dirección está dentro del bloque esperado y que la forma textual vuelve a analizarse a los mismos bits. Una ida y vuelta detecta errores de compresión de ceros en IPv6, donde 2001:db8:0:0:0:0:0:1 debe normalizarse a 2001:db8::1 y a nada más.
Comprueba también lo que la dirección no es. Un fixture de ámbito privado no debe caer dentro de un bloque público, un fixture loopback debe estar en 127.0.0.0/8 o ser exactamente ::1, y ningún fixture debería ser multicast, broadcast ni la dirección no especificada salvo que la prueba trate explícitamente esos casos. Esas aserciones negativas son baratas y detectan los errores de generador más vergonzosos.
- Ida y vuelta: analizar, formatear, analizar, comparar bits y no cadenas
- Comprobación de familia: el valor se analiza como la versión de IP solicitada
- Comprobación de ámbito: contención en el bloque, no comparación de prefijo de cadena
- Comprobación negativa: no multicast, no broadcast, no no especificada
- Normalización: la salida IPv6 usa la forma comprimida canónica
Preguntas
- IPv4 público, privado, loopback y link-local; IPv6 global, unique local, link-local y loopback. El ámbito se elige explícitamente en lugar de inferirse de la salida.
- No. Ámbito público significa fuera de los bloques privados y de uso especial, no sin asignar. Usa los rangos de documentación 192.0.2.0/24 y 2001:db8::/32 cuando una prueba no deba alcanzar un host real.
- 100.64.0.0/10. No es espacio privado RFC 1918, pero tampoco es enrutable globalmente, así que trátalo como privado en la lógica de clasificación.
- El rango fe80::/10 existe por separado en cada enlace, así que la misma dirección puede referirse a hosts distintos. El identificador de zona, como un signo de porcentaje seguido de un nombre de interfaz, indica a qué enlace te refieres.
- Genera los cuatro ámbitos IPv6 documentados. Las formas mapeadas de IPv4 como ::ffff:192.0.2.1 son una representación de transición y debería manejarlas tu analizador en lugar de usarlas como fixtures ordinarios.
¿Qué ámbitos puede producir el generador?+
¿Es seguro contactar una dirección IP pública generada?+
¿Qué bloque IPv4 es de NAT de nivel de operador?+
¿Por qué mi dirección IPv6 link-local necesita un índice de zona?+
¿Puede el generador crear direcciones IPv6 mapeadas de IPv4?+
Los ejemplos son sintéticos. No utilices una dirección generada para verificaciones de identidad, registro de cuentas ni entregas.