WireGuard es un protocolo VPN moderno integrado en el núcleo de Linux: usa criptografía actual, tiene muy poco código y suele ser más rápido y sencillo de configurar que OpenVPN o IPsec. En este tutorial montarás un servidor WireGuard en Ubuntu 24.04 configurado a mano, sin scripts de terceros, para que sepas exactamente qué hace cada línea. Al terminar, tus dispositivos saldrán a Internet a través del servidor y podrás añadir clientes nuevos cuando quieras.
Requisitos previos
Para seguir esta guía necesitas:
- Un servidor con Ubuntu 24.04 LTS y una IP pública, por ejemplo un VPS de CubePath. En Debian 12 los pasos son los mismos.
- Un usuario no root con privilegios
sudo. - UFW activo con SSH permitido. Si aún no lo tienes, sigue una guía de configuración de UFW antes de empezar.
- Un dispositivo cliente con la aplicación oficial de WireGuard (Windows, macOS, Android, iOS) o el paquete
wireguarden Linux.
En la guía se usa la red interna 10.8.0.0/24 para la VPN: el servidor tendrá la 10.8.0.1 y el primer cliente la 10.8.0.2.
Paso 1: Instalar WireGuard
WireGuard está en los repositorios oficiales de Ubuntu. Instala también qrencode, que usarás para pasar la configuración al móvil:
sudo apt update
sudo apt install wireguard qrencode
Comprueba que las herramientas están disponibles:
wg --version
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/
Paso 2: Generar las claves del servidor
Cada extremo de un túnel WireGuard tiene un par de claves: una privada, que nunca sale del equipo, y una pública, que compartes con el otro extremo. Genera las del servidor dentro de /etc/wireguard con permisos restrictivos (umask 077 hace que solo root pueda leer los archivos):
sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
exit
Muestra la clave privada, que necesitarás en el siguiente paso:
sudo cat /etc/wireguard/server.key
Paso 3: Configurar la interfaz wg0
Averigua el nombre de la interfaz pública del servidor, la que tiene la ruta por defecto:
ip route show default
default via 203.0.113.1 dev eth0 proto static
En este ejemplo es eth0. Crea el archivo de configuración del túnel:
sudo nano /etc/wireguard/wg0.conf
Pega el siguiente contenido, sustituyendo clave_privada_del_servidor por el contenido de server.key:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = clave_privada_del_servidor
Addresses la IP del servidor dentro de la VPN.ListenPortes el puerto UDP en el que escucha WireGuard.51820es el habitual.
Los clientes (secciones [Peer]) se añaden más adelante.
Paso 4: Activar el reenvío de paquetes
Para que el servidor encamine el tráfico de los clientes hacia Internet, el núcleo debe reenviar paquetes entre interfaces. Crea un archivo de sysctl:
sudo nano /etc/sysctl.d/99-wireguard.conf
net.ipv4.ip_forward = 1
Aplica el cambio y compruébalo:
sudo sysctl --system
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Paso 5: Configurar UFW y el NAT
Hay que hacer tres cosas en el cortafuegos: abrir el puerto de WireGuard, permitir el tráfico reenviado desde el túnel y enmascarar (NAT) las IPs de la VPN tras la IP pública del servidor.
Abre el puerto UDP:
sudo ufw allow 51820/udp
Permite que el tráfico que entra por wg0 salga por la interfaz pública (UFW bloquea el tráfico reenviado por defecto). Sustituye eth0 si tu interfaz tiene otro nombre:
sudo ufw route allow in on wg0 out on eth0
Para el NAT, edita las reglas previas de UFW:
sudo nano /etc/ufw/before.rules
Añade este bloque al principio del archivo, antes de la línea *filter:
# NAT para la VPN WireGuard
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
Recarga UFW y comprueba las reglas:
sudo ufw reload
sudo ufw status verbose
To Action From
-- ------ ----
OpenSSH ALLOW IN Anywhere
51820/udp ALLOW IN Anywhere
Anywhere on eth0 ALLOW FWD Anywhere on wg0
Paso 6: Arrancar el servidor WireGuard
WireGuard incluye la unidad de systemd wg-quick@, que levanta la interfaz a partir del archivo wg0.conf. Actívala para que arranque también tras cada reinicio:
sudo systemctl enable --now wg-quick@wg0
Comprueba el estado del servicio y de la interfaz:
sudo systemctl status wg-quick@wg0
sudo wg show
interface: wg0
public key: Qd3xT0...=
private key: (hidden)
listening port: 51820
Paso 7: Crear el primer cliente
Genera las claves del cliente en el servidor. Es más cómodo para un móvil; si prefieres que la clave privada no pase nunca por el servidor, genera el par en el propio cliente y copia solo la clave pública.
sudo -i
mkdir -p /etc/wireguard/clients
cd /etc/wireguard/clients
umask 077
wg genkey | tee movil.key | wg pubkey > movil.pub
exit
Añade el cliente al servidor como [Peer]. AllowedIPs indica qué IP de la VPN corresponde a este cliente:
sudo nano /etc/wireguard/wg0.conf
Añade al final del archivo, sustituyendo clave_publica_del_cliente por el contenido de movil.pub:
[Peer]
# movil
PublicKey = clave_publica_del_cliente
AllowedIPs = 10.8.0.2/32
Aplica el cambio sin cortar las conexiones activas. wg-quick strip convierte el archivo al formato que entiende wg syncconf:
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'
Crea ahora el archivo de configuración del cliente:
sudo nano /etc/wireguard/clients/movil.conf
Sustituye clave_privada_del_cliente (contenido de movil.key), clave_publica_del_servidor (contenido de /etc/wireguard/server.pub) e ip_del_servidor:
[Interface]
PrivateKey = clave_privada_del_cliente
Address = 10.8.0.2/32
DNS = 1.1.1.1, 9.9.9.9
[Peer]
PublicKey = clave_publica_del_servidor
Endpoint = ip_del_servidor:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
AllowedIPs = 0.0.0.0/0envía todo el tráfico IPv4 del cliente por la VPN. Si solo quieres acceder a la red de la VPN, usa10.8.0.0/24.PersistentKeepalive = 25mantiene el túnel abierto cuando el cliente está detrás de un NAT, como el de un router doméstico o una red móvil.
Paso 8: Conectar el cliente
En un móvil, abre la aplicación de WireGuard, pulsa en añadir túnel, elige escanear código QR y escanea el que muestra este comando:
sudo qrencode -t ansiutf8 < /etc/wireguard/clients/movil.conf
En Windows o macOS, copia el archivo movil.conf al equipo por un canal seguro (por ejemplo con scp) e impórtalo desde la aplicación con la opción de importar túnel desde archivo.
En Linux, instala wireguard, guarda el archivo como /etc/wireguard/wg0.conf y levanta el túnel con sudo wg-quick up wg0. Si al levantarlo aparece resolvconf: command not found, crea el enlace de compatibilidad con systemd-resolved, que acepta la sintaxis de resolvconf:
sudo ln -s /usr/bin/resolvectl /usr/local/bin/resolvconf
Activa el túnel en el cliente y comprueba en el servidor que hay un saludo (handshake) reciente:
sudo wg show
peer: 7bH2kL...=
endpoint: 198.51.100.23:53012
allowed ips: 10.8.0.2/32
latest handshake: 5 seconds ago
transfer: 45.21 KiB received, 102.84 KiB sent
Desde el cliente, comprueba que tu IP pública es ahora la del servidor, por ejemplo abriendo https://ifconfig.me en el navegador o, en Linux:
curl -4 https://ifconfig.me
203.0.113.10
Añadir más clientes
Para cada dispositivo nuevo, repite el paso 7 con otro nombre de archivo y la siguiente IP libre (10.8.0.3/32, 10.8.0.4/32...), tanto en el [Peer] del servidor como en Address del cliente. Cada dispositivo debe tener su propio par de claves: no reutilices una configuración en varios equipos a la vez.
Para revocar un cliente, borra su bloque [Peer] de wg0.conf y vuelve a ejecutar sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'.
Solución de problemas
latest handshakeno aparece. El cliente no llega al servidor. Confirma que51820/udpestá abierto en UFW y queEndpointapunta a la IP y puerto correctos. Revisa también que la clave pública de cada lado corresponde a la privada del otro.- Hay handshake pero no hay Internet. Suele ser el reenvío o el NAT. Comprueba
sysctl net.ipv4.ip_forward, que el nombre de interfaz enbefore.rulesy en la reglaufw routees el correcto, y que ejecutastesudo ufw reload. - Navegas pero no resuelve nombres. Revisa la línea
DNSdel cliente. En Linux, confirma que el comandoresolvconfexiste (ver paso 8). - El servicio no arranca. Consulta
sudo journalctl -u wg-quick@wg0para ver el error exacto, normalmente una clave mal copiada o una línea mal escrita enwg0.conf.
Conclusión
Tienes un servidor VPN WireGuard propio, configurado a mano, que arranca con el sistema y enruta el tráfico de tus dispositivos a través de la IP del servidor. Como siguientes pasos, puedes añadir IPv6 a la VPN, usar AllowedIPs para dar acceso solo a redes privadas concretas en lugar de todo el tráfico, o restringir los servicios internos del servidor para que solo escuchen en 10.8.0.1.
