--- title: "Cómo configurar un túnel GRE en Ubuntu 24.04" description: "Crea un túnel GRE entre dos servidores Ubuntu 24.04: interfaz, rutas entre redes, MTU y MSS correctos, persistencia con Netplan y cifrado con IPsec strongSwan." category: "Redes Avanzadas" language: es source: https://cubepath.com/es/docs/redes-avanzadas/configuracion-de-tunel-gre-en-linux updated: 2026-09-25 --- # Cómo configurar un túnel GRE en Ubuntu 24.04 GRE (Generic Routing Encapsulation) es un protocolo de túnel sin estado que encapsula paquetes IP dentro de otros paquetes IP. Es muy sencillo, lo soporta prácticamente cualquier router o firewall y se usa para unir redes entre sedes, transportar protocolos de enrutamiento como OSPF o BGP y conectar con equipos de red de terceros. En este tutorial crearás un túnel GRE entre dos servidores Ubuntu 24.04, enrutarás una red a través de él, ajustarás la MTU, lo harás persistente con Netplan y, al final, lo cifrarás con IPsec. ## Requisitos previos - Dos servidores con Ubuntu 24.04 LTS con IP públicas fijas, por ejemplo VPS de CubePath. - Un usuario no root con privilegios `sudo` en ambos. - Que el protocolo IP 47 (GRE) pueda circular entre los dos servidores. GRE no es TCP ni UDP, así que algunos firewalls y NAT lo bloquean aunque tengan los puertos abiertos. El tutorial usa estos valores de ejemplo: | | Host A | Host B | |---|---|---| | IP pública | `203.0.113.10` | `203.0.113.20` | | IP del túnel | `10.10.0.1/30` | `10.10.0.2/30` | | Red local detrás del host | `10.0.1.0/24` | `10.0.2.0/24` | > Advertencia: GRE no cifra ni autentica el tráfico. Cualquiera que vea los paquetes entre los dos servidores puede leerlos. Si el túnel cruza Internet, completa el paso 6 o usa WireGuard en su lugar. ## Paso 1: Cargar el módulo y abrir el firewall Carga el módulo GRE del kernel en ambos hosts: ```bash sudo modprobe ip_gre lsmod | grep gre ``` ```output ip_gre 32768 0 ip_tunnel 36864 1 ip_gre gre 12288 1 ip_gre ``` Al cargarse, el módulo crea una interfaz llamada `gre0`. Es un dispositivo interno del kernel que recibe el GRE que no corresponde a ningún túnel, así que no la uses: este tutorial llama `gre1` al túnel. Si usas UFW, permite el protocolo GRE solo desde el otro host. En el **host A**: ```bash sudo ufw allow proto gre from 203.0.113.20 to any ``` En el **host B**: ```bash sudo ufw allow proto gre from 203.0.113.10 to any ``` ## Paso 2: Crear el túnel En el **host A**, crea la interfaz del túnel indicando los dos extremos. `ttl 255` evita que el TTL del paquete interior se copie al exterior, lo que rompería el túnel si el paquete original llega con un TTL bajo: ```bash sudo ip tunnel add gre1 mode gre local 203.0.113.10 remote 203.0.113.20 ttl 255 sudo ip link set gre1 mtu 1476 up sudo ip addr add 10.10.0.1/30 dev gre1 ``` En el **host B**, con los extremos intercambiados: ```bash sudo ip tunnel add gre1 mode gre local 203.0.113.20 remote 203.0.113.10 ttl 255 sudo ip link set gre1 mtu 1476 up sudo ip addr add 10.10.0.2/30 dev gre1 ``` La MTU de 1476 resulta de restar a los 1500 bytes de Ethernet la cabecera IP exterior (20 bytes) y la cabecera GRE básica (4 bytes). Comprueba el túnel desde el host A: ```bash ip tunnel show gre1 ping -c 3 10.10.0.2 ``` ```output gre1: gre/ip remote 203.0.113.20 local 203.0.113.10 ttl 255 64 bytes from 10.10.0.2: icmp_seq=1 ttl=64 time=1.21 ms 64 bytes from 10.10.0.2: icmp_seq=2 ttl=64 time=1.08 ms ``` Para ver el encapsulado, captura en la interfaz pública del host B (sustituye `eth0` por la tuya) mientras haces ping: ```bash sudo tcpdump -ni eth0 proto gre ``` ```output IP 203.0.113.10 > 203.0.113.20: GREv0, length 88: IP 10.10.0.1 > 10.10.0.2: ICMP echo request, id 4, seq 1, length 64 ``` ## Paso 3: Enrutar las redes locales por el túnel El túnel sirve para que las redes que hay detrás de cada host se alcancen entre sí. Añade en cada host la ruta hacia la red del otro lado a través de la IP del túnel remoto. En el **host A**: ```bash sudo ip route add 10.0.2.0/24 via 10.10.0.2 dev gre1 ``` En el **host B**: ```bash sudo ip route add 10.0.1.0/24 via 10.10.0.1 dev gre1 ``` Para que los hosts reenvíen tráfico entre su red local y el túnel, activa el reenvío IP de forma persistente en ambos: ```bash echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/60-ip-forward.conf sudo sysctl --system ``` Si UFW está activo, su política por defecto descarta el tráfico reenviado. Permite el reenvío entre el túnel y la interfaz de la red local (en este ejemplo `eth1`) en ambos sentidos: ```bash sudo ufw route allow in on gre1 out on eth1 sudo ufw route allow in on eth1 out on gre1 ``` Las máquinas de la red `10.0.1.0/24` también deben saber que `10.0.2.0/24` se alcanza a través del host A, ya sea porque el host A es su puerta de enlace o porque les añades una ruta estática. Comprueba el camino desde una máquina de la red A: ```bash ip route get 10.0.2.10 ping -c 3 10.0.2.10 ``` ## Paso 4: Evitar problemas de MTU con MSS clamping Las máquinas de las redes locales usan MTU 1500 y no saben que el túnel admite menos. Si el ICMP que avisa de la fragmentación se filtra en algún punto, las conexiones TCP se quedan colgadas al transferir paquetes grandes. La solución habitual es ajustar el MSS de TCP en el host que hace de router, para que las conexiones negocien un tamaño que quepa en el túnel. Ubuntu 24.04 usa nftables como backend de firewall, así que la forma más limpia es una tabla nftables propia, independiente de las reglas de UFW. Instala la herramienta `nft` (normalmente ya está presente) y crea el archivo de reglas en ambos hosts: ```bash sudo apt install nftables sudo mkdir -p /etc/nftables.d sudo nano /etc/nftables.d/gre-mss.nft ``` Las dos primeras líneas declaran y borran la tabla, de modo que el archivo se puede cargar varias veces sin duplicar reglas: ```text table inet gre_mss delete table inet gre_mss table inet gre_mss { chain forward { type filter hook forward priority mangle; policy accept; oifname "gre1" tcp flags syn tcp option maxseg size set rt mtu iifname "gre1" tcp flags syn tcp option maxseg size set rt mtu } } ``` Carga la tabla y comprueba que existe: ```bash sudo nft -f /etc/nftables.d/gre-mss.nft sudo nft list table inet gre_mss ``` No actives el servicio `nftables` para cargarla en el arranque: su archivo `/etc/nftables.conf` empieza con `flush ruleset` y borraría las reglas de UFW. En su lugar, crea una unidad de systemd que cargue solo este archivo: ```bash sudo nano /etc/systemd/system/gre-mss.service ``` ```ini [Unit] Description=MSS clamping para el tunel GRE After=network-pre.target ufw.service [Service] Type=oneshot ExecStart=/usr/sbin/nft -f /etc/nftables.d/gre-mss.nft RemainAfterExit=yes [Install] WantedBy=multi-user.target ``` Actívala y comprueba su estado: ```bash sudo systemctl daemon-reload sudo systemctl enable --now gre-mss.service systemctl status gre-mss.service ``` Comprueba que un paquete del tamaño máximo cruza el túnel sin fragmentar (1448 bytes de datos más 28 de cabeceras ICMP e IP suman 1476): ```bash ping -c 3 -M do -s 1448 10.10.0.2 ``` ## Paso 5: Hacer el túnel persistente con Netplan El túnel, su dirección y las rutas desaparecen al reiniciar. Netplan, el gestor de red de Ubuntu, puede declarar túneles GRE. Borra primero la interfaz temporal para que Netplan la cree: ```bash sudo ip link del gre1 ``` Crea un archivo de Netplan en el **host A**: ```bash sudo nano /etc/netplan/60-gre1.yaml ``` ```yaml network: version: 2 tunnels: gre1: mode: gre local: 203.0.113.10 remote: 203.0.113.20 mtu: 1476 addresses: - 10.10.0.1/30 routes: - to: 10.0.2.0/24 via: 10.10.0.2 ``` Netplan exige que sus archivos no sean legibles por otros usuarios: ```bash sudo chmod 600 /etc/netplan/60-gre1.yaml ``` Aplica la configuración. `netplan try` revierte los cambios automáticamente si pierdes la conexión y no confirmas en 120 segundos: ```bash sudo netplan try ``` Pulsa Intro para confirmar y comprueba el resultado: ```bash networkctl status gre1 ip route show dev gre1 ``` ```output 10.0.2.0/24 via 10.10.0.2 proto static 10.10.0.0/30 proto kernel scope link src 10.10.0.1 ``` Repite en el host B con `local`, `remote`, la dirección y la ruta intercambiados. Reinicia uno de los servidores y confirma que el ping entre `10.10.0.1` y `10.10.0.2` sigue funcionando. ## Paso 6: Cifrar el túnel con IPsec IPsec en modo transporte cifra los paquetes GRE entre los dos hosts sin cambiar nada del túnel: GRE sigue funcionando igual, pero sus paquetes viajan dentro de ESP. Este paso usa strongSwan con su interfaz moderna, `swanctl`. Instala strongSwan en ambos hosts: ```bash sudo apt update sudo apt install charon-systemd strongswan-swanctl ``` Genera una clave precompartida larga y aleatoria. Usarás la misma en los dos hosts: ```bash openssl rand -base64 32 ``` Crea la configuración en el **host A**: ```bash sudo nano /etc/swanctl/conf.d/gre.conf ``` ```text connections { gre-ipsec { version = 2 local_addrs = 203.0.113.10 remote_addrs = 203.0.113.20 proposals = aes256gcm16-prfsha384-ecp384 dpd_delay = 30s local { auth = psk id = 203.0.113.10 } remote { auth = psk id = 203.0.113.20 } children { gre { mode = transport local_ts = dynamic[gre] remote_ts = dynamic[gre] esp_proposals = aes256gcm16-ecp384 start_action = trap dpd_action = restart } } } } secrets { ike-gre { id-a = 203.0.113.10 id-b = 203.0.113.20 secret = "your_psk" } } ``` Sustituye `your_psk` por la clave generada. En el **host B**, usa el mismo archivo intercambiando `local_addrs`/`remote_addrs` y los `id` de `local` y `remote`. `local_ts = dynamic[gre]` limita la protección al protocolo GRE entre las dos IP, y `start_action = trap` negocia la conexión automáticamente en cuanto hay tráfico GRE. Restringe los permisos, ya que contiene la clave: ```bash sudo chmod 600 /etc/swanctl/conf.d/gre.conf ``` Permite IKE y ESP desde el otro host en el firewall. En el host A: ```bash sudo ufw allow from 203.0.113.20 to any port 500,4500 proto udp sudo ufw allow proto esp from 203.0.113.20 to any ``` ESP añade entre 50 y 60 bytes por paquete, así que reduce la MTU del túnel a 1400 en ambos hosts cambiando `mtu: 1476` por `mtu: 1400` en `/etc/netplan/60-gre1.yaml` y aplicándolo con `sudo netplan apply`. Carga la configuración y reinicia el servicio en ambos hosts: ```bash sudo systemctl restart strongswan sudo swanctl --load-all ``` Genera tráfico por el túnel y comprueba la asociación de seguridad: ```bash ping -c 3 10.10.0.2 sudo swanctl --list-sas ``` ```output gre-ipsec: #1, ESTABLISHED, IKEv2, ... local '203.0.113.10' @ 203.0.113.10[500] remote '203.0.113.20' @ 203.0.113.20[500] gre: #1, reqid 1, INSTALLED, TRANSPORT, ESP:AES_GCM_16-256 local 203.0.113.10/32[gre] remote 203.0.113.20/32[gre] ``` Una captura en la interfaz pública ya no debe mostrar GRE en claro, sino paquetes ESP: ```bash sudo tcpdump -ni eth0 host 203.0.113.20 and not port 22 ``` ```output IP 203.0.113.10 > 203.0.113.20: ESP(spi=0xc1a2b3c4,seq=0x5), length 132 ``` ## Solución de problemas **El túnel está `UP` pero el ping a la IP remota del túnel no responde.** Captura con `sudo tcpdump -ni eth0 proto gre` en ambos hosts. Si los paquetes salen de un lado y no llegan al otro, algo en el camino bloquea el protocolo 47: el firewall del destino, un grupo de seguridad del proveedor o un NAT. GRE no atraviesa NAT de forma fiable; si uno de los extremos está detrás de NAT, usa WireGuard. **El ping entre túneles funciona pero no entre las redes locales.** Comprueba que `sysctl net.ipv4.ip_forward` devuelve `1` en ambos hosts, que existen las rutas en los dos sentidos (`ip route get` desde cada lado) y que la cadena `FORWARD` no descarta el tráfico (`sudo iptables -L FORWARD -v -n`). **Las conexiones SSH o HTTP a través del túnel se cuelgan tras conectar.** Es un problema de MTU. Revisa que la tabla `gre_mss` está cargada y que la MTU de `gre1` es 1476 (o 1400 con IPsec). **`swanctl --list-sas` no muestra nada.** Consulta el registro con `sudo journalctl -u strongswan -n 50`. `AUTHENTICATION_FAILED` indica que la clave o los `id` no coinciden; `NO_PROPOSAL_CHOSEN`, que los `proposals` son distintos en cada lado. ## Conclusión Tienes un túnel GRE persistente entre dos servidores Ubuntu 24.04 que une dos redes, con la MTU y el MSS ajustados para evitar conexiones colgadas y, opcionalmente, cifrado con IPsec en modo transporte. GRE sigue siendo la opción adecuada cuando el otro extremo es un router o firewall que no soporta WireGuard, o cuando necesitas transportar multicast para protocolos de enrutamiento. Como siguientes pasos puedes ejecutar OSPF o BGP sobre el túnel con FRRouting para anunciar las redes de forma dinámica, o añadir un segundo túnel hacia otra sede.