IPv6 es la versión actual del protocolo IP y usa direcciones de 128 bits, lo que elimina la escasez de direcciones de IPv4 y la necesidad de NAT. Cada vez más usuarios acceden a Internet con IPv6, así que un servidor con doble pila (IPv4 e IPv6) llega a más clientes y con mejores rutas. En este tutorial configurarás una dirección IPv6 estática en Ubuntu 24.04 con Netplan, en Rocky Linux 9 con NetworkManager y en Debian 12 con ifupdown, abrirás el firewall, harás que tus servicios escuchen en IPv6 y publicarás el registro DNS AAAA.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS, Rocky Linux 9 o Debian 12, por ejemplo un VPS de CubePath.
  • Un usuario no root con privilegios sudo.
  • Los datos IPv6 que te asigna tu proveedor: la dirección o el prefijo (normalmente un /64) y la puerta de enlace.
  • Acceso por consola (VNC o consola web del panel) por si un error de red corta la sesión SSH.

En los ejemplos se usan direcciones del rango reservado para documentación, 2001:db8::/32. Sustitúyelas por las tuyas:

DatoValor de ejemplo
Interfazeth0
Dirección IPv62001:db8:10::10/64
Puerta de enlace2001:db8:10::1
DNS IPv62606:4700:4700::1111 y 2620:fe::fe

Conceptos básicos de IPv6

Una dirección IPv6 se escribe en ocho grupos de cuatro cifras hexadecimales separados por :. Los ceros a la izquierda de cada grupo se pueden omitir y una sola secuencia de grupos a cero se puede sustituir por ::. Así, 2001:0db8:0010:0000:0000:0000:0000:0010 se escribe 2001:db8:10::10.

Los tipos de dirección que verás en un servidor son:

TipoRangoUso
Global unicast2000::/3Direcciones públicas, enrutables en Internet
Link-localfe80::/10Solo válidas en el enlace local; toda interfaz con IPv6 tiene una
Loopback::1/128Equivale a 127.0.0.1
Unique localfc00::/7Redes privadas, equivalente a 10.0.0.0/8

Las direcciones se asignan de tres formas: estática (la escribes tú), SLAAC (el sistema la construye a partir de los anuncios del router) o DHCPv6. En un servidor lo habitual es la estática, porque la dirección debe ser fija para publicarla en DNS.

Al escribir una dirección IPv6 con puerto, por ejemplo en una URL, va entre corchetes: http://[2001:db8:10::10]:8080/.

Paso 1: Comprobar el soporte de IPv6

Los tres sistemas traen IPv6 activado de serie, pero conviene comprobar que nadie lo ha desactivado. Revisa el parámetro del kernel:

sysctl net.ipv6.conf.all.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 0

Un 0 significa que IPv6 está activo. Si ves un 1, busca dónde se desactiva y elimina esa línea:

grep -r disable_ipv6 /etc/sysctl.conf /etc/sysctl.d/

Después aplica los cambios con sudo sysctl --system. Si el comando sysctl dice que la clave no existe, IPv6 está desactivado desde el arranque con ipv6.disable=1 en /etc/default/grub: quítalo de GRUB_CMDLINE_LINUX, ejecuta sudo update-grub (Ubuntu, Debian) o sudo grub2-mkconfig -o /boot/grub2/grub.cfg (Rocky) y reinicia.

Mira qué direcciones IPv6 tiene ahora la interfaz:

ip -6 address show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 fe80::be24:11ff:fe2a:3b4c/64 scope link
       valid_lft forever preferred_lft forever

Si solo aparece la dirección fe80:: con scope link, la interfaz tiene IPv6 pero todavía no tiene dirección pública. Si ya aparece una con scope global, tu servidor ya está configurado y puedes pasar directamente al paso 5 para verificarlo.

Paso 2: Configurar IPv6 con Netplan (Ubuntu 24.04)

Netplan guarda la red en archivos YAML de /etc/netplan/. Lista los existentes:

ls /etc/netplan/

Si el archivo es 50-cloud-init.yaml, la red la genera cloud-init en cada arranque y tus cambios se perderían. Para gestionar la red a mano, desactiva la configuración de red de cloud-init:

sudo nano /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg
network: {config: disabled}

Abre el archivo de Netplan existente (o crea el tuyo si no hay ninguno) y añade la dirección IPv6 junto a la IPv4 que ya tienes:

sudo nano /etc/netplan/50-cloud-init.yaml
network:
  version: 2
  ethernets:
    eth0:
      dhcp4: false
      dhcp6: false
      accept-ra: false
      addresses:
        - 203.0.113.10/24
        - 2001:db8:10::10/64
      routes:
        - to: default
          via: 203.0.113.1
        - to: "::/0"
          via: "2001:db8:10::1"
      nameservers:
        addresses:
          - 1.1.1.1
          - 2606:4700:4700::1111
          - 2620:fe::fe

Qué hace cada clave relacionada con IPv6:

  • addresses: admite a la vez direcciones IPv4 e IPv6, cada una con su prefijo.
  • routes: la ruta ::/0 es la ruta por defecto de IPv6. Si tu proveedor te da como puerta de enlace una dirección link-local (por ejemplo fe80::1), escríbela tal cual en via.
  • accept-ra: false: ignora los anuncios de router, así el servidor no se añade direcciones o rutas por su cuenta además de las que has fijado. Si tu proveedor usa SLAAC en lugar de direcciones estáticas, elimina accept-ra: false y la dirección IPv6 de addresses.

Restringe los permisos del archivo, valida y aplica con reversión automática:

sudo chmod 600 /etc/netplan/*.yaml
sudo netplan generate
sudo netplan try

Pulsa Enter antes de 120 segundos para confirmar. Como la dirección IPv4 no cambia, la sesión SSH se mantiene.

Comprueba la dirección y la ruta:

ip -6 address show dev eth0 scope global
ip -6 route show default
    inet6 2001:db8:10::10/64 scope global
       valid_lft forever preferred_lft forever
default via 2001:db8:10::1 dev eth0 proto static metric 1024 pref medium

Paso 3: Configurar IPv6 con NetworkManager (Rocky Linux 9)

En Rocky Linux y el resto de la familia RHEL 9 se usa nmcli. Localiza el nombre de la conexión:

nmcli connection show
NAME         UUID                                  TYPE      DEVICE
System eth0  5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03  ethernet  eth0

Configura la dirección, la puerta de enlace y los DNS IPv6, y pasa el método a manual:

sudo nmcli connection modify "System eth0" \
  ipv6.method manual \
  ipv6.addresses 2001:db8:10::10/64 \
  ipv6.gateway 2001:db8:10::1 \
  ipv6.dns "2606:4700:4700::1111 2620:fe::fe"

Si tu proveedor usa SLAAC, usa ipv6.method auto en lugar de indicar dirección y puerta de enlace.

Reactiva la conexión para aplicar los cambios:

sudo nmcli connection up "System eth0"

Comprueba el resultado:

nmcli connection show "System eth0" | grep -E '^ipv6\.(method|addresses|gateway):'
ip -6 route show default
ipv6.method:                            manual
ipv6.addresses:                         2001:db8:10::10/64
ipv6.gateway:                           2001:db8:10::1
default via 2001:db8:10::1 dev eth0 proto static metric 100 pref medium

Paso 4: Configurar IPv6 con ifupdown (Debian 12)

En Debian 12 con ifupdown, IPv6 se configura con un bloque inet6 propio para la interfaz, además del bloque inet de IPv4. Haz una copia de seguridad y abre el archivo:

sudo cp /etc/network/interfaces /etc/network/interfaces.bak
sudo nano /etc/network/interfaces

Añade el bloque inet6 debajo del de IPv4:

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

iface eth0 inet6 static
    address 2001:db8:10::10/64
    gateway 2001:db8:10::1
    accept_ra 0

accept_ra 0 cumple la misma función que accept-ra: false en Netplan. Si tu VPS usa cloud-init, desactiva su gestión de red como en el paso 2 y revisa que la interfaz no esté definida también en /etc/network/interfaces.d/.

Para añadir los DNS IPv6, edita /etc/resolv.conf (o usa dns-nameservers en el bloque si tienes instalado el paquete resolvconf):

nameserver 1.1.1.1
nameserver 2606:4700:4700::1111

Aplica los cambios reiniciando la interfaz en una sola línea, preferiblemente desde la consola del panel:

sudo ifdown eth0 && sudo ifup eth0

Verifica con ip -6 address show dev eth0 scope global como en el paso 2.

Paso 5: Verificar la conectividad IPv6

Primero, que llegas a la puerta de enlace:

ping -6 -c 3 2001:db8:10::1

Después, que sales a Internet por IPv6. El servidor DNS público de Cloudflare es un buen destino:

ping -6 -c 3 2606:4700:4700::1111
PING 2606:4700:4700::1111 (2606:4700:4700::1111) 56 data bytes
64 bytes from 2606:4700:4700::1111: icmp_seq=1 ttl=58 time=1.21 ms
...
3 packets transmitted, 3 received, 0% packet loss, time 2003ms

Comprueba qué dirección ve el exterior cuando conectas por IPv6. Debe ser la que acabas de configurar:

curl -6 https://icanhazip.com
2001:db8:10::10

Por último, verifica que la ruta hacia Internet es correcta:

tracepath -6 cloudflare.com

tracepath viene con el paquete iputils-tracepath en Ubuntu y Debian y con iputils en Rocky. Si no está instalado, usa sudo apt install iputils-tracepath o sudo dnf install iputils.

Paso 6: Permitir IPv6 en el firewall

En Ubuntu y Debian, UFW aplica las reglas a IPv4 e IPv6 siempre que IPV6=yes esté activo en su configuración, que es el valor por defecto. Compruébalo:

grep IPV6 /etc/default/ufw
IPV6=yes

Cada regla que añadas aparecerá dos veces, una con (v6):

sudo ufw allow 80/tcp
sudo ufw status
To                         Action      From
--                         ------      ----
80/tcp                     ALLOW       Anywhere
80/tcp (v6)                ALLOW       Anywhere (v6)

Si cambias IPV6 de no a yes, recarga el firewall con sudo ufw reload.

En Rocky Linux, firewalld aplica las mismas zonas a ambos protocolos, así que no hay que hacer nada especial:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload

Paso 7: Escuchar en IPv6 y publicar el registro AAAA

Tener dirección IPv6 no sirve de nada si tus servicios solo escuchan en IPv4. Revisa en qué direcciones escucha cada servicio:

sudo ss -tlnp
State   Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
LISTEN  0       511     0.0.0.0:80          0.0.0.0:*          users:(("nginx",...))
LISTEN  0       511     [::]:80             [::]:*             users:(("nginx",...))
LISTEN  0       128     [::]:22             [::]:*             users:(("sshd",...))

Una línea con [::] indica que el servicio acepta conexiones IPv6. SSH escucha en IPv6 por defecto. En Nginx, cada bloque server necesita su propia directiva de escucha IPv6:

server {
    listen 80;
    listen [::]:80;
    server_name your_domain;
    ...
}

Después, en el proveedor DNS de tu dominio, crea un registro AAAA para your_domain que apunte a tu dirección IPv6, igual que el registro A apunta a la IPv4. Cuando se propague, compruébalo:

dig +short AAAA your_domain
2001:db8:10::10

Y prueba el servicio completo desde el propio servidor o desde otra máquina con IPv6:

curl -6 -I http://your_domain

Solución de problemas

La dirección aparece como tentative o dadfailed

tentative dura un par de segundos mientras el kernel comprueba que nadie más usa la dirección (Duplicate Address Detection). Si pasa a dadfailed, otra máquina del segmento ya tiene esa dirección: elige otra o revisa la asignación con tu proveedor.

Tengo dirección global pero ping -6 a Internet falla

Comprueba que existe la ruta por defecto con ip -6 route show default. Si falta, revisa la puerta de enlace; si la puerta de enlace no está dentro de tu prefijo, necesitas on-link: true en Netplan. Prueba también ping -6 -c 3 2001:db8:10::1 para descartar un fallo en el enlace.

La conexión funciona un tiempo y después aparecen direcciones o rutas extra

El servidor está aceptando anuncios de router. Desactívalos con accept-ra: false (Netplan), accept_ra 0 (ifupdown) o fija ipv6.method manual (nmcli).

La web carga por IPv4 pero no por IPv6

Revisa con sudo ss -tlnp que el servicio escucha en [::], que el firewall muestra la regla (v6) y que el registro AAAA apunta a la dirección correcta. Un registro AAAA incorrecto es peor que no tenerlo, porque los clientes con IPv6 lo intentarán primero.

Conclusión

Has activado IPv6 en tu servidor con la herramienta de red de cada distribución, has comprobado la conectividad, has abierto el firewall para ambos protocolos y has publicado tus servicios con un registro AAAA. Como siguientes pasos, configura el DNS inverso (PTR) de tu dirección IPv6, especialmente si el servidor envía correo, y revisa que los servicios que solo deben ser internos no queden expuestos ahora por IPv6.