Como configurar una VPN con WireGuard

Wireguard Vpn Configuracion Inicial

En otro articulo os cuento el proceso de alta en hetzner y la parte de creación y hardening basico del servidor.

En este articulo quiero mostrar como configurar una conexión VPN con WireGuard. Concretamente en un servidor de Hetzener. Quiero ir un paso mas hallá con la configuración del VPN y realizar dos configuraciones:

  • Un perfil básico para tener conexión privada con el servidor a través de la VPN. De esta manera poder habilitar solo la conexión ssh con vpn y no exponer ssh publicamente.
  • Un segundo perfil que no solo conecte con el servidor, si no, que enrute todo el tráfico y use el servidor como salida, como si se tratara de un VPN comercial, para poder navegar ocultando tu ip y mostrando la del servidor.

Idea inicial

  • Servidor en Hetzner, en este caso con Debian 12.
  • Cliente: Puedes usar el que quieras, ya que el resultado en un archivo de configuración. En este caso te enseño com conectarte desde un macbook.

En mi caso, lo he usado para conectar con el servidor en la nube, pero podrías usarlo para conectarte a tu servidor de homelab y poder usar los servicios que tengas en tu red, como podría ser jellyfin, seafile, etc. O para que la IP de salida sea la de tu casa, para evitar problemas con netflix/disney y similar o incluso para trabajar en remoto y que a efectos de IP, estes conectado desde tu casa.

Comentar que en la práctica, uso Tailscale para conectarme a los servicios de mi homelab, pero ya hablaré de Tailscale en otro articulo.

Antes de empezar

¿Qué es y por qué Wireguard?

WireGuard es una VPN moderna, rápida y ligera. A diferencia de opciones tradicionales como OpenVPN o IPSec, WireGuard se basa en un diseño minimalista: menos código, menos complejidad, menos margen de error. Usa criptografía de última generación (como Curve25519 y ChaCha20) y está pensado para ser fácil de configurar, auditar y mantener.

Te recomiendo estos dos videos sencillos y rápidos sobre wireguard:

Indice del paso a paso a nivel conceptual

  1. Acceder al servidor por ssh e instalación wireguard
  2. Generar claves de wireguard en el servidor
  3. Configuración de los perfiles
    1. Activación del reenvio de paquetes
    2. Configuración del cortafuegos
  4. Iniciar el servicio de wireguard
  5. Generación de los perfiles de los clientes
  6. Configuración de los clientes
  7. Conexion de los clientes y test

Paso a paso

Acceso inicial al servidor e instalación de wireguard

Entramos por ssh al servidor, ya sea por contraseña o usando claves, actualizamos el sistema e instalamos wireguard.

ssh root@IP_SERVIDOR 

# una vez dentro de la maquina

apt update && apt upgrade -y

apt install wireguard -y

`

Generación de claves de wireguard

WireGuard usa un par de claves (privada y pública) para identificar a cada nodo.

umask 077
wg genkey | tee /etc/wireguard/privatekey | wg pubkey > /etc/wireguard/publickey

Esto:

  • Aplica permisos seguros (para que nadie más pueda leer las claves)
  • Crea dos archivos:
    • /etc/wireguard/privatekey
    • /etc/wireguard/publickey

Con estas claves vamos a generar el arcivho de congfiguración de wireguard.

Creación de wg0.conf

Creamos el archivo wg0.conf, por ejemplo en, /etc/wireguard/wg0.conf

[Interface]
PrivateKey = TU_CLAVE_PRIVADA
Address = 10.8.0.1/24
ListenPort = 51820
SaveConfig = true

# Opcional (activamos reenvío IP, importante para redireccionar tráfico)
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; ufw route allow in on wg0 out on eth0
PostDown = sysctl -w net.ipv4.ip_forward=0; iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; ufw route delete allow in on wg0 out on eth0

En private key, ponemos el contenido de /etc/wireguard/privatekey

Address, esta será la red que vamos a crear y la IP de la máquina por VPN será 10.8.0.1

Por defecto se suele usar el puerto 51820, pero podemos usar el que queramos, importante saber que wireguard usa UDP, por si tenemos que configurar el firewall, debemos de anotar el puerto que estamos usando.

  • PrivateKey: la clave del servidor
  • Address: IP interna del servidor en la red VPN
  • ListenPort: puerto UDP (puedes cambiarlo si usas otro)
  • SaveConfig: guarda cambios si haces modificaciones con wg
  • PostUp/PostDown: activa y desactiva el reenvío de IPs automáticamente
    • La regla ufw route allow in on wg0 out on eth0 es necesaria si estás usando UFW, como en mi caso.

Abrir los puertos del firewall (UFW en mi caso)

Es importante saber como se enruta y filtra el trafico en tu red, o en servidor en concreto. Por ejemplo, Hetzner, cuenta con un firewall que puedes ajustar desde el dashbord centra y aplicarlo al servidor, luego, dentro del servidor puedes configurar como mi caso, un firewall.

Si tienes firewall activado, seguro que sabes como permitir la entrado por un puerto. En mi caso:

ufw allow 51820/udp

Activar el reenvio de IPs (IP Forwarding)

Esto es necesario si queremos enrutar el tráfico y “enmascarar nuestra IP” para navegar con la IP del servidor.

Editamos sysctl.conf:

nano /etc/sysctl.conf

Buscamos o añadimos la siguiente declaración:

net.ipv4.ip_forward=1

Aplicamos el cambio sin reiniciar con:

sysctl -p
#deberiamos de ver "net.ipv4.ip_forward = 1"

Activar la interfaz wg0

Con este paso, levantamos la interface y ponemos el marcha el servidor VPN.

wg-quick up wg0

#deería ver algo como esto:
# [#] ip link add wg0 type wireguard
# [#] wg setconf wg0 /dev/fd/63
# [#] ip address add 10.8.0.1/24 dev wg0
# [#] ip link set up dev wg0

Para verificar si esta funcionando puedes usar el comando: wg y verás la configuración activa de wg0, incluyendo tu clave pública y puerto.

Crear las claves del cliente

En el servidor, ejecutamos lo siguiente. Yo lo he llamado mac, tu puedes llamarlo como quieras. Ten en cuenta que lo que vas a crear ahora es un archivo.conf que tendras que usar en el cliente, puedes usar el mismo para conectarte desde tu mac o desde tu movil, pero no a la vez, si requieres conexión de varios dispositivos a la vez deberias crear un perfil para cada cliente.

mkdir -p ~/wireguard/clients/mac
cd ~/wireguard/clients/mac

wg genkey | tee privatekey | wg pubkey > publickey

Esto te genera dos archivos:

  • privatekey → clave privada del cliente (Mac)
  • publickey → clave pública del cliente (se añade al servidor)

Crear el archivo.conf para importar en la app WireGuard

Aqui vamos a crear dos perfiles, uno para enrutar todo el tráfico (mac-routing.conf) y otro para solo conectarnos a la máquina (mac.conf)

mac-routing.conf

# estamos en ~/wireguard/clients/mac
nano mac-routing.conf

#añadimos lo siguiente:
[Interface]
PrivateKey = TU_CLAVE_PRIVADA_DEL_CLIENTE
Address = 10.8.0.2/32
DNS = 9.9.9.9

[Peer]
PublicKey = CLAVE_PUBLICA_DEL_SERVIDOR
Endpoint = IPV4_DEL_SERVIDOR:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25
  • TU_CLAVE_PRIVADA_DEL_CLIENTE → contenido de privatekey
  • CLAVE_PUBLICA_DEL_SERVIDOR → contenido de /etc/wireguard/publickey
  • En DNS, el servidor dns a usar.
  • Importante el AllowedIPs poner 0.0.0.0/ para enrutar todo el trafico.

mac.conf

En este archivo lo único que cambia es la linea “AllowedIPs” donde le decimos la IP de la interface wg0.

# estamos en ~/wireguard/clients/mac
nano mac.conf

#añadimos lo siguiente:
[Interface]
PrivateKey = TU_CLAVE_PRIVADA_DEL_CLIENTE
Address = 10.8.0.2/32
DNS = 9.9.9.9

[Peer]
PublicKey = CLAVE_PUBLICA_DEL_SERVIDOR
Endpoint = IPV4_DEL_SERVIDOR:51820
AllowedIPs = 10.8.0.1/32
PersistentKeepalive = 25

Añadir el cliente al servidor de wireguard

nano /etc/wireguard/wg0.conf

Y añadimos el cliente (peer) quedando el archivo de la siguiente manera.

[Interface]
Address = 10.8.0.1/24
DNS = 9.9.9.9
SaveConfig = true
PostUp = sysctl -w net.ipv4.ip_forward=1; iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; ufw route allow in on wg0 out on eth0
PostDown = sysctl -w net.ipv4.ip_forward=0; iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE; ufw route delete allow in on wg0 out on eth0
ListenPort = 51820
PrivateKey = TU_CLAVE_PRIVADA_DEL_SERVIDOR

[Peer]
PublicKey = CLAVE_PUBLICA_DEL_CLIENTE #(~/wireguard/clients/mac/publickey)
AllowedIPs = 10.8.0.2/32

Guardamos y aplicamos cambios con:

wg-quick down wg0 && wg-quick up wg0

Importar el perfil en el cliente

Esto puede hacerse con QR o con el propio archivo mac-routing.conf

Para descargar el archivo mac-routing.conflo mas sencillo es hacer un cat y copiarlo a tu máquina local.

cat ~/wireguard/clients/mac/mac-routing.conf

Lo copiamos y creamos un archivo en nuestro editar favorito en nuestro equipo local. Lo llamamos como queramos, pero para ser consistentes lo llamaremos igual “mac-routing.conf” o “mac.conf”

También lo puedes hacer de una manera un poco mas sofisticiada con scpque usa la conexión ssh para copiar archivos:

scp root@IP_DEL_SERVIDOR:~/wireguard/clients/mac/mac.conf ~/Downloads/

Importar el perfil (archivo.conf) a WireGuard

Descargamos e instalamos la app, que puedes encontrar aquí: https://www.wireguard.com/install/

Importamos el archivo.conf, activamos la conexión y para probarlo podemos hacer en la terminal.

Comprobando la conexion

Ahora vamos a cerrar la conexión ssh que tenemos abierta y tratar de entrar por el tunnel VPN.

Primero podemos probar si la conexión con el servidor por VPN esta activa:

ping 10.8.0.1

Igual que antes haciamos ssh root@ipv4 del servidor ahora tendremos que usar la conexión VPN que acabamos de configurar y activar:

ssh root@10.8.0.1

Y con esto ya hemos finalizado con configuración y tenemos acceso al servidor mediante tunel VPN.

Podemos probar la otra configuración, la que nos permite enrutar todo el tráfico y ya siemplemente activando el perfil en wireguard estaremos navegando con la IP de nuestro servidor. (Puedes comprobarlo aqui: ipinfo.io )

Problemas encontrados por el camino y solución

Esto es una recopilación de errores y pequeños problemas que he tenido en el proceso de instalación. Arriba te muestro el paso a paso ya corregido, pero cuando lo hice en su día, tuve estos problemas.

Confundir las claves privadas/publicas en los archivos de configuración.

Confundí las claves del servidor y las del cliente, y estaban mal en el archivo de configuración… revisa que esten bien las claves publicas y privadas del los archivos de configuración.

Vpn Wireguard Esquema

Interfaz wg0 no persistía tras reinicio

Al reiniciar el servidor, la interfaz wg0 de WireGuard no se levantaba automáticamente.

Para activarlo, por defecto y que el sistema la levante al iniciarse:

sudo systemctl enable wg-quick@wg0

Posibles problemas: UFW vs iptables

Cuando configuramos el enrutamiento de tráfico en una VPN WireGuard, es muy común encontrarse con tutoriales que te dicen que debes hacer algo como esto:
(que es lo que me indico Chatgpt en primer lugar)

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

Esto añade una regla para que los paquetes que salen desde la red de la VPN (en este caso 10.8.0.0/24) sean “disfrazados” con la IP del servidor (la interfaz eth0), y así puedan salir a Internet correctamente. Esta es una forma directa de usar iptables.

Pero, si tienes ufw (Uncomplicated Firewall) activo, esto puede no funcionar como esperas.

¿Por qué?

Porque cuando ufw está activo, se encarga de gestionar internamente sus propias reglas de iptables, y puede ignorar o incluso borrar las reglas que añadiste a mano con iptables.

Si, como yo, estas usando UFW, debes aplicar esto a la configuraión:

ufw route allow in on wg0 out on eth0

Esto le dice a ufw que permita reenviar tráfico desde la interfaz de WireGuard (wg0) hacia la interfaz de salida (eth0).

Resumen:

  • Si no usas ufw: puedes usar reglas iptables directamente.
  • Si usas ufw: no uses solo iptables, haz el enrutamiento con ufw route allow.