Montar tu propia VPN
con WireGuard
Redes y privacidad | unfantasmaenelsistema.com
En el artículo sobre VPN, Tor y proxy llegábamos a una conclusión incómoda: cuando usas una VPN comercial no eliminas la confianza, solo la trasladas. Antes tu operador de internet veía a dónde ibas; ahora lo ve una empresa que promete —en su web— no mirar. La única forma de romper del todo ese problema es que el servidor VPN sea tuyo: un equipo que tú administras, en el que tú decides si hay logs y en el que nadie más tiene una cuenta.
Eso, que hace diez años era un proyecto de fin de semana con OpenVPN y una lista larga de dolores de cabeza, hoy es cuestión de unos minutos gracias a WireGuard. Este artículo explica qué hace distinto a WireGuard, cómo funciona su modelo de pares y claves, y cómo levantar tu propio servidor en un VPS o en un mini-PC de casa, con los ficheros de configuración comentados línea a línea.
Qué aprenderás en este artículo
Por qué WireGuard es más simple, más rápido y más auditable que los protocolos VPN clásicos · El modelo de pares (peers) y el papel de las claves pública y privada · Cómo instalar y configurar el servidor en un VPS propio o en tu red doméstica · Los ficheros wg0.conf de servidor y de cliente, explicados campo a campo · AllowedIPs como enrutado y como control de acceso, NAT, DNS y kill switch · Split tunnel vs full tunnel, clientes móviles y herramientas de gestión (wg-easy, Headscale)
1. Por qué WireGuard
WireGuard es un protocolo de túnel cifrado que se incorporó al kernel de Linux en la versión 5.6 (2020). Su diseño parte de una idea deliberada: hacer menos cosas, pero hacerlas bien.
1.1 Superficie de código mínima
La implementación de referencia ronda las 4.000 líneas de código, frente a las cientos de miles de OpenVPN más OpenSSL. Menos código significa menos sitios donde esconder un fallo y una auditoría abarcable por una sola persona. Esto no es un detalle estético: la mayoría de vulnerabilidades graves en VPN de la última década han estado en el parseo de configuraciones complejas y en las capas de compatibilidad, no en la criptografía en sí.
1.2 Criptografía fija, sin negociación
OpenVPN e IPsec negocian al conectar qué cifrado, qué hash y qué curva usar. Esa flexibilidad es una fuente histórica de ataques de degradación. WireGuard no negocia nada: usa ChaCha20 para cifrar, Poly1305 para autenticar, Curve25519 para el intercambio de claves, BLAKE2s como hash. Si en el futuro algo de eso se considera débil, se publica una versión nueva del protocolo y se migra; no hay «suites» que configurar mal.
1.3 Rendimiento y comportamiento en red
- Al vivir en el kernel, evita las copias de memoria entre espacio de usuario y kernel que lastran a OpenVPN; en la práctica satura enlaces donde OpenVPN se queda a medias
- Es stateless en reposo: si no hay tráfico, no manda nada y no mantiene conexión. No hay «reconexión» — cuando vuelve a haber datos, el túnel simplemente funciona
- Usa un único puerto UDP. No responde a paquetes de origen no autenticado, así que para un escáner de puertos el servidor es indistinguible de una máquina que no escucha (silent by design)
- El roaming es transparente: el móvil puede pasar de wifi a datos móviles sin que el túnel se entere, porque el servidor identifica al par por su clave, no por su IP de origen
2. El modelo mental: pares, no cliente y servidor
WireGuard no distingue formalmente entre «servidor» y «cliente». Solo hay pares (peers). Cada par tiene una clave privada (nunca sale del equipo) y una clave pública (se comparte con los demás). Que uno haga de servidor es solo una consecuencia de la configuración: tiene IP fija o dominio, abre un puerto y varios pares lo listan como destino.
La relación es una malla de confianza explícita: un par solo acepta tráfico de otro par cuya clave pública tenga configurada, y solo si el paquete viene cifrado de forma que demuestra que el emisor posee la clave privada correspondiente. No hay usuarios, contraseñas ni certificados de una autoridad. Añadir un dispositivo a tu VPN es literalmente añadir un bloque `[Peer]` con su clave pública en el servidor, y viceversa.
# Generar el par de claves de un equipo (servidor o cliente, da igual) wg genkey | tee privatekey | wg pubkey > publickey # privatekey -> se queda SOLO en este equipo, permisos 600 # publickey -> es la que compartes con el otro extremo # Opcional: clave precompartida extra (defensa frente a criptografia cuantica futura) wg genpsk > preshared.key
3. Preparar el servidor
Sirve cualquier Linux con kernel 5.6 o superior: un VPS de 3-5 euros al mes (para salir a internet con otra IP y cifrar en redes públicas) o un mini-PC / Raspberry Pi en casa (para entrar a tu red doméstica desde fuera). Los pasos son los mismos.
# Debian / Ubuntu sudo apt update && sudo apt install wireguard wireguard-tools # Activar el reenvio de paquetes IPv4 (y IPv6 si lo usas) echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-wireguard.conf sudo sysctl --system # Generar las claves del servidor cd /etc/wireguard && umask 077 wg genkey | tee server_private.key | wg pubkey > server_public.key
Elige bien el rango de la VPN
Usa un rango privado que no choque con ninguna red a la que te vayas a conectar · 10.0.0.0/8 y 192.168.0.0/16 son justo los que usan casi todos los routers domésticos y oficinas · El rango 100.64.0.0/10 (CGNAT) o un /24 poco común como 10.77.33.0/24 te evitan colisiones de rutas
4. El fichero del servidor: wg0.conf
El servidor se configura en `/etc/wireguard/wg0.conf`. Este ejemplo monta un full tunnel (todo el tráfico del cliente sale por el servidor) para dos dispositivos:
[Interface] # IP del servidor DENTRO de la VPN, y mascara del rango completo Address = 10.77.33.1/24 # Puerto UDP en el que escucha (elige uno; 51820 es el de facto) ListenPort = 51820 # Clave privada del servidor (contenido de server_private.key) PrivateKey = <SERVER_PRIVATE_KEY> # Al levantar: activar NAT para que el trafico de la VPN salga a internet PostUp = iptables -t nat -A POSTROUTING -s 10.77.33.0/24 -o eth0 -j MASQUERADE PostUp = iptables -A FORWARD -i wg0 -j ACCEPT # Al bajar: deshacer exactamente lo anterior PostDown = iptables -t nat -D POSTROUTING -s 10.77.33.0/24 -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -j ACCEPT [Peer] # portatil PublicKey = <LAPTOP_PUBLIC_KEY> # Que IP(s) se le permiten a ESTE par dentro del tunel (aqui, una sola) AllowedIPs = 10.77.33.2/32 [Peer] # movil PublicKey = <PHONE_PUBLIC_KEY> AllowedIPs = 10.77.33.3/32
Sustituye `eth0` por el nombre real de la interfaz de salida del servidor (`ip route show default` te lo dice). Cada `[Peer]` es un dispositivo autorizado; su `AllowedIPs` con máscara `/32` significa «este par solo puede usar esta única dirección», lo que evita que un cliente suplante a otro.
4.1 Arrancar y comprobar
# Levantar el tunel ahora y activarlo en cada arranque sudo wg-quick up wg0 sudo systemctl enable wg-quick@wg0 # Ver estado: claves, ultimo handshake, bytes transferidos por par sudo wg show # Parar / reiniciar sudo wg-quick down wg0
5. El fichero del cliente
Cada dispositivo lleva su propio `wg0.conf`. Este es el del portátil del ejemplo anterior:
[Interface] # IP de ESTE cliente dentro de la VPN (coincide con su AllowedIPs en el servidor) Address = 10.77.33.2/32 PrivateKey = <LAPTOP_PRIVATE_KEY> # DNS que usara el cliente mientras el tunel este activo DNS = 10.77.33.1 # o 1.1.1.1 / 9.9.9.9 / tu Pi-hole [Peer] # Clave publica del SERVIDOR PublicKey = <SERVER_PUBLIC_KEY> # Direccion publica y puerto del servidor Endpoint = vpn.midominio.com:51820 # full tunnel: enruta TODO el trafico por la VPN AllowedIPs = 0.0.0.0/0, ::/0 # Mantener viva la sesion a traves de NAT/firewall (util en el movil) PersistentKeepalive = 25
Para un split tunnel —solo enrutar el acceso a tu red de casa y dejar el resto por la conexión normal— cambias esa línea por el rango concreto, por ejemplo `AllowedIPs = 192.168.1.0/24`. Ahí se ve la doble función del campo.
6. AllowedIPs: enrutado y cortafuegos a la vez
Es el concepto que más confunde al empezar. `AllowedIPs` significa cosas distintas según el lado:
| Dónde aparece | Qué hace realmente |
|---|---|
| En el cliente, dentro de [Peer] (el servidor) | Tabla de rutas: qué destinos se envían POR el túnel. 0.0.0.0/0 = todo; un /24 = solo esa red |
| En el servidor, dentro de [Peer] (cada cliente) | Control de acceso: qué IPs de origen se aceptan de ese par. Un paquete con otra IP se descarta |
| En ambos casos | WireGuard usa la clave pública para elegir el par y AllowedIPs para decidir si el paquete es válido — es criptografía + filtrado en un solo paso (cryptokey routing) |
Regla práctica
En el servidor, da a cada cliente un /32 (una sola IP) · Si un cliente hace de puerta a una red entera (site-to-site), entonces sí pones su /24 en el servidor y añades esa red al AllowedIPs de los demás · Nunca pongas 0.0.0.0/0 en el AllowedIPs de un cliente dentro de la config del servidor: le estarías permitiendo suplantar cualquier origen
7. DNS, fugas y kill switch
7.1 Fugas de DNS
De nada sirve cifrar el tráfico si tu dispositivo sigue preguntando «¿qué IP tiene ejemplo.com?» al DNS de la cafetería. El campo `DNS` del cliente fuerza a que las consultas vayan por el túnel. En Linux, `wg-quick` lo aplica vía `resolvconf` o `systemd-resolved`; comprueba el resultado en dnsleaktest.com tras conectar.
7.2 Kill switch
Un kill switch corta todo el tráfico si el túnel se cae, para que nada salga «en claro» por error. Con `wg-quick` se consigue de forma sencilla:
# En el [Interface] del cliente Linux: bloquea trafico fuera del tunel PostUp = iptables -I OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT PreDown = iptables -D OUTPUT ! -o wg0 -m mark ! --mark $(wg show wg0 fwmark) -m addrtype ! --dst-type LOCAL -j REJECT # Las apps oficiales de Android / iOS / Windows lo traen como casilla: # 'Block connections without VPN' / 'Kill switch'
8. Clientes móviles y de escritorio
- Android / iOS: app oficial «WireGuard». Importa la config escaneando un código QR — `qrencode -t ansiutf8 < cliente-movil.conf` lo genera en el terminal del servidor
- Windows / macOS: app oficial de gráfica; importa el `.conf` y añade túneles
- Linux escritorio: `wg-quick` a mano, o integración en NetworkManager (`nmcli connection import type wireguard file cliente.conf`)
- Genera un par de claves distinto por dispositivo. Nunca reutilices la misma config en dos equipos: romperías el enrutado por clave y no podrías revocar solo uno
9. Herramientas de gestión
Editar `wg0.conf` a mano está bien para 3-4 dispositivos. A partir de ahí, conviene una capa por encima:
| Herramienta | Qué aporta |
|---|---|
| wg-easy | Panel web sencillo en un contenedor: crear/borrar clientes, ver tráfico, generar QR. Sigue siendo WireGuard puro por debajo |
| Tailscale | Malla WireGuard gestionada: NAT traversal automático, sin abrir puertos, control de acceso por identidad. El plano de control es de un tercero |
| Headscale | Implementación libre y autoalojada del plano de control de Tailscale: te quedas la comodidad sin depender de su servidor |
| Netmaker / Firezone | Orientadas a organizaciones: interfaz, roles, registro de accesos, integración con SSO |
¿VPN propia o malla?
Un wg0.conf clásico es ideal para «salir a internet por mi VPS» o «entrar a mi casa» · Tailscale/Headscale brillan cuando quieres que 10 dispositivos en 5 redes distintas se vean entre sí sin configurar rutas ni port forwarding a mano · Las dos usan el mismo cifrado WireGuard: la diferencia es quién orquesta las claves y las rutas
10. Buenas prácticas y errores habituales
- Permisos `600` (o `077` de umask) en todo `/etc/wireguard`: la clave privada en claro es la única credencial que hay
- Haz que el `Endpoint` sea un dominio, no una IP: si el servidor cambia de IP, actualizas el DNS y los clientes siguen funcionando
- En un VPS, deja el firewall (o el grupo de seguridad) abriendo solo el puerto UDP de WireGuard y el de SSH; todo lo demás, cerrado
- `PersistentKeepalive` solo hace falta en el lado que está detrás de NAT (típicamente los clientes), no en un servidor con IP pública
- Si el handshake no ocurre (`wg show` no muestra «latest handshake»): casi siempre es el puerto UDP cerrado en el proveedor, `ip_forward` desactivado, o un desajuste entre `AllowedIPs` y la `Address` del cliente
- Haz copia de la carpeta de claves. Si pierdes la clave privada del servidor, todos los clientes hay que reconfigurarlos
Encuadre: esto es para tu propia red
Una VPN propia se monta sobre infraestructura tuya: un VPS que has contratado a tu nombre o un equipo de tu domicilio · Enrutar tráfico de terceros, saltarte los controles de red de tu empresa o de un centro educativo sin autorización, u ofrecer salida a internet a otras personas puede infringir las condiciones del servicio y, según el uso, la normativa aplicable · El objetivo aquí es reducir en quién tienes que confiar para tu propio tráfico, no habilitar el de otros
Conclusión
Montar tu propia VPN con WireGuard cierra el círculo que dejaba abierto el artículo sobre VPN comerciales: el servidor donde se descifra tu tráfico es tuyo, y la política de logs la decides tú porque eres quien administra la máquina. A cambio asumes el mantenimiento —parches, copias de las claves, vigilar que el VPS siga en pie— y pierdes la red de decenas de países que ofrece un proveedor de pago.
Para el caso de uso más común —cifrar tu conexión en redes públicas y volver a entrar a tu red de casa desde fuera— ese intercambio sale claramente a favor de hacerlo tú. WireGuard ha convertido lo que antes era un proyecto de administrador de sistemas en algo que cabe en dos ficheros de veinte líneas, y eso es precisamente lo que lo hace difícil de configurar mal.
Referencias
wireguard.com — Documentación oficial, whitepaper del protocolo y apps por plataforma · wireguard.com/quickstart — Guía rápida de wg-quick · github.com/wg-easy/wg-easy — Panel web para gestionar clientes · headscale.net — Plano de control libre compatible con los clientes de Tailscale · Nuestro artículo «VPN, Tor y proxy: qué te protege realmente y de qué», para el marco conceptual
unfantasmaenelsistema.com | Seguridad, sistemas y todo lo que no debería funcionar (pero funciona)

