Configuración de Túneles GRE en Linux
GRE (Generic Routing Encapsulation) es un protocolo de tunelización que encapsula paquetes de cualquier protocolo de capa de red dentro de datagramas IP, siendo una solución simple y eficiente para conectar redes remotas punto a punto. Esta guía cubre la creación de túneles GRE en Linux, la configuración de rutas, las consideraciones de MTU, el cifrado con IPsec y la persistencia de la configuración.
Requisitos Previos
- Ubuntu 20.04/22.04 o Debian 11/12 / CentOS 7/8
- Acceso root en ambos extremos del túnel
- El protocolo IP 47 (GRE) debe estar permitido entre los dos hosts
- IPs públicas o accesibles mutuamente en ambos extremos
# Verificar que el módulo GRE está disponible
modprobe ip_gre
lsmod | grep gre
# Verificar conectividad entre los hosts (requerida para el túnel)
ping -c 3 203.0.113.20 # IP del host remoto
Conceptos de GRE
GRE encapsula el paquete original completo dentro de un nuevo paquete IP:
Paquete original:
[IP orig: 10.0.1.10 → 10.0.2.10] [Datos]
Después de encapsulación GRE:
[IP outer: 203.0.113.10 → 203.0.113.20] [Cabecera GRE] [IP orig: 10.0.1.10 → 10.0.2.10] [Datos]
Ventajas de GRE:
- Simple y ampliamente soportado
- Puede encapsular múltiples protocolos (IPv4, IPv6, MPLS)
- Sin estado: no negocia conexión
- Bajo overhead (4-8 bytes de cabecera)
Desventajas:
- Sin cifrado nativo (necesita IPsec para seguridad)
- Overhead adicional reduce el MTU efectivo
Creación de un Túnel GRE Básico
Escenario: conectar la red 10.0.1.0/24 (Site A) con la red 10.0.2.0/24 (Site B):
# ===== SITE A (Host A) =====
# IP pública de Host A: 203.0.113.10
# Red local del Site A: 10.0.1.0/24
# Habilitar el reenvío IP
sysctl -w net.ipv4.ip_forward=1
# Crear el túnel GRE
ip tunnel add gre0 \
mode gre \
local 203.0.113.10 \ # IP local del extremo del túnel
remote 203.0.113.20 \ # IP del extremo remoto
ttl 255 # TTL para los paquetes GRE
# Activar la interfaz del túnel
ip link set gre0 up
# Asignar IPs al túnel (red interna del túnel)
ip addr add 10.10.0.1/30 dev gre0
# Verificar que el túnel está activo
ip link show gre0
ip addr show gre0
# ===== SITE B (Host B) =====
# IP pública de Host B: 203.0.113.20
# Red local del Site B: 10.0.2.0/24
sysctl -w net.ipv4.ip_forward=1
ip tunnel add gre0 \
mode gre \
local 203.0.113.20 \
remote 203.0.113.10 \
ttl 255
ip link set gre0 up
ip addr add 10.10.0.2/30 dev gre0
# Verificar conectividad a través del túnel
ping -c 3 10.10.0.1 # Desde Site B hacia el extremo A del túnel
Configuración de Enrutamiento
Con el túnel activo, configurar las rutas para alcanzar las redes remotas:
# ===== SITE A =====
# Ruta para alcanzar la red del Site B a través del túnel
ip route add 10.0.2.0/24 via 10.10.0.2 # O simplemente:
ip route add 10.0.2.0/24 dev gre0
# ===== SITE B =====
# Ruta para alcanzar la red del Site A
ip route add 10.0.1.0/24 via 10.10.0.1
# Verificar las rutas en ambos lados
ip route show | grep gre
# Probar la conectividad entre las redes locales
# Desde un host en 10.0.1.x en Site A:
ping 10.0.2.10 # Host en Site B
# Si no funciona, verificar que los hosts locales tienen rutas correctas
# y que hay reglas de NAT si es necesario
Configurar una ruta por defecto a través del túnel (para enrutar todo el tráfico):
# ATENCIÓN: esto enruta TODO el tráfico por el túnel
# Solo apropiado en casos específicos (red hub-and-spoke)
# Primero, mantener la ruta al endpoint remoto por la interfaz física
ip route add 203.0.113.20/32 via <gateway_local>
# Luego, enviar el resto por el túnel
ip route add 0.0.0.0/0 dev gre0
Consideraciones de MTU
El overhead de GRE reduce el MTU disponible:
# Ethernet MTU estándar: 1500 bytes
# Cabecera IP outer: 20 bytes
# Cabecera GRE: 4 bytes (sin clave) o 8 bytes (con clave)
# MTU efectivo sin clave: 1500 - 20 - 4 = 1476 bytes
# MTU efectivo con clave GRE: 1500 - 20 - 8 = 1472 bytes
# Configurar el MTU de la interfaz GRE
ip link set gre0 mtu 1476
# Verificar el MTU actual
ip link show gre0 | grep mtu
# Habilitar el path MTU discovery (PMTUD) para que TCP ajuste automáticamente
sysctl -w net.ipv4.ip_no_pmtu_disc=0
# Alternatively, usar TCP MSS clamping con iptables para prevenir fragmentación
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu
# Verificar si hay fragmentación en el túnel
ping -c 5 -s 1450 -M do 10.10.0.2 # Probar con tamaño específico sin fragmentar
GRE sobre IPsec
GRE no incluye cifrado; IPsec añade seguridad:
# Instalar strongSwan para IPsec
apt install -y strongswan strongswan-pki libstrongswan-extra-plugins
# Configurar IPsec para proteger el tráfico GRE
# Archivo: /etc/ipsec.conf
cat << 'EOF' > /etc/ipsec.conf
config setup
charondebug="ike 1, knl 1, cfg 0"
# Proteger el tráfico GRE entre los dos hosts (protocolo IP 47)
conn gre-tunnel
type=transport # Modo transporte (no túnel)
keyexchange=ikev2
# Lado local
left=203.0.113.10
leftauth=psk
# Lado remoto
right=203.0.113.20
rightauth=psk
# Cifrar solo el tráfico GRE (protocolo 47)
leftprotoport=gre
rightprotoport=gre
auto=start
dpdaction=restart
EOF
# Configurar la clave pre-compartida
cat << 'EOF' > /etc/ipsec.secrets
203.0.113.10 203.0.113.20 : PSK "ClaveCompartidaMuySegura123!"
EOF
chmod 600 /etc/ipsec.secrets
# Iniciar IPsec
systemctl enable strongswan
systemctl start strongswan
# Ahora crear el túnel GRE (el tráfico será cifrado por IPsec)
ip tunnel add gre-secure \
mode gre \
local 203.0.113.10 \
remote 203.0.113.20
ip link set gre-secure up
ip addr add 10.10.0.1/30 dev gre-secure
ip route add 10.0.2.0/24 dev gre-secure
# Verificar el estado de IPsec
ipsec status
Túneles GRE con Claves
Las claves GRE permiten múltiples túneles entre los mismos endpoints:
# Crear múltiples túneles GRE entre los mismos hosts usando claves diferentes
# Túnel para la VLAN de servidores web (clave 1)
ip tunnel add gre-web \
mode gre \
local 203.0.113.10 \
remote 203.0.113.20 \
key 1 \
ttl 255
ip link set gre-web up
ip addr add 10.10.1.1/30 dev gre-web
# Túnel para la VLAN de bases de datos (clave 2)
ip tunnel add gre-db \
mode gre \
local 203.0.113.10 \
remote 203.0.113.20 \
key 2 \
ttl 255
ip link set gre-db up
ip addr add 10.10.2.1/30 dev gre-db
# En el host remoto, crear los mismos túneles con las mismas claves
# Los paquetes con key=1 irán a gre-web, los de key=2 a gre-db
# Verificar los túneles
ip tunnel show
Persistencia con systemd-networkd
# Configuración persistente con systemd-networkd
# Crear el archivo de definición del dispositivo GRE
cat << 'EOF' > /etc/systemd/network/10-gre-tunnel.netdev
[NetDev]
Name=gre0
Kind=gre
MTUBytes=1476
[Tunnel]
Local=203.0.113.10
Remote=203.0.113.20
TTL=255
EOF
# Crear la configuración de red para la interfaz GRE
cat << 'EOF' > /etc/systemd/network/10-gre-tunnel.network
[Match]
Name=gre0
[Network]
Address=10.10.0.1/30
[Route]
Destination=10.0.2.0/24
Gateway=10.10.0.2
EOF
# Activar y recargar systemd-networkd
systemctl enable systemd-networkd
systemctl restart systemd-networkd
# Verificar el estado
networkctl status gre0
Solución de Problemas
# Verificar el estado del túnel
ip tunnel show gre0
ip link show gre0
ip addr show gre0
# Verificar las rutas a través del túnel
ip route show | grep gre
# Capturar tráfico GRE en la interfaz física
tcpdump -i eth0 proto gre -v
# Capturar tráfico dentro del túnel (tráfico encapsulado)
tcpdump -i gre0 -v
# Verificar que el protocolo GRE (IP 47) no está bloqueado
# El firewall puede bloquear el protocolo 47 aunque permita TCP/UDP
iptables -L | grep -i gre
iptables -A INPUT -p gre -j ACCEPT
iptables -A OUTPUT -p gre -j ACCEPT
# Para CentOS/Rocky con firewalld
firewall-cmd --permanent --add-protocol=gre
firewall-cmd --reload
# Ver el estado de IPsec si está configurado
ipsec statusall
# Verificar el MTU con diferentes tamaños de paquete
for SIZE in 1200 1400 1450 1476 1500; do
if ping -c 1 -s $SIZE -M do 10.10.0.2 > /dev/null 2>&1; then
echo "MTU $SIZE: OK"
else
echo "MTU $SIZE: FALLO (fragmentación)"
fi
done
El ping a través del túnel no funciona pero el túnel está activo:
# Verificar que el reenvío IP está habilitado en ambos hosts
sysctl net.ipv4.ip_forward
# Verificar que hay rutas de retorno en el host remoto
ip netns exec ns-remote ip route show
# Comprobar que iptables no está bloqueando el tráfico tunelizado
iptables -L FORWARD -v -n
iptables -A FORWARD -i gre0 -j ACCEPT
iptables -A FORWARD -o gre0 -j ACCEPT
Conclusión
Los túneles GRE en Linux son una herramienta versátil para crear conectividad punto a punto entre redes, con una configuración mínima y bajo overhead. Aunque no incluyen cifrado nativo, la combinación con IPsec proporciona una solución de conectividad segura comparable a las VPNs empresariales. Para casos de uso más modernos con cifrado integrado, WireGuard es generalmente preferible; sin embargo, GRE sigue siendo relevante por su amplia compatibilidad con equipos de red y su capacidad para encapsular protocolos no-IP.


