Redes

Configurar PiVPN detrás de CGNAT: 3 métodos reales cuando tu ISP no te da IP pública

TL;DR — Lo que vas a tener al final

  • El problema: tu ISP te asignó una IP privada y por eso PiVPN no escucha conexiones entrantes, aunque pienses que está abierto.
  • Detección rápida: comparás la IP WAN de tu router contra curl ifconfig.me desde la Pi. Si difieren, estás tras CGNAT.
  • Tres métodos reales: (1) VPS puente con WireGuard hop-by-hop, (2) Tailscale/NetBird como plano de control, (3) pedir IPv6 o IPv4 pública al ISP.
  • Resultado: tu VPN levanta en 30–120 minutos dependiendo del método, sin tocar la configuración de PiVPN que ya tienes funcionando.

Instalé PiVPN en casa de un amigo la semana pasada y perdimos dos horas Debuggeando por qué WireGuard no conectaba. La Pi respondía al ping desde la LAN, el puerto UDP 51820 estaba abierto en el router, el firewall de la Pi aceptaba el tráfico, el QR escaneado en el celular se configuraba perfecto, y aun así nada. Después de media hora de revisar wg show con cara de no entender nada, probé un curl ifconfig.me en la Pi y comparé con la IP WAN que reportaba el router del propio modem. Eran distintas. Router decía 190.45.x.x, internet veía 200.54.x.x. El ISP lo estaba enmascarando doble: NAT residencial (una sola capa) más CGNAT del operador (otra capa encima). Resultado: el celular podía salir a internet, pero internet no podía volver a entrar a la Pi.

Este artículo existe porque ése es el escenario CGNAT (Carrier-Grade NAT) en 2026 y afecta a la mayoría de los ISPs residenciales de LATAM y España. Si configuraste PiVPN siguiendo cualquier tutorial en internet y nunca te funcionó, vuelve a esta guía cuando termines. No hay una solución única: depende del método del ISP, de si tienes un VPS disponible, y de cuánta pereza te da depender de un proveedor externo. Te voy a dar los tres caminos reales, con los comandos exactos, qué falla en cada uno, y cuándo cada uno deja de tener sentido.

Qué es CGNAT y por qué rompe tu PiVPN

CGNAT es una capa adicional de NAT que el ISP pone entre tu router y el internet público. El operador comparte una misma IP pública entre muchos clientes (a veces 200, a veces 2.000), dándoles a todos direcciones privadas del rango 100.64.0.0/10 (RFC 6598) o 10.0.0.0/8 recortado. Tu router hace NAT como siempre hacia esa IP privada del ISP, y el ISP hace NAT otra vez hacia su pool de IPs públicas compartidas.

El problema concreto para PiVPN es que el handshake inicial de WireGuard requiere que el cliente UDP-envíe un paquete al puerto 51820 de la IP pública. Ese paquete llega al ISP, pero el ISP no sabe a cuál de los 500 clientes debe reenviarlo — todos comparten IP, no hay state, no hay entrada de port forwarding. Tu Pi nunca escucha el primer paquete. El cliente agota timeout, te marca “conectando” para siempre, y tú asumes que el firewall está mal.

No es un bug de PiVPN ni de WireGuard. Es arquitectura de red. PiVPN está perfectamente bien instalado; el problema es que la red no deja llegar el tráfico hasta PiVPN.

Concepto Configuración clásica Con CGNAT
Tu IP WAN Igual a la pública que ve internet Es privada (100.64.x.x) y NO enrutable
Port forwarding Funciona, los paquetes llegan No hay forma de configurar en la red del ISP
Clientes VPN entrantes Pueden iniciar el handshake El handshake se pierde en el NAT del operador
Solución real PiVPN + port forward Salir del CGNAT por otro camino

Verifica si tu ISP te tiene en CGNAT

Antes de aplicar cualquiera de los tres métodos, confirma que estás en CGNAT. Asumir sin verificar te puede llevar a configurar un puente SSH y descubrir después que tenías IP pública todo el tiempo y solo te faltaba un port forward bien hecho en el router.

# Paso 1: IP que reporta tu router (búscala en la admin del modem)
# Comúnmente en 192.168.1.1, 192.168.0.1, 192.168.100.1
# Paso 2: la IP que internet ve cuando la Pi habla hacia afuera
curl -s ifconfig.me
curl -s ipinfo.io/ip
# Paso 3: la IP local que tiene la interfaz WAN de la Pi (o tu desktop)
ip -4 addr show | grep -E 'inet ' | grep -v '127.0.0.1'

Si la salida del paso 3 es 100.64.x.x, 100.65.x.x hasta 100.127.x.x, estás 100 % en CGNAT según RFC 6598. Si la salida es 10.x.x.x o 192.168.x.x siendo la IP WAN (no la de la LAN 192.168.1.x privada), también. Si es una IP pública directa como 190.x.x.x o 200.x.x.x, no estás en CGNAT y tu problema de PiVPN es otro: mal port forward, firewall bloqueando UDP, o clave mal exportada.

Una segunda señal rápida: haz un traceroute desde internet (usa mtr desde una VPS o un traceroute web como ping.pe) hacia tu IP pública. Si ves un salto adicional justo en la frontera del ISP que no responde al TTLExceeded, es el NAT del operador.

# Verifica también desde la propia Pi
traceroute -n 8.8.8.8 | head -5
# Si ves dos saltos seguidos con IPs privadas consecutivas,
# estás en doble NAT residencial + CGNAT

Método 1 — Puente VPS con WireGuard hop-by-hop

Este es el método que mejor entiende un sysadmin clásico: contratas un VPS barato (Hetzner, Contabo, Racknerd, todos tienen planes anuales por menos de 30 USD), montas WireGuard entre la Pi y el VPS, y los clientes se conectan a la IP pública del VPS. El VPS hace de bridge, la Pi sigue siendo el “server” lógico, y todo el cifrado punto a punto entre cliente y Pi se mantiene.

Requisitos: un VPS con IPv4 pública, root, y entre 512 MB y 1 GB de RAM. El tráfico VPN pasa por el VPS, así que el ancho de banda del VPS es tu cuello de botella real para el throughput de los túneles (no para el internet general, los clientes pueden salir directo por el VPS o hacer full-tunnel hacia la Pi, según cómo configures AllowedIPs).

# === EN EL VPS ===
# Después de instalar pivpn en la Pi con la config normal,
# instalamos WireGuard también en el VPS como bridge
sudo apt update && sudo apt install -y wireguard
# Generamos un par de claves dedicado para el tunel Pi<->VPS
wg genkey | tee /etc/wireguard/bridge_private.key | wg pubkey > /etc/wireguard/bridge_public.key
sudo chmod 600 /etc/wireguard/bridge_private.key

El truco clave: el VPS actúa como intermediario forwarding, no como endpoint. Es decir, los clientes VPN se siguen conectando al endpoint que PiVPN configuró originalmente (la IP que hayas puesto en pivpn -wg durante el setup), pero esa IP la delega el VPS. La Pi no necesita una IP pública propia. Cuando el VPS recibe un paquete UDP al puerto 51820, lo reenvía por el túnel cifrado a la Pi, que es donde realmente corre PiVPN.

# === EN EL VPS — config de WireGuard para el bridge ===
sudo tee /etc/wireguard/bridge.conf <<EOF
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = $(sudo cat /etc/wireguard/bridge_private.key)
# Habilitamos forwarding para reenviar tráfico del cliente a la Pi
PostUp = sysctl -w net.ipv4.ip_forward=1
PostUp = iptables -t nat -A POSTROUTING -s 10.6.0.0/24 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.6.0.0/24 -j MASQUERADE
[Peer]
# Clientes VPN (subred 10.6.0.0/24 que PiVPN asigna por defecto)
PublicKey = <PEER_PI_PUBLIC_KEY>
AllowedIPs = 10.6.0.0/24
EOF
sudo systemctl enable --now wg-quick@bridge

El bloque PostUp es lo que rompe la cadena CGNAT: el VPS acepta las conexiones entrantes en su IP pública (que sí es alcanzable), las descifra con WireGuard hacia el túnel interno, y las reenruta a la Pi. La Pi ve una conexión desde 10.99.0.x que es legítimo porque es la IP del VPS en el túnel.

La clave pública de la Pi la obtienes así desde la propia Pi después de instalar PiVPN:

# === EN LA PI ===
sudo pivpn -d   # diagnóstico, te da la clave pública de la interfaz wg0
sudo wg show wg0 public-key

Método 2 — Tailscale o NetBird como plano de control

Si no quieres administrar un VPS ni pelearte con claves WireGuard, el camino rápido es delegar el plano de control a un servicio moderno tipo Tailscale, NetBird o ZeroTier. Estos proveedores implementan un patrón llamado “NAT traversal” o “hole punching” mediante relays DERP, y prácticamente garantizan conectividad extremo a extremo aunque los dos extremos estén detrás de NATs anidados (CGNAT incluido).

Funciona así: instalas Tailscale en la Pi, te logueas con tu cuenta, y la Pi obtiene una IP estable del rango 100.x.x.x en la red tailnet. Cuando un cliente (tu celular, por ejemplo) también tiene Tailscale y está en tu cuenta, puede alcanzar la Pi directamente por esa 100.x.x.x aunque ambos estén bajo NAT. Tailscale negocia el camino punto a punto si es posible, o usa sus relays DERP cifrados (también llamados “fallback”) si no lo es.

# === EN LA PI ===
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
sudo tailscale status   # anota el 100.x.x.x que te asignó
# Para que el endpoint acepte como subnet router (clientes pueden salir a tu LAN)
sudo tailscale up --advertise-routes=192.168.1.0/24
# Confirma en la admin web de Tailscale que las routes están aprobadas

Ahora el cliente VPN ya no se conecta por IP pública ni por puerto UDP; se conecta por la IP de tailnet de la Pi. Puedes seguir usando la app de Tailscale en el celular, o extraer la clave del cliente para meterla en el cliente WireGuard nativo (Tailscale usa WireGuard por debajo, así que es el mismo binario).

Trade-offs importantes que debes asumir antes de elegir este método:

  1. Dependencia externa. Si Tailscale (o NetBird, o Headscale si lo self-hosteas) cae, tu VPN cae. Es un riesgo de proveedor.
  2. Lock-in parcial. La IP 100.x.x.x solo tiene sentido dentro de tu tailnet. No puedes compartirla con un tercero.
  3. Latencia adicional en el peor caso. Si el NAT traversal falla y se va por DERP, sumas 30–80 ms contra servidores europeos (depende de cuál DERP te toque).
  4. Cero configuración de firewall. Esto también es la ventaja — no tocas puertos, no abres nada en el router, no necesitas IP pública.

Si quieres evitar la dependencia externa pero conservar el patrón NAT-traversal, puedes hostear tu propio Tailscale con Headscale (su plano de control es open source). Es lo que hace la mayoría de los sysadmins que les gusta este método pero no confían en proveedores cerrados. El post 4198 de soylinux cubre ese setup en detalle.

Método 3 — Pedir IPv6 o IPv4 pública al ISP

El método más subestimado y el más barato. Muchos ISPs ya entregan IPv6 nativa en planes residenciales y, aunque tú no lo sepas, tienes una IP global IPv6 que es accesible directamente desde internet. Combinado con Dual-Stack Lite, eso basta para que PiVPN atienda sin tocar nada raro.

# Verifica si ya tienes IPv6 global
ip -6 addr show | grep -E 'scope global'
# Si ves un 2001:0:xxx o 2800:xxx o 2a02:xxx, tienes IPv6 global

Si tienes IPv6, configura PiVPN para escuchar también en esa interfaz. Por defecto PiVPN escucha en 0.0.0.0 que cubre IPv4; para IPv6 necesitas agregar el bind explícito. Edita /etc/wireguard/wg0.conf y cambia el bloque [Interface] para incluir ListenPort = 51820 (eso ya está) y agrega:

# Dentro del bloque [Interface] en /etc/wireguard/wg0.conf
PostUp = ip -6 addr add <TU_IPv6_GLOBAL>/128 dev wg0
PostUp = ip -6 route add default dev wg0

Con eso, los clientes que tengan IPv6 (celulares modernos en redes 4G/5G, casi todos) se pueden conectar directamente a la dirección IPv6 de tu Pi sin pasar por CGNAT. El único requisito: que el modem de tu ISP tenga el firewall IPv6 abierto al puerto 51820. Algunos ISPs lo bloquean por defecto; prueba primero con un nc -zu <tu_ipv6> 51820 desde una red externa con IPv6.

Si tu ISP no entrega IPv6 (raro en 2026, pero pasa con algunos planes de Argentina yMéxico viejos), la siguiente alternativa es solicitar la quita del CGNAT. En algunos operadores se llama “IP fija residencial”, “modo bridge”, “sin NAT” o “single-stack público”. Los precios oscilan entre gratis (si lo pides bien) y 5–10 USD mensuales:

ISP típico LATAM Costo por IPv4 pública Método de solicitud
VTR (Chile) CLP $4.990 / mes Call center, mencionas “Plan Avanzado IP Fija”
Movistar (Chile/AR/CO) USD 4–6 / mes App MiMovistar, sección “Servicios adicionales”
Telecom (Argentina) Gratis si lo solicitas Sucursal con DNI, demoraban 5 días hábiles
Telmex (México) Incluido en Infinitum Negocio Migración de plan residencial a negocio
Claro (multi-país) Variable, negociar Retailler autorizado, depende de ciudad

La negociación con el ISP es lenta y frustrante. Pero es la única solución que te deja sin hacks: PiVPN funcionando exactamente como la guía original, sin VPS, sin Tailscale, sin relays. Una vez que te asignan IP pública estática, puedes incluso hostear tu propio DDNS y olvidarte del cambio de IP cada 24 horas.

Cuándo NO vale la pena batallar con CGNAT

Hay escenarios donde quedarse en PiVPN bajo CGNAT es una pérdida de tiempo. Antes de invertir horas en el método 1 o 2, considera estos casos donde cambia la ecuación:

  1. Solo necesitas acceder a uno o dos servicios específicos desde el celular. PiVPN para esto es como matar una mosca con un cañón. Mejor expón los servicios con Cloudflare Tunnel (gratis para uso personal, soporta HTTPS sin abrir puertos en el router) y usa clientes específicos por app.
  2. Tu ISP rota la IP pública cada 5 minutos y no puedes contratar fija. PiVPN tradicional con IP dinámica es viable si configuras DDNS en el cliente, pero CGNAT + DDNS es innecesariamente complejo. Mejor método 2 (Tailscale) y listo.
  3. Tu uso es únicamente salir a internet desde redes no confiables. No necesitas entrar a tu casa: necesitas una VPN de salida. Cualquier servicio comercial (Mullvad, ProtonVPN) te lo da sin administrar nada. PiVPN está pensado para el caso contrario, acceder a recursos de tu propia red.
  4. Estás detrás de dos capas de NAT (residencial + CGNAT) y quieres administrar 10+ clientes. El método 1 con VPS aguanta, pero a esa escala conviene saltar a WireGuard nativo como en el post 4127, con un hub central dedicado y spoke servers en cada sitio.

Si tu caso cae en cualquiera de estos, no te tortures intentando configurar PiVPN. Las herramientas correctas son distintas. El setup moderno para “salir a internet desde wifi del café” es un VPN comercial con WireGuard (Mullvad cobra 5 EUR/mes). Para “exponer mis servicios a internet”, Cloudflare Tunnel. Para “VPN de acceso a mi red desde el celular”, entonces sí, uno de los tres métodos arriba.

Resumen

CGNAT no es el fin del autoalojamiento, es el empuje que el mercado te da para escoger entre tres caminos reales. El método 1 con VPS puente te da control total, el método 2 con Tailscale te da cero configuración a cambio de un proveedor externo, y el método 3 con tu ISP te da la solución limpia si tienes la paciencia de pedirla. Los tres están validados en producción por lectores de soylinux en Chile, Argentina y México.

Lo importante es que diagnostiques antes de actuar. Compara la IP WAN de tu router con la que reporta curl ifconfig.me. Si difieren, ya sabes que estás en CGNAT. El resto es decidir cuánta magia negra de relay estás dispuesto a tolerar en tu infraestructura.

Si ya tienes PiVPN funcionando bajo uno de los tres métodos y te topaste con otro obstáculo (el cliente no resuelve DNS,AllowedIPs mal escrita, PersistentKeepalive demasiado alto), el post 3909 cubre el troubleshooting fino de WireGuard. Para entender el patrón hub-and-spoke que escala a múltiples sitios, el post 4127 va directo a esa arquitectura.

Preguntas frecuentes

¿Cómo sé con certeza si estoy en CGNAT o solo detrás de NAT residencial?

La señal definitiva es que la interfaz WAN de tu router tenga una dirección en el rango 100.64.0.0/10 (comúnmente 100.64.x.x a 100.127.x.x). Eso es CGNAT RFC 6598 reservado por el ISP. NAT residencial usa 192.168.x.x, 10.x.x.x o 172.16-31.x.x como IP WAN, y aún permite port forwarding porque la IP WAN es pública para el ISP. La prueba práctica: abre un puerto UDP en tu router y haz un test desde una web tipo canyouseeme.org. Si el puerto se ve abierto, no estás en CGNAT y tu problema de PiVPN es de configuración. Si canyouseeme reporta “timed out” aunque tengas port forward configurado, sí estás en CGNAT.

¿Tailscale sigue funcionando si su servidor central cae?

Solo para nodos que ya establecieron conexión punto a punto antes de la caída. Para nuevas conexiones, sí necesitas el plano de control de Tailscale arriba. El servicio lleva más de 4 años con disponibilidad alta (99.97 % según su status page público) y mantienen relays DERP redundantes en múltiples regiones. Si este riesgo te importa, la opción open source es Headscale: hosteas tu propio plano de control y los nodos siguen siendo código de Tailscale original. El post 4198 de soylinux cubre ese setup completo con apt install de Headscale y configuración de tailscaled en los nodos.

¿Cuánto ancho de banda consume un túnel WireGuard puente por el VPS?

Un overhead de unos 32 bytes por paquete UDP para las cabeceras WireGuard, despreciable. El costo real es el tráfico útil: si un cliente ve un video de 5 GB desde tu LAN a través del VPS, consumes 5 GB del ancho de banda del VPS más los 32 bytes extra por paquete. En un VPS residencial Hetzner de 22 TB/mes, este tráfico no es problema. En un plan Cloudflare Tunnel o Tailscale, el tráfico DERP es gratis para uso personal hasta cierto umbral (Tailscale cobra solo uso comercial declarado por la empresa).

¿Puedo combinar método 1 y método 2 si el VPS se cae?

Sí, se llama failover y es relativamente común en setups de producción. Configuras WireGuard directo con port forward en el router cuando estés en casa (método 0 tradicional, sin CGNAT), Tailscale o NetBird como respaldo permanente (método 2), y el VPS bridge (método 1) cuando los clientes están fuera de tu red. Los clientes priorizan un endpoint sobre otro según latencia: en casa usan tu IP pública directa (más rápida), fuera usan Tailscale (más resiliente). El truco es que cada cliente tiene varias configuraciones WireGuard pre-cargadas y conmuta automáticamente si una falla.

¿Qué pasa con Pi-hole si configuro el túnel con VPS puente?

Pi-hole sigue funcionando exactamente igual porque está en la misma máquina que PiVPN (la Pi). Los clientes VPN al resolver DNS a través del túnel llegan al Pi-hole local por la subred 10.6.0.0/24 que PiVPN crea. Lo único que tienes que verificar es que en el archivo wg0.conf la línea DNS apunte a la IP de la Pi-hole (típicamente 10.6.0.1 o 192.168.1.x según cómo lo hayas configurado en pivpn -wg) y no a 1.1.1.1 ni a 8.8.8.8, que pasarían por alto Pi-hole y arruinarían el bloqueo de anuncios en el túnel.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *