A) VPN de acceso remoto con OpenVPN y certificados x509

Escenario:

Escenario de red para la VPN de acceso remoto con OpenVPN

El escenario ya está montado con su reenvío de paquetes, ips, snat; en esta práctica simplemente nos centraremos en el servidor y en el cliente para que se comunique con el servidor. Sabiendo esto, lo primero que vamos a hacer es configurar el ServidorVPN.

Instalación de OpenVPN y OpenSSL

1sudo apt update && sudo apt install openvpn openssl -y

Y vamos a crear también la estructura de los directorios: en la carpeta ca tendremos los certificados de la autoridad certificadora, en servidor los certificados del servidorvpn, y en cliente los certificados del clientevpn.

1sudo mkdir -p /etc/openvpn/ca
2sudo mkdir -p /etc/openvpn/servidor
3sudo mkdir -p /etc/openvpn/cliente

Generar Certificados

Generar la Autoridad Certificadora

Generamos la clave privada de la CA:

1sudo openssl genrsa -out /etc/openvpn/ca/ca.key 2048

Vamos a generar ahora el certificado autofirmado de la CA:

1sudo openssl req -new -x509 -days 3650 \
2-key /etc/openvpn/ca/ca.key \
3-out /etc/openvpn/ca/ca.crt \
4-subj "/C=ES/ST=Sevilla/L=DosHermanas/O=iesgn/OU=informatica/CN=CA-josemanuel/emailAddress=hola@gmail.com"

Generar certificado del Servidor

Generamos la clave privada del servidor:

1sudo openssl genrsa -out /etc/openvpn/servidor/servidor.key 2048

Y generamos el CSR del servidor:

1sudo openssl req -new -key /etc/openvpn/servidor/servidor.key -out /etc/openvpn/servidor/servidor.csr -subj "/C=ES/ST=Sevilla/L=DosHermanas/O=iesgn/OU=informatica/CN=servidor.iesgn.org/emailAddress=adios@gmail.com"

Ahora firmamos el certificado del servidor con la CA:

1sudo openssl x509 -req -days 3650 \
2-in /etc/openvpn/servidor/servidor.csr \
3-CA /etc/openvpn/ca/ca.crt \
4-CAkey /etc/openvpn/ca/ca.key \
5-set_serial 01 \
6-out /etc/openvpn/servidor/servidor.crt

Generar certificado del CLIENTE

Generamos también la clave privada del cliente:

1sudo openssl genrsa -out /etc/openvpn/cliente/josemanuel.key 2048

Generamos el CSR del cliente:

1sudo openssl req -new -key /etc/openvpn/cliente/josemanuel.key -out /etc/openvpn/cliente/josemanuel.csr -subj "/C=ES/ST=Sevilla/L=DosHermanas/O=iesgn/OU=informatica/CN=cliente.iesgn.org/emailAddress=cliente@gmail.com"

Y lo firmamos con la CA:

1sudo openssl x509 -req -days 3650 \
2-in /etc/openvpn/cliente/josemanuel.csr \
3-CA /etc/openvpn/ca/ca.crt \
4-CAkey /etc/openvpn/ca/ca.key \
5-set_serial 02 \
6-out /etc/openvpn/cliente/josemanuel.crt

Generar parámetros Diffie-Hellman

Diffie-Hellman es un algoritmo matemático que permite que cliente y servidor acuerden una clave secreta compartida sin enviarla por la red.

1sudo openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Generación de los parámetros Diffie-Hellman en la terminal

Vemos que todo está bien estructurado:

Estructura de directorios de OpenVPN verificada con tree

Crear archivos de extensiones X509v3

Vamos a tener que crear también unos archivos de extensiones X509v3, ya que OpenVPN verifica que el certificado sea específicamente para servidor o cliente y, sin estas extensiones, OpenVPN rechaza la conexión.

Este es para el servidor:

1sudo nano /etc/openvpn/servidor-ext.cnf
1keyUsage = digitalSignature, keyEncipherment
2extendedKeyUsage = serverAuth

Cliente:

1sudo nano /etc/openvpn/cliente-ext.cnf
1keyUsage = digitalSignature
2extendedKeyUsage = clientAuth

digitalSignature firma datos para probar que vienen del servidor. keyEncipherment cifra las claves simétricas que luego se usan para cifrar el túnel VPN. serverAuth es que solo se puede usar para autenticarse como servidor. clientAuth es que solo se puede usar para autenticarse como cliente.

Configurar el servidor OpenVPN

Creamos el archivo de configuración del servidor:

1sudo nano /etc/openvpn/servidor.conf
 1port 1194
 2proto udp
 3dev tun
 4ca /etc/openvpn/ca/ca.crt
 5cert /etc/openvpn/servidor/servidor.crt
 6key /etc/openvpn/servidor/servidor.key
 7dh /etc/openvpn/dh2048.pem
 8server 10.99.99.0 255.255.255.0
 9persist-key
10persist-tun
11status /var/log/openvpn-status.log
12log-append /var/log/openvpn.log
13verb 3
14duplicate-cn
15keepalive 10 120

Explicación de cada parámetro:

  • port 1194: Puerto UDP donde el servidor escucha conexiones entrantes.
  • proto udp: Protocolo de transporte. UDP es mejor que TCP para la VPN, para una menor latencia y mejor rendimiento.
  • dev tun: Tipo de interfaz virtual.
  • ca /etc/openvpn/ca/ca.crt: Certificado de la Autoridad Certificadora, valida la autenticidad de certificados de servidor y clientes.
  • cert /etc/openvpn/servidor/servidor.crt: Certificado público del servidor, identifica el servidor ante los clientes.
  • key /etc/openvpn/servidor/servidor.key: Clave privada del servidor, usada para descifrar y firma digital.
  • dh /etc/openvpn/dh2048.pem: Parámetros Diffie-Hellman, permiten el intercambio seguro de claves simétricas mediante Perfect Forward Secrecy (PFS).
  • server 10.99.99.0 255.255.255.0: Define la red del túnel VPN; el servidor toma 10.99.99.1 y asigna IPs del rango 10.99.99.4-10.99.99.251 a los clientes.
  • persist-key: Mantiene las claves criptográficas y evita relectura de archivos protegidos por permisos restrictivos.
  • persist-tun: Mantiene la interfaz TUN abierta durante reinicios suaves y previene pérdida temporal de conectividad.
  • status /var/log/openvpn-status.log: Archivo de estado con clientes conectados, IPs asignadas, bytes transferidos y timestamp de última actividad.
  • log-append /var/log/openvpn.log: Registro acumulativo de eventos, esencial para auditoría y troubleshooting.
  • verb 3: Nivel de verbosidad (0-11). 3 es producción estándar: muestra conexiones, desconexiones y errores sin exceso de detalle.
  • duplicate-cn: Permite múltiples conexiones simultáneas con el mismo Common Name; por defecto, OpenVPN rechaza conexiones duplicadas por seguridad.
  • keepalive 10 120: Envía ping cada 10 segundos y, si no hay respuesta en 120 segundos, reinicia la conexión.

Habilitamos el IP Forwarding en el ServidorVPN

1sudo nano /etc/sysctl.conf

Descomentamos la siguiente línea:

Descomentando net.ipv4.ip_forward en /etc/sysctl.conf

Aplicamos cambios y verificamos:

1sudo sysctl -p
2cat /proc/sys/net/ipv4/ip_forward

Verificación del IP forwarding habilitado

Iniciar OpenVPN

1sudo systemctl start openvpn@servidor
2sudo systemctl enable openvpn@servidor
3sudo systemctl status openvpn@servidor

Servicio openvpn@servidor activo y corriendo

Y como vemos, ya nos aparece la interfaz tun0 levantada:

Salida de ip a mostrando la interfaz tun0 del servidor

Configuración Cliente

Tenemos que copiar los certificados desde ServidorVPN a ClienteVPN; para ello nos pasaremos los certificados o bien por correo cifrado, scp… etc.

Estructura de archivos de certificados ya copiados en ClienteVPN

Crear la configuración del cliente

1sudo nano /etc/openvpn/cliente.conf
 1client
 2dev tun
 3proto udp
 4
 5remote 51.76.222.3 1194
 6
 7ca /etc/openvpn/ca.crt
 8cert /etc/openvpn/josemanuel.crt
 9key /etc/openvpn/josemanuel.key
10
11persist-key
12persist-tun
13
14remote-cert-tls server
15
16log-append /var/log/openvpn-client.log
17verb 3
18
19keepalive 10 120
20
21resolv-retry infinite
22nobind

Iniciamos el cliente:

1sudo systemctl start openvpn@cliente
2sudo systemctl enable openvpn@cliente
3sudo systemctl status openvpn@cliente

Comprobación para demostrar la VPN

Como vemos, el cliente y el servidor ya se pueden comunicar entre sí; en este ejemplo el cliente se puede conectar al servidor sin problemas.

El ClienteVPN se conecta por SSH al ServidorVPN a través del túnel

B) VPN sitio a sitio con OpenVPN y certificados x509

El escenario que hemos hecho es una simulación de dos oficinas conectadas a través de Internet. La infraestructura consta de cuatro máquinas principales: dos servidores VPN, ServidorA y ServidorB, y dos equipos cliente, Sevilla y Betis, que representan los equipos de usuario final en cada sede.

La red nat 192.168.122.0/24 es la simulación de “Internet” y está proporcionada por un dispositivo NAT1 de GNS3 que asigna direcciones IP dinámicas mediante DHCP a las interfaces externas de ambos servidores VPN.

Escenario:

Escenario de red para la VPN sitio a sitio entre ServidorA y ServidorB

Instalación de los paquetes en ServidorA y ServidorB

1sudo apt update && sudo apt install openvpn openssl iptables-persistent -y

Generar Certificados en ServidorA

Crear estructura de directorios

1sudo mkdir -p /etc/openvpn/ca
2sudo mkdir -p /etc/openvpn/servidor
3sudo mkdir -p /etc/openvpn/cliente

Generar la Autoridad Certificadora

El primer paso en la construcción de nuestra PKI es la creación de la Autoridad Certificadora; este proceso se realiza exclusivamente en ServidorA, que actuará como emisor de todos los certificados de la infraestructura. Comenzamos generando una clave privada RSA de 2048 bits, que representa el secreto criptográfico fundamental de toda la PKI y debe ser protegida:

1sudo openssl genrsa -out /etc/openvpn/ca/ca.key 2048

Este comando utiliza el algoritmo RSA para generar un par de claves asimétricas. La longitud de 2048 bits proporciona un nivel de seguridad considerado robusto para aplicaciones comerciales actuales, ofreciendo protección contra ataques de factorización durante varias décadas según los estándares NIST.

Vamos a generar ahora el certificado autofirmado de la CA:

1sudo openssl req -new -x509 -days 100 \
2-key /etc/openvpn/ca/ca.key \
3-out /etc/openvpn/ca/ca.crt \
4-subj "/C=ES/ST=Sevilla/L=DosHermanas/O=iesgn/OU=informatica/CN=CA-josemanuel/emailAddress=servera@gmail.com"
  • -new -x509: Crea un certificado autofirmado
  • -days 100: Válido por 100 días
  • -key ca.key: Usa la clave privada que acabamos de crear
  • -out ca.crt: Guarda el certificado público
  • -subj: Información de la CA

Crear dos archivos de extensiones X509v3

OpenVPN 2.6+ implementa validaciones estrictas de certificados que requieren la presencia de extensiones X.509v3 específicas. Estas extensiones definen el propósito autorizado del certificado, implementando el principio de seguridad de “mínimo privilegio”: cada certificado debe tener únicamente los permisos necesarios para su función específica.

Este es para el servidor:

1sudo nano /etc/openvpn/servidor-ext.cnf
1keyUsage = digitalSignature, keyEncipherment
2extendedKeyUsage = serverAuth

Y este para el cliente:

1sudo nano /etc/openvpn/cliente-ext.cnf
1keyUsage = digitalSignature
2extendedKeyUsage = clientAuth

La extensión keyUsage define las operaciones criptográficas permitidas. digitalSignature habilita la firma digital de datos para autenticación, mientras que keyEncipherment permite el cifrado de claves simétricas durante el intercambio de claves — capacidad exclusiva del servidor, porque en TLS el cliente genera la clave de sesión y la cifra con la clave pública del servidor.

La extensión extendedKeyUsage especifica el contexto de uso del certificado. serverAuth marca el certificado como válido únicamente para autenticación de servidores TLS, mientras que clientAuth lo restringe a autenticación de clientes TLS. Esta separación previene ataques de suplantación donde un certificado comprometido de cliente podría intentar utilizarse para suplantar un servidor legítimo.

Generar certificado para Sevilla en el ServidorA

El proceso de generación de certificados sigue el flujo estándar de solicitud-firma característico de las PKIs. Para cada entidad (ServidorA/Sevilla y ServidorB/Betis) realizamos tres pasos:

Generación de clave privada:

1sudo openssl genrsa -out /etc/openvpn/sevilla/sevilla.key 2048

Generación de la clave privada de Sevilla con openssl genrsa

Creación de CSR:

1sudo openssl req -new \
2-key /etc/openvpn/sevilla/sevilla.key \
3-out /etc/openvpn/sevilla/sevilla.csr \
4-subj "/C=ES/ST=Sevilla/O=MiEmpresa/CN=vpn-sevilla.empresa.com/emailAddress=sevilla@empresa.com"

Firma con la CA:

1sudo openssl x509 -req -days 3650 \
2-in /etc/openvpn/sevilla/sevilla.csr \
3-CA /etc/openvpn/ca/ca.crt \
4-CAkey /etc/openvpn/ca/ca.key \
5-set_serial 01 \
6-out /etc/openvpn/sevilla/sevilla.crt \
7-extfile /etc/openvpn/servidor-ext.cnf

Generar certificado para Betis en el ServidorB

Hacemos lo mismo que para Sevilla, pero con el nombre betis y serial 02:

 1sudo openssl genrsa -out /etc/openvpn/betis/betis.key 2048
 2
 3sudo openssl req -new \
 4-key /etc/openvpn/betis/betis.key \
 5-out /etc/openvpn/betis/betis.csr \
 6-subj "/C=ES/ST=Sevilla/O=MiEmpresa/CN=vpn-betis.empresa.com/emailAddress=betis@empresa.com"
 7
 8sudo openssl x509 -req -days 3650 \
 9-in /etc/openvpn/betis/betis.csr \
10-CA /etc/openvpn/ca/ca.crt \
11-CAkey /etc/openvpn/ca/ca.key \
12-set_serial 02 \
13-out /etc/openvpn/betis/betis.crt \
14-extfile /etc/openvpn/cliente-ext.cnf

Es crucial asignar números de serie únicos (-set_serial) a cada certificado, ya que la CA debe mantener un registro de todos los certificados emitidos para posibilitar futuras revocaciones mediante CRL o OCSP.

Generar parámetros Diffie-Hellman

1sudo openssl dhparam -out /etc/openvpn/dh2048.pem 2048

Diffie-Hellman es un protocolo criptográfico que permite que dos partes establezcan un secreto compartido a través de un canal inseguro sin transmitir directamente ninguna clave. Proporciona Perfect Forward Secrecy: incluso si la clave privada del servidor se viera comprometida en el futuro, las sesiones pasadas permanecerán protegidas, porque cada sesión usa claves efímeras generadas mediante DH que no se almacenan permanentemente.

La generación de estos parámetros es computacionalmente intensiva porque requiere encontrar números primos grandes y calcular generadores del grupo cíclico correspondiente.

Generación de los parámetros Diffie-Hellman en ServidorA

Verificamos que lo tengamos de esta manera:

Estructura de directorios de certificados en ServidorA verificada con tree

Ahora nos iremos al ServidorB y crearemos la estructura de directorios:

1sudo mkdir -p /etc/openvpn/ca
2sudo mkdir -p /etc/openvpn/betis

Y nos tendremos que pasar el ca.crt, betis.crt y betis.key; para ello lo haremos por scp, aunque se podría hacer por correo también o por donde se prefiera.

Copia de los certificados de ServidorA a ServidorB por scp

Moveremos ahora los archivos y tiene que quedar tal que así:

Estructura de directorios de certificados en ServidorB verificada con tree

Configuración OpenVPN en el ServidorA

El servidor OpenVPN se configura en modo tls-server, escuchando conexiones entrantes en el puerto UDP 1194. La configuración establece un túnel punto a punto con direccionamiento estático:

1sudo nano /etc/openvpn/sevilla.conf
 1dev tun
 2proto udp
 3port 1194
 4tls-server
 5
 6ca /etc/openvpn/ca/ca.crt
 7cert /etc/openvpn/sevilla/sevilla.crt
 8key /etc/openvpn/sevilla/sevilla.key
 9dh /etc/openvpn/dh2048.pem
10
11ifconfig 10.99.99.1 10.99.99.2
12
13route 192.168.2.0 255.255.255.0
14
15persist-key
16persist-tun
17
18status /var/log/openvpn-sevilla-status.log
19log-append /var/log/openvpn-sevilla.log
20verb 3
21
22keepalive 10 120

Análisis de parámetros clave:

  • dev tun: Crea una interfaz de red virtual de capa 3 (IP). Las interfaces TUN operan con paquetes IP completos.
  • proto udp: UDP es preferible para VPNs porque evita la “retransmisión doble” que ocurre con TCP sobre TCP: si usáramos TCP, tanto el túnel VPN como las conexiones dentro del túnel intentarían retransmitir paquetes perdidos, degradando significativamente el rendimiento.
  • tls-server: Declara este extremo como servidor TLS, habilitando el handshake TLS donde el servidor presenta su certificado primero.
  • ifconfig 10.99.99.1 10.99.99.2: Configura el direccionamiento punto a punto. El primer IP (10.99.99.1) es la dirección local, el segundo (10.99.99.2) es el peer remoto.
  • route 192.168.2.0 255.255.255.0: Añade una ruta estática hacia la red remota (Betis) a través del túnel. Sin esta ruta, el servidor no sabría cómo alcanzar la red 192.168.2.0/24.
  • persist-key y persist-tun: Mantienen las claves y la interfaz TUN abierta durante reinicios suaves (SIGUSR1), evitando recargar archivos y destruir/recrear la interfaz innecesariamente.
  • keepalive 10 120: Envía pings de control cada 10 segundos; si no hay respuesta en 120 segundos, reinicia la conexión. Esto detecta enlaces caídos rápidamente.

Habilitar IP Forwarding en los dos servidores

Por defecto, los sistemas Linux no reenvían paquetes entre interfaces de red; para que nuestros servidores VPN puedan enrutar tráfico entre sus redes locales y el túnel VPN, debemos habilitar el IP forwarding:

1sudo nano /etc/sysctl.conf

Descomentando net.ipv4.ip_forward en ServidorA

1sudo sysctl -p

Verificación del IP forwarding habilitado en ServidorA

Iniciar OpenVPN

1sudo systemctl start openvpn@sevilla
2sudo systemctl enable openvpn@sevilla
3sudo systemctl status openvpn@sevilla

Servicio openvpn@sevilla activo en ServidorA

Salida de ip a con la interfaz tun0 levantada en ServidorA

Crear archivo de configuración para el ServidorB

El lado cliente se conecta activamente al servidor y opera en modo tls-client:

1sudo nano /etc/openvpn/betis.conf
 1remote 192.168.122.227 1194
 2dev tun
 3proto udp
 4tls-client
 5
 6ca /etc/openvpn/ca/ca.crt
 7cert /etc/openvpn/betis/betis.crt
 8key /etc/openvpn/betis/betis.key
 9
10ifconfig 10.99.99.2 10.99.99.1
11
12route 192.168.1.0 255.255.255.0
13
14remote-cert-tls server
15
16persist-key
17persist-tun
18
19log-append /var/log/openvpn-betis.log
20verb 3
21
22keepalive 10 120
23nobind

Parámetros del cliente:

  • remote 192.168.122.227 1194: Especifica la dirección IP y puerto del servidor VPN. El cliente inicia activamente la conexión.
  • tls-client: Opera como cliente TLS, esperando que el servidor presente su certificado primero durante el handshake.
  • remote-cert-tls server: Valida que el certificado presentado por el peer remoto contenga la extensión serverAuth. Previene ataques man-in-the-middle donde un atacante podría interceptar la conexión usando un certificado de cliente robado.
  • nobind: No vincula a un puerto local específico. Útil para clientes detrás de NAT o que necesitan múltiples conexiones simultáneas.

El direccionamiento ifconfig es inverso al del servidor: local 10.99.99.2, peer 10.99.99.1.

Iniciamos OpenVPN en el ServidorB

1sudo systemctl start openvpn@betis
2sudo systemctl enable openvpn@betis
3sudo systemctl status openvpn@betis

Servicio openvpn@betis activo en ServidorB

Salida de ip a con la interfaz tun0 levantada en ServidorB

Comprobación

Como vemos, ambos se hacen ping, confirmando que el túnel encriptado funciona correctamente.

Ping exitoso desde ServidorA a ServidorB a través del túnel

Ping exitoso desde ServidorB a ServidorA a través del túnel

Finalmente, probamos servicios reales como SSH, y vemos cómo desde Sevilla podemos conectarnos a Betis, y Betis se puede conectar a Sevilla simultáneamente.

Conexión SSH desde Sevilla a Betis a través del túnel

Conexión SSH desde Betis a Sevilla a través del túnel

C) VPN de acceso remoto con WireGuard

WireGuard es un protocolo VPN moderno que destaca por su simplicidad, rendimiento superior y base de código reducida. Utiliza criptografía de última generación (Curve25519, ChaCha20, Poly1305) y fue integrado oficialmente en el kernel de Linux desde la versión 5.6.

En esta práctica se implementa una infraestructura VPN completa utilizando WireGuard, permitiendo la conexión segura de múltiples clientes (Windows, Linux y Android) a través de Internet, con acceso tanto a la red privada del servidor como a Internet mediante NAT, con direccionamiento de IP “públicas” para simular Internet.

Escenario:

Escenario de red para la VPN de acceso remoto con WireGuard, con clientes Windows, Linux y Android

Tanto en el router como en el servidor ya está configurado el reenvío de paquetes y el SNAT para que puedan salir a Internet los clientes. También en el Router tengo un servidor DHCP que asigna las IPs automáticamente a los clientes.

Instalación y Configuración del ServidorVPN

Instalación de software

1sudo apt update && sudo apt install wireguard wireguard-tools -y

El paquete wireguard-tools proporciona las utilidades de espacio de usuario:

  • wg: Herramienta de configuración y monitorización de interfaces WireGuard
  • wg-quick: Script de alto nivel que simplifica la gestión de configuraciones completas

Criptografía y gestión de claves

Modelo de seguridad de WireGuard

WireGuard implementa un modelo de seguridad radicalmente diferente al de las VPNs tradicionales. En lugar de depender de certificados X.509 con jerarquías de confianza y autoridades certificadoras, WireGuard utiliza criptografía de clave pública asimétrica donde cada peer (tanto servidor como clientes) genera un par de claves criptográficas:

  • Clave privada: secreto criptográfico de 256 bits que nunca sale del dispositivo que lo generó. Es análoga a una clave privada SSH y debe protegerse.
  • Clave pública: derivada matemáticamente de la clave privada, se comparte con los peers autorizados y actúa como identificador único del dispositivo.

Generación de claves criptográficas

En el ServidorVPN, nos vamos al directorio que ha creado WireGuard para las claves:

1cd /etc/wireguard

Generamos clave privada y pública del servidor:

1wg genkey | sudo tee server_private.key | wg pubkey | sudo tee server_public.key

Generamos la clave privada para el cliente Windows (la pública nos la dará Windows al meter la clave privada):

1wg genkey | sudo tee windows_private.key

Generamos claves para el cliente Linux:

1wg genkey | sudo tee linux_private.key | wg pubkey | sudo tee linux_public.key

Generamos la clave para Android (solo la privada, la pública nos la dará Android):

1wg genkey | sudo tee android_private.key

Protegemos las claves privadas:

1sudo chmod 600 /etc/wireguard/*_private.key

Normalmente se generan en el servidor tanto las claves privadas como las públicas, y se pasarían al cliente correspondiente para la configuración (scp, email…). En este caso se hace distinto: creándolas desde la clave privada que da el servidor, o incluso generándolas desde cero en el propio cliente — lo importante es que luego, en el archivo de configuración, cada clave esté puesta correctamente.

Listado de las claves privadas y públicas generadas en /etc/wireguard

Crear configuración del servidor

WireGuard utiliza archivos de configuración INI simples ubicados en /etc/wireguard/. El nombre del archivo determina el nombre de la interfaz que se creará (wg0.conf → interfaz wg0).

1sudo nano /etc/wireguard/wg0.conf
 1[Interface]
 2#ip del tunel
 3Address = 10.99.99.1/24
 4ListenPort = 51820
 5#clave privada del servidor
 6PrivateKey = *****
 7
 8#Windows
 9[Peer]
10PublicKey = ibCzEN6XO6Gb2OWOSC4mkBROyDICHll3YPz03ddxynI=
11AllowedIPs = 10.99.99.2/32
12PersistentKeepalive = 25
13
14#Cliente Linux
15[Peer]
16PublicKey = ESgSFMN4/VMkg7WYfg4e0DHnj/r0hwl3TkZYXoxLPT8=
17AllowedIPs = 10.99.99.3/32
18PersistentKeepalive = 25
19
20#Android
21[Peer]
22PublicKey = HAnqlFKDaIXvOTcsmRAcUM9v6a3o1iynWj3z9hEXgVE=
23AllowedIPs = 10.99.99.4/32
24PersistentKeepalive = 25

Explicación de parámetros:

  • Address: IP que tendrá el servidor dentro del túnel VPN
  • ListenPort: Puerto UDP donde WireGuard escucha conexiones (51820 por defecto)
  • PrivateKey: Clave privada del servidor
  • PublicKey: Clave pública del cliente
  • AllowedIPs: IPs que el cliente puede usar en el túnel
  • PersistentKeepalive: Envía paquetes keepalive cada 25 segundos para mantener la conexión activa a través de NATs

Iniciar y habilitar WireGuard

Levantamos la interfaz wg0:

1sudo wg-quick up wg0

Habilitamos para que se inicie automáticamente en el arranque:

1sudo systemctl enable wg-quick@wg0

Y verificamos el estado:

1sudo wg show

Interfaz wg0 levantada, con los tres peers configurados y su estado

Configuración ClienteLinux

Instalación de WireGuard

En el cliente Linux instalamos los mismos paquetes que en el servidor:

1sudo apt update && sudo apt install wireguard wireguard-tools -y

Crear configuración del cliente

En el archivo de configuración meteremos la clave privada propia y la pública que nos ha dado el servidor.

1sudo nano /etc/wireguard/wg0.conf
 1[Interface]
 2Address = 10.99.99.3/24
 3PrivateKey = *****
 4DNS = 8.8.8.8
 5
 6[Peer]
 7PublicKey = c6uL2aELD42hoOQoB+NbVCm8NEENt1BKpiHtwh+MjjQ=
 8Endpoint = 200.100.50.150:51820
 9AllowedIPs = 0.0.0.0/0
10PersistentKeepalive = 25

Ahora vamos a iniciar la VPN

La iniciamos:

1sudo wg-quick up wg0

Habilitamos el arranque:

1sudo systemctl enable wg-quick@wg0

Verificamos el estado:

1sudo wg show

Comprobación

Para probar la conexión hacemos ping al servidor y nos conectamos por SSH:

Túnel wg0 activo en ClienteLinux: ping y conexión SSH exitosos hacia el servidor

Configuración cliente Windows

Instalación

Lo primero es instalar WireGuard, desde: wireguard.com/install

Página oficial de descarga de WireGuard para Windows

Una vez ejecutado el .exe se instalará y comenzaremos con la configuración.

Ventana principal de la aplicación WireGuard en Windows, sin túneles todavía

Configuración Windows

Le damos a “Add Tunnel” y creamos la configuración:

Menú Add Tunnel de WireGuard en Windows, con la opción Add empty tunnel

Lista de túneles de WireGuard en Windows antes de configurar

La configuración queda así: metemos la clave privada que generamos en el servidor y se crea automáticamente (debajo de Name) la clave pública, que hay que copiar en el archivo de configuración del servidor wg0.conf.

Configuración del túnel en WireGuard para Windows, con Interface y Peer rellenos

Guardamos y le damos a activar:

Túnel activo en Windows, con el estado, la clave pública y los datos del peer

Comprobación

Para probar si está bien, hacemos ping al servidor y a “DondeVamosAConectarnos” para ver si hay comunicación fuera de nuestra red.

Configuración de red IPv4 del adaptador WireGuard en Windows y pings exitosos al servidor y a la red remota

Y en el servidor, con sudo wg show, también nos aparecería el peer conectado:

sudo wg show en el servidor mostrando el peer de Windows conectado

Configuración cliente Android

Instalación

Para instalar WireGuard en Android hay que ir a Play Store y buscar WireGuard.

WireGuard en Google Play Store

Una vez instalada, creamos el túnel VPN desde cero, dándole al “+”.

Pantalla principal de la app WireGuard en Android, con el botón para añadir un túnel

Creamos la configuración: en el nombre ponemos lo que queramos, en la clave privada la que se generó en el servidor (se creará la clave pública, que hay que copiar en el wg0.conf del servidor), luego la dirección IP del túnel VPN que tendrá Android (en este caso 10.99.99.4/24) y el servidor DNS 8.8.8.8, para que al activar la VPN meta el nameserver en /etc/resolv.conf.

Más abajo metemos la clave pública del ServidorVPN, con 25s de keepalive, apuntando a la IP “pública” del servidor, y permitimos todas las IPs con 0.0.0.0/0.

Configuración de la interfaz y el peer del túnel WireGuard en Android

Configuración del peer en Android, con clave pública, keepalive, endpoint e IPs permitidas

Guardamos la configuración y activamos

Túnel activo en Android, con los datos de transferencia y la última comunicación

Comprobación

Para comprobarlo, entramos en la terminal de Android y hacemos ping al servidor y al cliente de la otra red.

Ping desde Android al servidor y a la red remota a través de wg0

Pruebas de conectividad

Si vamos al servidor y ponemos sudo wg show veremos todos los clientes conectados:

sudo wg show en el servidor con los tres peers (Windows, Linux, Android) conectados y transfiriendo datos

  • latest handshake: tiempo desde el último intercambio criptográfico. Si dice “(never)”, el peer no está conectado.
  • endpoint: IP y puerto desde donde el peer se conecta.
  • transfer: datos transmitidos/recibidos.

Comunicación de Windows a los clientes y servidor:

Pings desde Windows al servidor y a los clientes Linux y Android

De cliente Linux a los clientes y servidores:

Pings desde ClienteLinux al servidor y a los clientes Windows y Android

De Android al cliente y servidores:

Pings desde Android al servidor y a los clientes Windows y Linux

Comparación Apartado C vs A

WireGuard simplifica la configuración eliminando la necesidad de PKI, certificados X.509 y parámetros Diffie-Hellman que requiere OpenVPN. Utiliza criptografía moderna de curva elíptica (Curve25519) en lugar de RSA/TLS, logrando menor latencia y mejor rendimiento. La configuración es minimalista, un solo archivo con claves públicas/privadas, frente a la complejidad de OpenVPN con múltiples certificados, CA y archivos de extensiones, siendo especialmente superior en dispositivos móviles por su mejor manejo de NAT traversal y cambios de red.

D) VPN sitio a sitio con WireGuard

Escenario:

Escenario de red para la VPN sitio a sitio con WireGuard entre ServidorA y ServidorB

Configuración del ServidorA

Instalación de WireGuard

1sudo apt update && sudo apt install wireguard wireguard-tools -y

Generación de las claves criptográficas

1cd /etc/wireguard
2sudo wg genkey | sudo tee serverA_private.key
3sudo cat serverA_private.key | wg pubkey | sudo tee serverA_public.key
4sudo chmod 600 serverA_private.key

Creamos el archivo de configuración del servidor

1sudo nano /etc/wireguard/wg0.conf
 1[Interface]
 2Address = 10.99.99.1/24
 3PrivateKey = *****
 4ListenPort = 51820
 5
 6#servidorb
 7[Peer]
 8PublicKey = aAabSt754vjHHVHy29PHiUcksA3uhfbOakvk8B96e3o=
 9AllowedIPs = 10.99.99.2/32, 10.0.0.0/8
10PersistentKeepalive = 25

Explicación de parámetros:

  • Address: IP que tendrá ServidorA dentro del túnel VPN (10.99.99.1/24)
  • PrivateKey: Clave privada del servidor para autenticación criptográfica
  • ListenPort: Puerto UDP donde escucha conexiones entrantes (51820 por defecto)
  • AllowedIPs: Define qué rangos IP puede usar el peer remoto. Incluye tanto la IP del túnel del peer (10.99.99.2/32) como la red (10.0.0.0/8)
  • PersistentKeepalive: Envía paquetes keepalive cada 25 segundos para mantener el túnel activo, especialmente útil detrás de NATs

Configuración del ServidorB

Instalación y generación de claves

1sudo apt update && sudo apt install wireguard wireguard-tools -y
2cd /etc/wireguard
3sudo wg genkey | sudo tee serverB_private.key
4sudo cat serverB_private.key | wg pubkey | sudo tee serverB_public.key
5sudo chmod 600 serverB_private.key

Crear configuración del servidor

1sudo nano /etc/wireguard/wg0.conf
 1[Interface]
 2Address = 10.99.99.2/24
 3PrivateKey = *****
 4ListenPort = 51820
 5
 6#servidorA
 7[Peer]
 8PublicKey = CI3EFCw4OFXGI4kExF07nLTmYnlFDYzLaIkF/57+Awc=
 9Endpoint = 200.100.50.96:51820
10AllowedIPs = 10.99.99.1/32, 172.22.0.0/16
11PersistentKeepalive = 25

Diferencia clave con ServidorA: Endpoint — ServidorB especifica a dónde conectarse (200.100.50.96:51820). ServidorA no tiene Endpoint porque actúa como “listener” esperando conexiones entrantes; ServidorB actúa como “initiator” que inicia la conexión. Además, ServidorB añade la ruta inversa a 172.22.0.0/16 (red del Sitio A) vía 10.99.99.1 (ServidorA).

Iniciar y habilitar WireGuard

Levantamos la interfaz wg0 en el ServidorA:

1sudo wg-quick up wg0
2sudo systemctl enable wg-quick@wg0
3sudo wg show

sudo wg show en ServidorB, con el peer ServidorA conectado

Lo mismo hacemos en el ServidorB:

1sudo wg-quick up wg0
2sudo systemctl enable wg-quick@wg0
3sudo wg show

sudo wg show en ServidorA, con el peer ServidorB conectado

Como vemos, el campo latest handshake confirma que el túnel VPN se estableció correctamente.

Verificación de conectividad

Ping desde Cliente1 a Cliente2, y traceroute para ver que pasa por la VPN:

Ping y traceroute desde Cliente1 a Cliente2, pasando por el túnel entre ServidorA y ServidorB

Lo mismo desde Cliente2 a Cliente1:

Ping y traceroute desde Cliente2 a Cliente1, pasando por el túnel entre ServidorA y ServidorB

Comparación Apartado D vs B

En sitio a sitio, WireGuard elimina la distinción cliente-servidor de OpenVPN (el tls-server/tls-client del archivo de configuración), tratando ambos extremos como peers simétricos donde solo uno especifica Endpoint para iniciar la conexión. El enrutamiento es más directo mediante AllowedIPs, especificando redes remotas directamente sin necesidad de rutas estáticas. La configuración es más simple manteniendo el mismo resultado funcional, con menor overhead y reconexión automática más rápida ante caídas del túnel.