Configurar una dirección IP estática en Debian y Ubuntu

Publicado el 14 min de lectura

Direcciones IPv4 e IPv6 fijas en Ubuntu 24.04, Ubuntu 22.04, Debian 13 y Debian 12: netplan, ifupdown y systemd-networkd comparados, con estrategia de vuelta atrás e IP adicionales.

Cuatro datos sin los que no deberías empezar

Una dirección estática se anota en un momento. Que aun así tantos servidores se queden mudos después del reinicio casi nunca se debe a la sintaxis, sino a que uno de los cuatro datos básicos se adivinó en lugar de leerse: el nombre de la interfaz, la dirección con su longitud de prefijo, el gateway y los servidores de nombres. Consulta esos valores con el sistema en marcha, mientras la máquina siga siendo accesible.

ip -brief address show
ip -4 route show
ip -6 route show
cat /etc/resolv.conf

La primera línea te da el nombre de la interfaz. En servidores virtuales se llama ens3, enp1s0 o eth0 según la plataforma, y en bare metal suele ser eno1. Copia el nombre tal cual, no lo adivines. Una errata en este punto produce una configuración impecable desde el punto de vista sintáctico que sencillamente no corresponde a ninguna tarjeta existente.

La longitud de prefijo merece atención especial. Muchos proveedores enrutan una única dirección IPv4 con /32 hacia el servidor, y entonces el gateway queda fuera de la propia subred. Otros asignan redes /24 clásicas. Cuál de los dos casos tienes delante lo revela la ruta que se usa realmente:

ip route get 1.1.1.1

Después crea un backup. Cuesta diez segundos y es la diferencia entre una vuelta atrás y un ticket.

cp -a /etc/netplan /root/netplan.bak
cp -a /etc/network/interfaces /root/interfaces.bak

¿Qué sistema controla ahora mismo tu red?

Debian y Ubuntu usan herramientas distintas, y la caída total más frecuente aparece cuando dos de ellas configuran la misma interfaz a la vez. Aclara primero cuál está al mando:

ls -l /etc/netplan/
ls -l /etc/network/interfaces /etc/network/interfaces.d/
ls -l /etc/systemd/network/

La regla general para las cuatro versiones actuales: Ubuntu 24.04 y Ubuntu 22.04 se configuran mediante netplan, que por debajo gobierna systemd-networkd. Debian 13 y Debian 12 llegan, tras una instalación estándar, con ifupdown y el archivo /etc/network/interfaces. systemd-networkd está presente en Debian, pero no activo, y netplan se puede instalar allí después, aunque no es el camino previsto.

En las imágenes cloud se suma una capa más: cloud-init escribe en el primer arranque su propio archivo, normalmente /etc/netplan/50-cloud-init.yaml o, en Debian, un bloque dentro de /etc/network/interfaces.d/. Si editas ese archivo sin frenar antes a cloud-init, en el siguiente reinicio vuelves a encontrarte la configuración antigua.

Ubuntu 24.04 y 22.04: dirección estática con netplan

netplan lee todos los archivos de /etc/netplan/ en orden alfabético y los traduce a configuración para systemd-networkd. No crees un segundo archivo con la misma interfaz: edita el que ya existe o desactiva el antiguo de forma limpia. Una configuración completa con IPv4 e IPv6 tiene este aspecto:

network:
  version: 2
  renderer: networkd
  ethernets:
    ens3:
      dhcp4: false
      dhcp6: false
      accept-ra: false
      addresses:
        - 203.0.113.10/24
        - "2001:db8:1234::2/64"
      routes:
        - to: default
          via: 203.0.113.1
        - to: default
          via: "2001:db8:1234::1"
      nameservers:
        addresses: [9.9.9.9, 149.112.112.112, 2620:fe::fe]

Tres detalles de ahí merecen una explicación por separado.

Primero, las rutas por defecto van bajo routes y ya no bajo gateway4 o gateway6. Esas dos claves están obsoletas desde netplan 0.103. En Ubuntu 22.04 y 24.04 siguen funcionando, pero responden a cada invocación con `gateway4` has been deprecated, use default routes instead. Quien escriba configuración nueva, que escriba rutas.

Segundo, accept-ra: false desactiva la configuración automática de IPv6. Si la dejas activa mientras asignas al mismo tiempo una dirección fija, la interfaz acaba con dos direcciones y dos rutas por defecto, y cuál de ellas gana lo decide la métrica, no tu intención.

Tercero, los permisos del archivo. Desde netplan 0.106, cada invocación avisa si el archivo YAML es legible por otros usuarios: Permissions for /etc/netplan/01-static.yaml are too open. Netplan configuration should NOT be accessible by others. No es cosmética, porque en esos archivos también hay claves de wifi y datos de túneles.

chmod 600 /etc/netplan/*.yaml

Cuando el gateway queda fuera de la propia subred

Con una dirección enrutada de forma individual con /32, el kernel no conoce ningún camino directo hacia el gateway y rechaza la ruta. En el journal aparece entonces Could not set route: Network is unreachable, y en el intento manual con ip route add la respuesta es RTNETLINK answers: Network is unreachable. La solución se llama on-link:

      addresses:
        - 203.0.113.10/32
      routes:
        - to: default
          via: 192.0.2.1
          on-link: true

En IPv6, el caso especial es la norma: muchas redes indican como gateway la dirección link-local fe80::1. Como netplan asocia siempre las rutas a una interfaz, basta con via: "fe80::1" dentro del bloque de la tarjeta correspondiente.

Silenciar cloud-init

Si en el directorio hay un 50-cloud-init.yaml, deja además puesto un bloqueo; de lo contrario, tu trabajo se sobrescribe en el siguiente arranque:

echo 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

netplan try: el comando que no te deja fuera

El orden es comprobar, probar y fijar. netplan generate traduce los archivos YAML sin activar nada y avisa de los errores de sintaxis al instante. Solo después llega la prueba de verdad.

netplan generate
netplan try --timeout 120
netplan apply

netplan try aplica la configuración nueva y restaura la antigua de forma automática si no pulsas Intro dentro del plazo. El valor por defecto son 120 segundos. Esa es justo la razón por la que en un servidor remoto nunca se empieza con netplan apply: una errata en la dirección del gateway termina con tu sesión SSH y, sin red de seguridad, la cosa acaba en la consola o en una reinstalación.

No confíes a ciegas en la reversión. Hay casos documentados en los que netplan try, tras agotarse el plazo, no restableció la conexión, sobre todo al editar el archivo generado por cloud-init. Después de una vuelta atrás, comprueba siempre si el archivo en disco está realmente otra vez en su estado anterior.

Para todo lo que netplan try no cubre (y para Debian con ifupdown, donde ese comando ni siquiera existe), hay un segundo cinturón de seguridad que da buen resultado: una tarea de rescate que restaure el backup si no das señales de vida a tiempo.

nohup sh -c 'sleep 300; cp -a /root/netplan.bak/. /etc/netplan/; netplan apply' >/dev/null 2>&1 &

Apunta el número de proceso que aparece en la salida. Si todo funciona, termina la tarea con kill. Si ya no consigues entrar, el sistema se repara solo en cinco minutos. Trabaja además dentro de tmux o screen, para que una sesión SSH que se corte no se lleve por delante tu editor en mitad del cambio.

En los servidores root KVM queda como última instancia la consola del área de cliente, con la que llegas al sistema incluso sin red operativa. En las máquinas dedicadas, el camino de vuelta es bastante más laborioso, así que allí la rutina de precaución cuenta el doble.

Debian 13 y 12 con /etc/network/interfaces

Tras una instalación estándar, quien gobierna la red es ifupdown. La configuración va orientada a líneas y usa bloques separados por familia de direcciones:

auto lo
iface lo inet loopback

auto ens3
iface ens3 inet static
    address 203.0.113.10/24
    gateway 203.0.113.1

iface ens3 inet6 static
    address 2001:db8:1234::2/64
    gateway 2001:db8:1234::1
    accept_ra 0

El auto ens3 vale para ambos bloques, no necesitas una segunda línea auto. Si el gateway queda fuera de la subred, sirve la misma idea que en netplan, solo que formulada a mano:

iface ens3 inet static
    address 203.0.113.10/32
    post-up ip route add 192.0.2.1 dev ens3
    post-up ip route add default via 192.0.2.1
    pre-down ip route del default via 192.0.2.1

La mayor trampa en Debian no es la sintaxis, sino la activación. systemctl restart networking baja la interfaz un momento y, si la configuración nueva no aguanta, la sesión desaparece. ifdown ens3 && ifup ens3 es todavía más delicado, porque el ifup no llega a ejecutarse nunca en cuanto la conexión se corta ya durante el ifdown. Así que crea antes la tarea de rescate descrita más arriba y ejecuta luego:

systemctl restart networking
systemctl status networking

Aquí te vas a cruzar con dos mensajes de forma habitual. ifup: interface ens3 already configured significa que ifupdown sigue contando la interfaz como activa, aunque quizá ya no lo esté; el estado está en /run/network/ifstate. Y Job for networking.service failed because the control process exited with error code es solo la cáscara: el motivo real está en journalctl -xeu networking, casi siempre una ruta por defecto asignada dos veces con RTNETLINK answers: File exists.

DNS con ifupdown

La línea evidente dns-nameservers 9.9.9.9 dentro del archivo solo surte efecto si hay instalado un intermediario que la traslade a /etc/resolv.conf, clásicamente el paquete resolvconf. Sin ese intermediario, la entrada no tiene consecuencia alguna, y eso no se nota hasta que los nombres dejan de resolverse: Temporary failure in name resolution. Si no quieres instalar nada adicional, mantén /etc/resolv.conf directamente y comprueba con ls -l /etc/resolv.conf si el archivo es un symlink, es decir, si lo gestiona otro servicio.

Usar Debian con systemd-networkd

Si en un servidor Debian ya utilizas herramientas de systemd de todos modos, o si administras muchas interfaces y túneles, con systemd-networkd todo queda más coherente. El cambio consta de tres pasos: crear la configuración, activar el servicio nuevo y retirar el antiguo.

[Match]
Name=ens3

[Network]
Address=203.0.113.10/24
Address=2001:db8:1234::2/64
Gateway=203.0.113.1
Gateway=2001:db8:1234::1
DNS=9.9.9.9
DNS=2620:fe::fe
IPv6AcceptRA=no

Este archivo va en /etc/systemd/network/10-ens3.network. Para un gateway fuera de la subred, añades un bloque de ruta propio:

[Route]
Gateway=192.0.2.1
GatewayOnLink=yes

Después viene el cambio, mejor otra vez con la tarea de rescate cubriéndote las espaldas:

systemctl enable --now systemd-networkd
systemctl disable networking
networkctl status ens3

La salida de networkctl status es la respuesta más sincera que ofrece este tema. Si allí pone State: routable (configured), el servicio aceptó el archivo y lo aplicó. Si pone configuring o degraded, lo intentó y fracasó, al margen de que el comando de arranque volviera sin errores.

La parte de DNS va por libre en Debian: systemd-networkd solo introduce servidores de nombres en la resolución si systemd-resolved está en marcha y /etc/resolv.conf apunta a su archivo.

apt-cache policy systemd-resolved

Esta consulta depende de la versión y engaña de una forma poco llamativa. Un paquete propio llamado systemd-resolved solo existe a partir de Debian 12 y Ubuntu 24.04, y allí el comando indica una versión. En Ubuntu 22.04, en cambio, el servicio sigue dentro del propio paquete systemd, y ahí el comando se ejecuta sin errores, pero no muestra absolutamente nada. Una instalación falla en consecuencia con Unable to locate package systemd-resolved. Es decir, la salida vacía no significa que falte el resolver, sino que en esa versión el paquete no existe. En sistemas más antiguos, como Debian 11, ocurre exactamente lo mismo. En esas versiones comprueba mejor lo siguiente:

apt-cache policy systemd
systemctl status systemd-resolved

El servicio se activa con systemctl enable --now systemd-resolved, y a continuación el symlink habitual apunta a /run/systemd/resolve/stub-resolv.conf. Si prefieres evitarlo, deja systemd-resolved a un lado y escribe los servidores de nombres de forma estática en /etc/resolv.conf. Lo que no deberías hacer: las dos cosas a medias.

Añadir direcciones IP adicionales

Las direcciones adicionales no son un caso especial, sino simplemente una entrada más. En netplan, la lista crece:

      addresses:
        - 203.0.113.10/24
        - 203.0.113.11/24
        - 203.0.113.12/24
        - "2001:db8:1234::2/64"
        - "2001:db8:1234::3/64"

En systemd-networkd escribes varias líneas Address= una debajo de otra. En ifupdown amplías la definición existente en lugar de crear una segunda:

iface ens3 inet static
    address 203.0.113.10/24
    gateway 203.0.113.1
    post-up ip addr add 203.0.113.11/24 dev ens3
    post-up ip addr add 203.0.113.12/24 dev ens3
    pre-down ip addr del 203.0.113.11/24 dev ens3
    pre-down ip addr del 203.0.113.12/24 dev ens3

La notación antigua con ens3:0 sigue funcionando, pero es una reliquia de la época anterior a la herramienta ip. No crea dispositivos adicionales de verdad, solo etiquetas, y en las reglas del firewall genera más confusión de la que aporta.

Con las direcciones adicionales suelen torcerse tres cosas. Primero, que la dirección no esté asignada del lado del servidor: ninguna configuración de sistema operativo del mundo pone en marcha una IP que no esté enrutada hacia tu servidor, así que mirar el área de cliente es el primer paso y no el último. Segundo, que a una segunda dirección de la misma red no le corresponde una segunda ruta por defecto: una segunda entrada de gateway predeterminado te regala un RTNETLINK answers: File exists o, peor todavía, caminos de respuesta cambiantes. Tercero, en IPv6 casi siempre se cumple que el /64 completo está enrutado hacia el servidor, de modo que puedes elegir libremente dentro de ese rango, pero solo la dirección indicada por el proveedor se necesita realmente como dirección de interfaz configurada.

Si una dirección adicional sale de verdad hacia fuera, lo compruebas de forma dirigida a través del punto de origen:

ping -c 3 -I 203.0.113.11 1.1.1.1

Cómo saber que ha quedado bien de verdad

Que un comando termine sin mensaje de error dice poco sobre el estado de la red. Estas cinco comprobaciones sí dicen algo:

  1. La dirección está en la interfaz correcta: ip -brief address show muestra exactamente las direcciones deseadas y ningún resto de la configuración antigua.
  2. El camino hacia fuera es correcto, dirección de origen incluida: ip route get 1.1.1.1 indica el gateway esperado y el src esperado.
  3. IPv6 tiene su propia ruta por defecto: ip -6 route show default no puede quedar vacío, o si no todo pasa en silencio por IPv4.
  4. La resolución de nombres funciona con independencia de la accesibilidad: getent hosts deb.debian.org devuelve una dirección y no solo silencio.
  5. La única prueba real es un reinicio. Solo después sabes si la configuración viene del archivo o todavía de la RAM.

En Ubuntu, netplan status --all saca además un resumen compacto, y en systemd-networkd networkctl status hace lo mismo. En caso de duda, ambos revelan que una dirección figura en el archivo, pero nunca llegó a aplicarse.

Mensajes de error al pie de la letra

MensajeCausa y solución
Invalid YAML at /etc/netplan/01-static.yaml line 6 column 8: did not find expected keyUn tabulador en lugar de espacios o una indentación descolocada. YAML no permite tabuladores, usa dos espacios por nivel.
Error in network definition: unknown key 'gateway'En netplan la clave no se llama gateway. Escribe una entrada bajo routes con to: default.
`gateway4` has been deprecated, use default routes insteadSolo es un aviso, la configuración sigue surtiendo efecto. Aun así, pásate a routes.
Permissions for /etc/netplan/… are too openAplica chmod 600 al archivo YAML.
RTNETLINK answers: Network is unreachableEl gateway queda fuera de la subred configurada. Pon on-link: true o bien GatewayOnLink=yes, o corrige la longitud de prefijo.
RTNETLINK answers: File existsLa dirección o la ruta ya existe, casi siempre porque dos sistemas de configuración trabajan a la vez.
Error: Cannot find device "eth0"La interfaz se llama de otra forma. Consulta el nombre con ip -brief link show.
Temporary failure in name resolutionEl enrutamiento está en pie, el DNS no. Revisa /etc/resolv.conf y averigua qué servicio escribe ese archivo.
ifup: interface ens3 already configuredifupdown considera activa la interfaz. Comprueba el estado en /run/network/ifstate.

Las cuatro distribuciones cara a cara

Debian 12Debian 13Ubuntu 22.04Ubuntu 24.04
Herramienta por defectoifupdownifupdownnetplannetplan
Archivo principal/etc/network/interfaces/etc/network/interfaces/etc/netplan/*.yaml/etc/netplan/*.yaml
Alternativasystemd-networkdsystemd-networkdsystemd-networkd directosystemd-networkd directo
Prueba sin quedarte fueratarea de rescate propiatarea de rescate propianetplan trynetplan try
systemd-resolvedpaquete propio, inactivopaquete propio, inactivoparte de systemdpaquete propio, activo
Aviso de permisos de netplanno aplicano aplicadesde 0.106

Si pones el firewall en marcha justo después de configurar la red, ten en cuenta que las reglas para la dirección nueva y para IPv6 se aplican por separado. Cómo montarlo de forma limpia lo explicamos en nuestra guía sobre UFW en Debian y Ubuntu, y cómo asegurar el acceso después, en proteger un servidor SSH.

Resumen para el próximo servidor

Leer los valores en vez de adivinarlos, crear un backup, escribir la configuración, probar con netplan try o con una tarea de rescate propia, fijar el cambio, reiniciar y solo entonces darlo por cerrado. Quien respete este orden pierde, en el peor de los casos, cinco minutos. Quien lo acorte pierde, en el peor de los casos, el servidor hasta que alguien se siente delante de la consola.

Preguntas frecuentes

¿Por qué mi servidor ya no responde después de netplan apply?
Casi siempre el gateway no es correcto o la longitud de prefijo no encaja con la red. Por eso, en sistemas remotos conviene usar primero netplan try, que restaura la configuración anterior de forma automática al cabo de 120 segundos si nadie pulsa Intro. Si ya ha ocurrido, en los servidores root KVM te saca del apuro la consola del área de cliente.
¿Debian 13 usa netplan?
No. Debian 13 sigue configurando la red, tras una instalación estándar, mediante ifupdown y /etc/network/interfaces. netplan se puede instalar desde los repositorios, pero en Debian no es el camino previsto y añade un paso de traducción más. Como alternativa cercana al sistema está systemd-networkd.
¿Qué sustituye a gateway4 en netplan?
Una entrada bajo routes con to: default y via: dirección del gateway. gateway4 y gateway6 están obsoletos desde netplan 0.103 y generan el aviso de que conviene usar rutas por defecto en su lugar. En Ubuntu 22.04 y 24.04 las claves antiguas todavía funcionan, pero deberías sustituirlas en cada revisión.
¿Por qué se sobrescribe una y otra vez mi /etc/resolv.conf?
Porque hay un servicio que la gestiona: systemd-resolved, resolvconf o cloud-init. Comprueba con ls -l /etc/resolv.conf si el archivo es un symlink. O bien anotas los servidores de nombres allí donde los espera el servicio correspondiente, o bien desactivas el servicio y mantienes el archivo de forma estática. Hacer las dos cosas a medias acaba en caídas después del reinicio.
¿Cómo añado una dirección IP adicional?
En netplan, como una entrada más en la lista addresses; en systemd-networkd, como una línea Address= adicional; en ifupdown, mediante post-up ip addr add. Lo importante es que no aparezca una segunda ruta por defecto y que la dirección esté realmente enrutada hacia el servidor del lado del proveedor. Eso se comprueba en el área de cliente, antes de ponerse a buscar en el sistema operativo.
Mi gateway queda fuera de la subred, ¿qué hago?
Es lo habitual con direcciones enrutadas de forma individual con /32. En netplan se pone on-link: true en la ruta por defecto; en systemd-networkd, GatewayOnLink=yes en el bloque de ruta; en ifupdown se crea primero, con post-up, una ruta de host hacia el gateway. Sin ese paso, el kernel avisa con Network is unreachable.

Debian Ubuntu netplan systemd-networkd Redes IPv6 Administración de Linux Servidor root