Blog Logo

20 Mar 2025 ~ 12 min read

Crea una VPN a tu casa con Wireguard (aunque tengas CGNAT) 🚀🔒


El problema: CGNAT y acceso remoto

Tengo un montón de aplicaciones corriendo de forma local en un servidor ubicado en mi casa, y quiero poder usarlas cuando me voy de viaje, pero obviamente solo las puedo usar con el wifi de mi casa.

Este es un problema muy común entre las personas que como tú y como yo tenemos nuestro propio NAS o simplemente un ordenador chapucero que nos sobraba, corriendo alguna aplicación de self-hosting.

Esto tiene muy fácil solución, se soluciona con una VPN, pero ojo, cuidado si tu operadora trabaja bajo CGNAT, vas a perder todo el control a tu IP y te va a hacer muy complicado esto de tener una VPN hacia tu casa. Pero tranquilo, aquí estoy yo para solucionarlo.

El vídeo de youtube donde hablo de este tema:

Crea una VPN a tu casa con Wireguard (aunque tengas CGNAT)

¿Qué es una VPN?

Una VPN (Virtual Private Network) es un método para crear una conexión segura entre tu dispositivo y una red privada a través de Internet. Se usa, por ejemplo, para conectarte a la red de tu empresa o en nuestro caso vamos a hacerlo para conectarnos a casa como si estuviéramos físicamente allí.

No creáis que una VPN sirve solamente para que de golpe vuestra ubicación aparezca en otro país, esa es la función de las VPN comerciales, pero al final lo que hacen es lo mismo que queremos: pasar nuestra conexión a un lugar concreto.

La función de las VPN es básicamente cifrar los datos, pasarlos por un túnel seguro y redirigir el tráfico para que pase por el servidor que queremos.

image.webp

¿Qué es CGNAT?

CGNAT (Carrier-Grade NAT) es una tecnología que usan los proveedores de Internet (ISPs) para gestionar la escasez de direcciones IPv4. Básicamente, en lugar de asignarte una dirección IP pública única, te meten en un sistema donde varios usuarios comparten la misma IP pública. Esto lo hacen porque, con la falta de direcciones IPv4, no pueden dar una IP exclusiva a cada cliente.

Esto se solucionaría si empezasen a trabajar con IPv6, que son los tronchos súper largos que no sé si habéis visto alguna vez, pero como no lo hacen todas las compañías todavía, nos tenemos que tragar esta chapuza…

El gran inconveniente es que, al compartir la IP con otros usuarios, no puedes abrir puertos ni acceder directamente a tu red desde fuera. Esto afecta a:

  • Servidores caseros (juegos, NAS, cámaras de seguridad, etc.).
  • Acceso remoto a tu red (por ejemplo, con una VPN casera, aunque eso lo vamos a solucionar hoy).
  • Servicios P2P o cualquier cosa que necesite conexiones directas entrantes.

¿Cómo sé si estoy bajo CGNAT?

Saber si estás bajo CGNAT es muy sencillo, y tienes diversos métodos para saberlo, uno muy común y rápido es primero averiguar tu IP. Para no complicarte, si pones en Google “cual es mi ip” te saldrán cientos de resultados donde te indiquen la IP.

Bien, ahora que la tienes, apúntala, y ve a los ajustes del router. Estos suelen estar en 192.168.1.1 o 192.168.1.0 dependiendo de tu puerta de enlace.

Lo puedes averiguar también, si no te sale, abriendo una consola, escribiendo ipconfig (en Windows) o ifconfig (en Linux/Mac) y buscando la frase que pone “puerta de enlace”.

Una vez en tu panel del router inicias sesión con el usuario que seguramente ponga detrás del papelito de tu router y buscas algo parecido a “Internet” o “WAN” hasta que encuentres una IP.

En mi caso fue la sección Internet, y más abajo me salían dos WAN. Ambas, solo con verlas me desvelan que estoy bajo CGNAT. ¿Cómo? Fijaos bien, una empieza por 10 y otra por 100. No solo son diferentes a la IP que me salía en la web que hemos visto antes, que con eso ya nos lo dice todo, sino que la que empieza por 10 indica que es una IP privada, y no pública, y la otra está dentro del rango de las IPs de CGNAT que son entre 100.64.x.x y 100.127.x.x.

image.webp

Esto es la forma de hacerlo si más o menos entendéis del tema y le ponéis algo de ganas, pero si no queréis complicaros hay una opción más rápida, y es llamar a tu compañía y preguntarles. En mi caso me lo dijeron en la primera llamada, y sí que es verdad que algunas, si lo pides, te asignan una IP pública sin CGNAT, pero en mi caso si lo pedía me subían la factura mensual al doble de lo que pago. ¿Una locura, no?

La solución: crear un túnel Wireguard con un VPS

Esto se puede hacer de muchas maneras. Hay software como Tailscale o Zerotier que permiten hacer esto mismo que vamos a hacer, pero nos limitan los dispositivos a no ser que paguemos y además no es 100% privado como esto que vamos a hacer. Y a parte, en este canal nos gusta cacharrear, ¿verdad?

Para nuestra solución, necesitamos:

  1. Un dispositivo en casa (Raspberry Pi, PC, etc.) que estará siempre encendido.
  2. Un VPS (servidor en la nube) con IP pública que hará de puente.

La idea es simple: establecemos un túnel VPN entre nuestro dispositivo casero y el VPS, y luego nos conectamos al VPS desde cualquier lugar para acceder a nuestra red doméstica.

image.webp

Lo que necesitamos

  • En casa: Una Raspberry Pi (recomendada por su bajo consumo) o cualquier PC que pueda estar siempre encendido.
  • En la nube: Un VPS básico. Puedes usar la capa gratuita de Oracle Cloud o un servidor económico de DigitalOcean/Vultr/etc.

Voy a usar Docker para simplificar la instalación, así que necesitaremos tenerlo instalado tanto en el VPS como en la Raspberry Pi.

Paso 1: Configuración del VPS

Primero, debemos preparar el servidor que servirá como puente entre internet y nuestra casa.

Conectarse al VPS por SSH

Lo primero que necesitamos es conectarnos al servidor por SSH. Si estás usando un VPS de Oracle Cloud, DigitalOcean o similares, seguramente tengas que usar una clave privada para conectarte:

ssh -i nombre_de_tu_clave_privada usuario@ip_del_servidor

Nota: La clave privada es la que guardaste al crear la instancia. Si te da problemas de permisos, asegúrate de darle los permisos correctos:

En Linux/Mac:

chmod 600 nombre_de_tu_clave_privada

En Windows:

icacls "C:\ruta\de\tu\clave_privada.pem" /inheritance:r
icacls "C:\ruta\de\tu\clave_privada.pem" /grant:r "%USERNAME%:R"

Si te pide contraseña en vez de clave privada, simplemente usa:

ssh usuario@ip_del_servidor

Y luego introduce la contraseña que configuraste.

Instalación de Docker y Docker Compose

# Actualizar el sistema
sudo apt update
sudo apt upgrade -y

# Instalar dependencias necesarias
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

# Añadir clave GPG oficial de Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

# Añadir repositorio de Docker
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

# Actualizar e instalar Docker
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io

# Añadir usuario actual al grupo docker
sudo usermod -aG docker $USER

# Instalar Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verificar instalación
docker --version
docker-compose --version

Preparar la configuración de Wireguard

Ahora vamos a clonar mi repositorio que contiene todos los archivos necesarios:

git clone https://github.com/edunavajas/wireguard-cgnat.git
cd wireguard-cgnat/vps

Generar las claves Wireguard

Es importante generar claves para nuestro servidor:

# Crear directorio config si no existe
mkdir -p config

# Generar claves con los permisos adecuados
cd config
umask 077 && sudo sh -c 'wg genkey | tee privatekey | wg pubkey > publickey'

# Verificar que las claves se han creado correctamente
ls -la

Configurar el servidor Wireguard

Ahora vamos a dar permisos de ejecución al script de configuración:

cd ../
sudo chmod +x setup-wireguard-tunnel.sh

Abrimos los puertos necesarios:

sudo ufw allow 51820/udp
sudo ufw status

Y ejecutamos el script de configuración:

sudo ./setup-wireguard-tunnel.sh

Este script realizará:

  • Habilitar el reenvío de IP
  • Iniciar el contenedor Docker de Wireguard
  • Configurar iptables para enrutamiento
  • Generar claves y configuraciones de cliente automáticamente

Modificar la configuración del cliente

Ahora modificamos la configuración generada para permitir el acceso a nuestra red doméstica:

cd /config/wg_confs/
nano wg0.conf

Busca la sección del peer1 y modifica la línea AllowedIPs para incluir tu red doméstica:

[Peer] # peer1
PublicKey = ...
...
AllowedIPs = 10.69.69.2/32, 192.168.1.0/24

Esto permite el tráfico hacia el cliente (10.69.69.2) y hacia tu red doméstica (192.168.1.0/24, ajusta esto a tu subred).

Reinicia el servicio de Wireguard para aplicar los cambios:

docker-compose down
docker-compose up -d

Obtener la configuración para el cliente

Guarda la configuración del cliente para usarla en la Raspberry Pi:

cat config/peer1/peer1.conf

Copia todo el contenido que aparece, lo necesitaremos para la Raspberry Pi.

Paso 2: Configuración de la Raspberry Pi

Ahora configuraremos nuestra Raspberry Pi para que se conecte al VPS.

Conectarse a la Raspberry Pi por SSH

Para conectarnos a nuestra Raspberry Pi, necesitamos usar SSH. Si estás en la misma red que la Raspberry, puedes conectarte usando:

ssh usuario@ip_de_raspberry

El usuario por defecto en Raspberry Pi OS suele ser “pi”, aunque puede que lo hayas cambiado. La IP la puedes averiguar desde tu router o usando herramientas como nmap:

nmap -sn 192.168.1.0/24

Esto escaneará tu red local en busca de dispositivos. Busca el que corresponda a tu Raspberry Pi.

Consejo: Para hacer que la conexión sea más fácil en el futuro, puedes configurar una IP estática en tu Raspberry Pi o agregarla a tu archivo de hosts.

Si te pide contraseña, por defecto en Raspberry Pi OS es “raspberry”, aunque es muy recomendable cambiarla por seguridad.

Instalación de Docker

Si aún no tienes Docker instalado en tu Raspberry Pi, sigue estos pasos:

# Actualizar el sistema
sudo apt update
sudo apt upgrade -y

# Instalar dependencias
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common

# Instalar Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Añadir usuario al grupo docker
sudo usermod -aG docker $USER

# Instalar Docker Compose
sudo pip3 install docker-compose

Configurar Wireguard en la Raspberry Pi

Primero, clonamos el repositorio:

git clone https://github.com/edunavajas/wireguard-cgnat.git
cd wireguard-cgnat/raspberry

Damos permisos de ejecución al script:

sudo chmod +x setup-wireguard-client.sh

Creamos el directorio de configuración y el archivo de configuración:

mkdir -p config
nano config/wg0.conf

Aquí pegamos la configuración del peer1 que copiamos del VPS, asegurándonos de que tenga esta estructura:

[Interface]
PrivateKey = <PRIVATE_KEY>
Address = 10.69.69.2/24
DNS = 1.1.1.1
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = <PUBLIC_KEY_DEL_VPS>
Endpoint = <IP_PUBLICA_DEL_VPS>:51820
PresharedKey = <KEY>
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25

Reemplaza los valores <PRIVATE_KEY>, <PUBLIC_KEY_DEL_VPS>, <IP_PUBLICA_DEL_VPS> y <KEY> con los valores correspondientes de la configuración del peer1.

Y finalmente, ejecutamos el script:

sudo ./setup-wireguard-client.sh

Paso 3: Conectarse desde otros dispositivos

Ahora que tenemos nuestro túnel VPN establecido entre el VPS y la Raspberry Pi, podemos conectarnos desde cualquier dispositivo.

Configuración para dispositivos adicionales

En el VPS, podemos obtener las configuraciones para otros dispositivos:

# Para el peer2
cat /config/peer2/peer2.conf

Luego debemos instalar el cliente de Wireguard en nuestro dispositivo:

  • Android/iOS: Descarga la app oficial “WireGuard” desde la tienda de aplicaciones.
  • Windows/Mac/Linux: Descarga el cliente oficial desde wireguard.com.

Una vez instalado el cliente, simplemente importamos el archivo de configuración (.conf) o escaneamos el código QR para conectarnos:

# Para mostrar el código QR del peer2 (útil para móviles)
docker exec -it wireguard /app/show-peer 2

Comprobando la conexión

Para verificar que todo funciona correctamente:

En el VPS

docker exec wireguard wg show

Deberías ver a tu Raspberry Pi conectada.

En la Raspberry Pi

docker exec wireguard-client wg show

Deberías ver la conexión al VPS.

Pruebas de conectividad

Desde el VPS, intenta hacer ping a tu Raspberry Pi:

ping 10.69.69.2

Desde la Raspberry Pi, intenta hacer ping al VPS:

ping 10.69.69.1

Para comprobar el acceso a tu red doméstica, conecta un dispositivo adicional al VPS e intenta acceder a algún servicio en tu red local. Por ejemplo, si tienes un servidor web en 192.168.1.100, intenta acceder a él.

Resolución de problemas

Si encuentras problemas de conectividad:

  1. Revisa la configuración del firewall Asegúrate de que el puerto UDP 51820 está abierto en tu VPS:

    sudo ufw status
    
  2. Verifica el estado de la interfaz Wireguard En ambos lados:

    ip a show wg0
    
  3. Revisa las tablas de enrutamiento

    ip route
    
  4. Consulta los logs de Wireguard

    docker logs wireguard
    docker logs wireguard-client
    
  5. Reinicia los servicios Wireguard En el VPS:

    cd wireguard-cgnat/vps
    docker-compose down
    docker-compose up -d
    

    En la Raspberry Pi:

    cd wireguard-cgnat/raspberry
    docker-compose down
    docker-compose up -d
    

Conclusión

¡Y listo! Ahora tienes una VPN completamente funcional que te permite acceder a tu red doméstica desde cualquier lugar, incluso si tu proveedor de internet te tiene bajo CGNAT.

Esta solución es:

  • Segura: El tráfico está cifrado de extremo a extremo.
  • Privada: No dependes de servicios de terceros que puedan acceder a tus datos.
  • Flexible: Puedes añadir tantos dispositivos como necesites.
  • Económica: Solo pagas por el VPS, que puede ser muy barato o incluso gratuito.

Espero que esta guía os sea útil y os ahorre los mismos dolores de cabeza que me ahorró a mí. Si tenéis alguna duda o sugerencia, podéis comentarlo abajo o visitar el repositorio en GitHub para más información.

¡Hasta la próxima! 👋


Edu Navajas Profile

Hola! soy Edu. Soy un desarrollador de software con más de 5 años de experiencia Puedes seguirme en Linkedin y ver mi trabajo en GitHub.

← Volver al blog