Quien administre Linux desde hace tiempo se ha topado con el truco: escribir 10.68
y llegar a 10.0.0.68
, o teclear 10.20.2
y alcanzar 10.20.0.2
. En un laboratorio ahorra pulsaciones; en producción puede convertirse en un dolor de cabeza. Este medio explica por qué funciona, dónde funciona, dónde dejará de funcionar y cómo gestionarlo de forma responsable en entornos Linux modernos.
No es brujería, es “parsing” heredado
El comportamiento nace de las APIs históricas de sockets IPv4 (familia inet_
), que aceptaban formatos abreviados además del clásico “dotted quad” (a.b.c.d
). Muchas herramientas Unix (y derivados) se construyeron sobre esas APIs, y de ahí la compatibilidad:
a.b.c
→ el último campoc
ocupa 16 bits (dos octetos).10.20.2
≡10.20.0.2
.a.b
→ el último campob
ocupa 24 bits (tres octetos).10.68
≡10.0.0.68
.a
(un entero) → 32 bits completos.167772161
≡10.0.0.1
.
Cuando faltan octetos, se rellenan por la izquierda con ceros dentro del bloque de 16/24/32 bits. De ahí que ping 10.68
funcione y termine en 10.0.0.68
, como muestra la captura de muchos laboratorios.
¿Dónde sigue funcionando en Linux?
Depende del binario y de qué API usa:
- Herramientas clásicas (
ping
,telnet
,ssh
, algunoscurl
compilados con resolutores tolerantes) suelen aceptar abreviados gracias a funciones comoinet_aton()
/inet_addr()
. - Utilidades y librerías más modernas que usan
getaddrinfo()
+inet_pton()
suelen exigir el formatoa.b.c.d
o un FQDN. Muchos SDKs y runtimes (Go, Rust, Pythonipaddress
, Java moderno) son estrictos. - Navegadores y clientes HTTP endurecieron parsing en los últimos años; algunos rechazan abreviados por motivos de seguridad.
Consecuencia: lo que funciona en una TTY puede fallar en otra herramienta, contenedor o pipeline. Para un sysadmin, esa inconsistencia es el problema.

Los “peros” que conviene conocer (y documentar)
1) Ceros a la izquierda, octal y hexadecimal: campo minado
Muchos parsers legacy interpretan:
010
como octal →8
.0x10
como hex →16
.
Eso ha originado bypass reales en WAF/SSRF y confusiones en ACLs. Ejemplo: 010.000.000.001
puede acabar resolviendo a 8.0.0.1
. Regla de oro: evitar ceros a la izquierda y bases no decimales.
2) No vale para todo
- CIDR, rutas y máscaras no aceptan abreviados:
10.0.0.0/24
debe escribirse completo. - Documentación, tickets, inventario, ACLs, firewalls: mezclar abreviados genera ambigüedad y deuda técnica.
- Logs y auditoría: normalizar siempre a cuatro octetos.
3) Seguridad operativa
Un atacante puede aprovechar divergencias de parsing entre componentes (proxy estricto vs. backend permisivo) para escapar validaciones. Evitar la superficie de ataque pasa por unificar representaciones.
Guía de buenas prácticas para equipos Linux
Producción: formato canónico o nada
- Siempre
a.b.c.d
en configuración (systemd-networkd, NetworkManager,iproute2
,nftables
,keepalived
,bird
,FRR
…). - Sin ceros a la izquierda (
10.0.0.1
, no010.000.000.001
). - Evitar abreviados en scripts, playbooks y plantillas (Ansible, Terraform, Helm).
Normalización automática (pre-commit / CI)
Integra un chequeo sencillo que rechace direcciones no canónicas en cambios de red:
# detecta IPs no canónicas (aprox.)
grep -RhoE '\b([0-9]+(\.[0-9]+){0,3})\b' ./configs \
| awk '
function valid(o){return (o>=0 && o<=255)}
{
n=split($0,a,".");
if (n!=4) { print "Non-canonical:", $0; next }
for (i=1;i<=4;i++) if (!valid(a[i])) bad=1;
if (bad) print "Out of range:", $0
}'
Lenguaje del código: PHP (php)
O utiliza parsers robustos:
# Canonicalizador simple (Python 3)
import ipaddress, sys
for line in sys.stdin:
for tok in line.split():
try:
ip = ipaddress.IPv4Address(tok)
print(str(ip))
except:
pass
Lenguaje del código: PHP (php)
Comprobación y “linter” en vivo
getent ahosts 10.68
te mostrará a qué IP resuelve tu glibc.python - <<'PY'\nimport ipaddress; print(ipaddress.ip_address("10.68"))\nPY
fallará (estricto), útil para detectar abreviados que se cuelan.ipcalc 10.68
te obliga a escribir completo; buena prueba para pipelines.
Documenta el comportamiento en tus “Runbooks”
Incluye una nota operativa: “En CLI se permiten abreviados por compatibilidad; la forma válida en este entorno es a.b.c.d
”. Evita que un miembro nuevo del equipo “optimice” con abreviados en un playbook.
“Cheat sheet” didáctico (por si necesitas explicarlo al equipo)
a.b.c
c
ocupa 16 bits:10.20.2
→10.20.(2>>8).(2&255)
→10.20.0.2
a.b
b
ocupa 24 bits:10.68
→10.(68>>16).((68>>8)&255).(68&255)
→10.0.0.68
a
(entero de 32 bits)(a>>24).((a>>16)&255).((a>>8)&255).(a&255)
Úsalo para didáctica interna, no para justificar su uso en producción.
Herramientas Linux: quién es estricto y quién no (panorama típico)
- Tolerantes (depende build):
ping
/ping6
(iputils),ssh
(OpenSSH),nc
tradicional, algunoscurl
/wget
según resolutor. - Estrictos: parsers de Go (
net.ParseIP
), Rust (std::net
/ipnet
), Python (ipaddress
), systemd en varias unidades, muchos SDK cloud y APIs web modernas, iptables/nftables (en reglas esperana.b.c.d
), navegadores.
Este listado puede variar por distro, versión y flags de compilación. Lo importante es no asumir homogeneidad.
Ejemplos útiles para formación interna
Mostrar el “engaño” de ceros a la izquierda (octal)
# En sistemas con inet_legacy:
ping -c1 010.000.000.001 # puede ir a 8.0.0.1 (¡peligro!)
# En herramientas estrictas:
python3 - <<'PY'
import ipaddress
try: print(ipaddress.ip_address('010.000.000.001'))
except Exception as e: print("Error:", e)
PY
Lenguaje del código: PHP (php)
Normalizar listas de hosts heredadas
# hosts.txt con IPs mezcladas
awk '{for(i=1;i<=NF;i++) if ($i ~ /^[0-9.]+$/) print $i}' hosts.txt \
| while read ip; do
python3 - "$ip" <<'PY'
import sys, ipaddress
try:
print(ipaddress.ip_address(sys.argv[1]))
except:
print("INVALID:", sys.argv[1])
PY
done | sort -u
Lenguaje del código: PHP (php)
Política recomendada del equipo de redes/SRE
- Formato canónico obligatorio en repos de config, CMDB e infraestructura como código.
- Bloqueo CI ante direcciones no canónicas o con ceros a la izquierda.
- Conversión automática de inventarios heredados con herramientas de normalización.
- Runbooks actualizados: cuándo un abreviado puede aparecer (CLI puntual en laboratorio) y por qué no se acepta en PRs.
- Pruebas de seguridad: añade casos de IP abreviadas/octales/hex a test de WAF/SSRF y validadores de entradas.
¿Y en IPv6?
Otra historia. IPv6 sí admite compresión, pero con reglas distintas (::
, supresión de ceros a la izquierda en cada hexteto, una sola ::
por dirección, etc.). No mezclar compresión IPv6 con abreviados “legacy” de IPv4: son mundos separados.
Conclusión
La compatibilidad con direcciones IPv4 abreviadas es un artefacto histórico útil en laboratorio que puede romper supuestos en producción. Un equipo Linux profesional debería:
- Conocer por qué
10.68
llega a10.0.0.68
. - Evitarlo en todo lo que toque configuración, automatización, documentación y seguridad.
- Normalizar y validar de forma sistemática en CI/CD.
- Formar al equipo sobre ceros a la izquierda, octal y hexadecimal.
Ahorra pulsaciones donde no importe; evita sorpresas donde sí.
Preguntas frecuentes (FAQ)
¿Cómo convertir direcciones IPv4 abreviadas a formato canónico en un script?
Usa parsers estrictos. En Python: ipaddress.IPv4Address('10.68')
falla (útil para detectar), pero puedes escribir una pequeña función que expanda a.b
→ a.0.0.b
y a.b.c
→ a.b.(c>>8).(c&255)
antes de validar y emitir a.b.c.d
.
¿Puedo usar IP abreviadas en reglas de iptables
/nftables
o en ip route
?
No es recomendable (y a menudo no funciona). Los motores esperan el dotted quad canónico. Mantén 10.0.0.68/32
, no 10.68/32
.
¿Por qué curl
acepta 10.68
en un servidor y lo rechaza en otro?
Probablemente porque está compilado con diferentes resolutores o versiones de glibc/libcURL. No confíes en que el comportamiento sea igual entre distros, contenedores o imágenes base.
¿Cómo detectar en mis repos si alguien coló una IP no canónica?
Añade un pre-commit o un job de CI que busque tokens ^[0-9.]+$
, descarte verdaderos a.b.c.d
y marque el resto como no canónico. Complementa con una pasada de ipaddress
en Python para validar rango (0–255) y rechazar ceros a la izquierda.
Did you know you can actually drop zeros in an IP address and it still works.
— sysxplore (@sysxplore) October 12, 2025
For example:
10.20.0.2 → 10.20.2
10.0.0.68 → 10.68
Both reach the same host.
It’s one of those neat little IP quirks I use in labs , saves me a few keystrokes every time 😅 pic.twitter.com/rXEooe7zkU