OpenVPN es una VPN de código abierto que cifra el tráfico con TLS y autentica a cada cliente con su propio certificado. Es una buena opción para dar acceso remoto seguro a una red privada o para que tus dispositivos salgan a Internet a través de un servidor de confianza. En este tutorial instalarás OpenVPN en Ubuntu 24.04, crearás una autoridad de certificación con Easy-RSA, configurarás el servidor para enrutar todo el tráfico de los clientes, generarás un perfil .ovpn listo para importar y aprenderás a revocar el acceso de un cliente.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS y una IP pública, por ejemplo un VPS de CubePath. 1 vCPU y 1 GB de RAM son suficientes para un uso personal o de un equipo pequeño.
- Un usuario no root con privilegios
sudo. - UFW como firewall, con SSH permitido. Si no lo tienes activado, lo harás en el paso 5.
- El puerto
1194/udpaccesible desde Internet. - Un dispositivo cliente con Linux, Windows, macOS, Android o iOS.
En el tutorial se usa your_server_ip para la IP pública del servidor y client1 como nombre del primer cliente.
Paso 1: Instalar OpenVPN y Easy-RSA
Ambos paquetes están en los repositorios de Ubuntu. OpenVPN es el servicio VPN; Easy-RSA es un conjunto de scripts para crear y firmar certificados:
sudo apt update
sudo apt install openvpn easy-rsa
Comprueba la versión instalada:
openvpn --version | head -n 1
OpenVPN 2.6.x x86_64-pc-linux-gnu [SSL (OpenSSL)] [LZO] [LZ4] [EPOLL] [PKCS11] [MH/PKTINFO] [AEAD] [DCO]
Paso 2: Crear la autoridad de certificación
OpenVPN autentica servidor y clientes con certificados firmados por una autoridad de certificación (CA) propia. Crea un directorio de trabajo para Easy-RSA en tu usuario, sin sudo, para que las claves no sean de root:
make-cadir ~/easy-rsa
cd ~/easy-rsa
Inicializa la infraestructura de clave pública (PKI):
./easyrsa init-pki
Crea la CA. Te pedirá una frase de paso para proteger la clave privada de la CA (la necesitarás cada vez que firmes un certificado) y un nombre común; puedes aceptar el propuesto o escribir algo como CubePath-VPN-CA:
./easyrsa build-ca
...
Notice
------
CA creation complete. Your new CA certificate is at:
* /home/your_user/easy-rsa/pki/ca.crt
ImportanteLa clave
pki/private/ca.keypermite emitir certificados válidos para tu VPN. Usa una frase de paso fuerte y haz una copia de seguridad cifrada del directorio~/easy-rsa. En entornos con requisitos más estrictos, la CA se mantiene en una máquina aparte, fuera del servidor VPN.
Paso 3: Generar el certificado del servidor y la clave tls-crypt
Genera la petición y la clave privada del servidor. nopass deja la clave sin frase de paso, necesario para que el servicio arranque solo. Acepta el nombre común server que te propone:
./easyrsa gen-req server nopass
Firma la petición como certificado de tipo servidor. Escribe yes para confirmar e introduce la frase de paso de la CA:
./easyrsa sign-req server server
...
Notice
------
Certificate created at:
* /home/your_user/easy-rsa/pki/issued/server.crt
Copia el certificado de la CA, el del servidor y su clave al directorio de configuración de OpenVPN:
sudo cp pki/ca.crt pki/issued/server.crt /etc/openvpn/server/
sudo install -m 600 pki/private/server.key /etc/openvpn/server/
Genera también una clave compartida para tls-crypt. Esta clave cifra y autentica los paquetes de control de TLS, de modo que el servidor descarta sin responder cualquier intento de conexión que no la tenga. Así se reduce la exposición a escaneos y ataques de denegación de servicio:
sudo openvpn --genkey secret /etc/openvpn/server/ta.key
Comprueba que tienes los cuatro archivos:
sudo ls -l /etc/openvpn/server/
-rw-r--r-- 1 root root 1204 Sep 25 10:00 ca.crt
-rw-r--r-- 1 root root 4608 Sep 25 10:01 server.crt
-rw------- 1 root root 1704 Sep 25 10:01 server.key
-rw------- 1 root root 636 Sep 25 10:02 ta.key
No hace falta generar parámetros Diffie-Hellman: la configuración usará dh none, con intercambio de claves por curva elíptica (ECDHE), que es más rápido y es el método recomendado en OpenVPN 2.6.
Paso 4: Configurar el servidor OpenVPN
Crea el archivo de configuración del servidor. El nombre del archivo (server.conf) determina el nombre de la instancia del servicio, openvpn-server@server:
sudo nano /etc/openvpn/server/server.conf
port 1194
proto udp
dev tun
ca ca.crt
cert server.crt
key server.key
dh none
tls-crypt ta.key
topology subnet
server 10.8.0.0 255.255.255.0
push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 1.1.1.1"
push "dhcp-option DNS 9.9.9.9"
keepalive 10 120
user nobody
group nogroup
persist-key
persist-tun
verb 3
explicit-exit-notify 1
Qué hace cada bloque:
port,proto,dev: escucha en1194/udpy crea una interfaz de red virtualtun(enrutada, capa 3).ca,cert,key,tls-crypt: los archivos del paso 3, con rutas relativas a/etc/openvpn/server/, que es el directorio de trabajo del servicio.server 10.8.0.0 255.255.255.0: la subred interna de la VPN. El servidor será10.8.0.1y los clientes recibirán direcciones a partir de10.8.0.2. Si esa red ya se usa en tu infraestructura o en las redes de tus clientes, elige otra privada.push "redirect-gateway ...": hace que los clientes envíen todo su tráfico por la VPN. Si solo quieres dar acceso a una red privada, quita esa línea y añade en su lugar una ruta concreta, por ejemplopush "route 10.10.0.0 255.255.0.0".push "dhcp-option DNS ...": los servidores DNS que usarán los clientes mientras estén conectados.user nobodyygroup nogroup: tras arrancar, el proceso deja de ejecutarse como root.
OpenVPN 2.6 negocia por defecto cifrados AEAD modernos (AES-256-GCM, AES-128-GCM o ChaCha20-Poly1305), así que no necesitas ninguna directiva de cifrado.
Paso 5: Activar el reenvío de IP y el NAT con UFW
Para que los clientes salgan a Internet a través del servidor, el kernel debe reenviar paquetes entre la interfaz tun0 y la interfaz pública, y el tráfico de la subred VPN debe salir con la IP del servidor (NAT).
Activa el reenvío de IPv4 de forma persistente:
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-openvpn.conf
sudo sysctl --system
Comprueba que está activo:
sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1
Identifica 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
Aquí es eth0; usa el nombre que veas en tu servidor en los siguientes comandos. Añade la regla de NAT al principio del archivo de reglas de UFW:
sudo nano /etc/ufw/before.rules
Pega este bloque justo después de los comentarios iniciales y antes de la línea *filter:
# NAT para los clientes de OpenVPN
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
Permite el puerto de OpenVPN, el reenvío desde la VPN hacia Internet y SSH, y activa o recarga UFW:
sudo ufw allow 1194/udp
sudo ufw route allow in on tun0 out on eth0
sudo ufw allow OpenSSH
sudo ufw enable
sudo ufw reload
La regla ufw route permite solo el tráfico reenviado de la VPN hacia la interfaz pública, en lugar de cambiar la política de reenvío global a ACCEPT. Comprueba las reglas:
sudo ufw status
Status: active
To Action From
-- ------ ----
1194/udp ALLOW Anywhere
OpenSSH ALLOW Anywhere
Anywhere on eth0 ALLOW FWD Anywhere on tun0
...
Paso 6: Iniciar el servicio
Arranca OpenVPN y actívalo para que se inicie con el sistema:
sudo systemctl enable --now openvpn-server@server
Comprueba su estado:
sudo systemctl status openvpn-server@server
● [email protected] - OpenVPN service for server
Loaded: loaded (/usr/lib/systemd/system/[email protected]; enabled; preset: enabled)
Active: active (running) since ...
Status: "Initialization Sequence Completed"
La interfaz de la VPN debe existir con la dirección del servidor:
ip -brief address show tun0
tun0 UNKNOWN 10.8.0.1/24 ...
Si el servicio no arranca, el motivo aparece en el registro:
sudo journalctl -u openvpn-server@server -n 50 --no-pager
Paso 7: Crear el perfil de un cliente
Cada cliente necesita su propio certificado. Genera la petición y fírmala como certificado de tipo cliente (escribe yes y la frase de paso de la CA cuando te lo pida):
cd ~/easy-rsa
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1
Lo más cómodo para el cliente es un único archivo .ovpn con la configuración y los certificados incrustados. Prepara un directorio para los perfiles con una copia de la clave tls-crypt que pueda leer tu usuario:
mkdir -p ~/clients
sudo install -m 600 -o "$USER" -g "$USER" /etc/openvpn/server/ta.key ~/clients/ta.key
chmod 700 ~/clients
Crea la configuración base común a todos los clientes, sustituyendo your_server_ip por la IP pública del servidor:
nano ~/clients/base.conf
client
dev tun
proto udp
remote your_server_ip 1194
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verb 3
remote-cert-tls server hace que el cliente solo acepte un certificado firmado como servidor, lo que impide que otro cliente de tu VPN se haga pasar por el servidor.
Como tendrás que repetir el montaje del archivo para cada cliente, crea un pequeño script que lo haga:
nano ~/clients/make-client.sh
#!/usr/bin/env bash
set -euo pipefail
name="${1:?Uso: make-client.sh NOMBRE_CLIENTE}"
pki="$HOME/easy-rsa/pki"
out="$HOME/clients/${name}.ovpn"
{
cat "$HOME/clients/base.conf"
echo "<ca>"
cat "$pki/ca.crt"
echo "</ca>"
echo "<cert>"
sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' "$pki/issued/${name}.crt"
echo "</cert>"
echo "<key>"
cat "$pki/private/${name}.key"
echo "</key>"
echo "<tls-crypt>"
cat "$HOME/clients/ta.key"
echo "</tls-crypt>"
} > "$out"
chmod 600 "$out"
echo "Perfil creado: $out"
Hazlo ejecutable y genera el perfil de client1:
chmod +x ~/clients/make-client.sh
~/clients/make-client.sh client1
Perfil creado: /home/your_user/clients/client1.ovpn
AdvertenciaEl archivo
.ovpncontiene la clave privada del cliente. Trátalo como una contraseña: transfiérelo por un canal cifrado (por ejemploscp) y no lo envíes por correo ni lo compartas entre personas. Cada usuario o dispositivo debe tener su propio perfil.
Desde tu equipo, descarga el perfil con scp:
scp your_user@your_server_ip:clients/client1.ovpn .
Paso 8: Conectar un cliente y verificar la VPN
En Windows, macOS, Android e iOS instala el cliente oficial (OpenVPN Connect u OpenVPN GUI en Windows) e importa el archivo client1.ovpn.
En un cliente Linux, instala OpenVPN y conecta desde la terminal:
sudo apt install openvpn
sudo openvpn --config client1.ovpn
Cuando la conexión se complete verás esta línea:
... Initialization Sequence Completed
Desde otra terminal del cliente, comprueba que llegas al servidor por la VPN y que tu tráfico sale con la IP del servidor:
ping -c 3 10.8.0.1
curl -4 https://icanhazip.com
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
your_server_ip
Si curl muestra la IP del servidor en lugar de la de tu conexión, todo el tráfico está pasando por la VPN.
NotaEn clientes Linux lanzados desde la terminal, las opciones DNS enviadas por el servidor no se aplican automáticamente. Si necesitas que se usen, importa el perfil en NetworkManager con
nmcli connection import type openvpn file client1.ovpn(requiere el paquetenetwork-manager-openvpn).
En el servidor, los clientes conectados aparecen en el archivo de estado del servicio:
sudo cat /run/openvpn-server/status-server.log
...
CLIENT_LIST,client1,198.51.100.20:51820,10.8.0.2,,...
...
Paso 9: Revocar el acceso de un cliente
Si un dispositivo se pierde o una persona deja de necesitar acceso, revoca su certificado. Desde el directorio de Easy-RSA:
cd ~/easy-rsa
./easyrsa revoke client1
./easyrsa gen-crl
gen-crl genera la lista de revocación pki/crl.pem. Cópiala al servidor OpenVPN con permisos de lectura, porque el proceso la lee ya sin privilegios de root:
sudo install -m 644 pki/crl.pem /etc/openvpn/server/crl.pem
La primera vez, añade la directiva que activa la comprobación en /etc/openvpn/server/server.conf:
crl-verify crl.pem
Reinicia el servicio:
sudo systemctl restart openvpn-server@server
A partir de ahora, un cliente revocado que intente conectarse será rechazado y en el registro del servidor aparecerá un error de verificación de certificado (certificate revoked). En las siguientes revocaciones basta con ejecutar revoke, gen-crl y volver a copiar crl.pem; OpenVPN relee el archivo en cada conexión.
ImportanteLa CRL generada por Easy-RSA caduca a los 180 días por defecto. Cuando caduca, OpenVPN rechaza a todos los clientes. Programa un recordatorio para regenerarla con
./easyrsa gen-crly copiarla de nuevo antes de esa fecha.
Solución de problemas
El cliente no conecta y se queda en TLS key negotiation failed to occur within 60 seconds
Los paquetes no llegan al servidor. Comprueba que el puerto 1194/udp está permitido en UFW (sudo ufw status), que remote en el perfil tiene la IP correcta y que el servicio está en marcha. Un perfil con una clave tls-crypt distinta produce el mismo síntoma, porque el servidor descarta los paquetes en silencio.
El cliente conecta pero no navega
Casi siempre falla el reenvío o el NAT. Comprueba en el servidor sysctl net.ipv4.ip_forward (debe ser 1), que el bloque *nat de /etc/ufw/before.rules usa el nombre correcto de la interfaz pública y que existe la regla ALLOW FWD en sudo ufw status. Tras editar before.rules, ejecuta sudo ufw reload.
El cliente navega por IP pero no resuelve nombres
El cliente no está aplicando los DNS enviados por el servidor. En Windows, macOS y móviles, el cliente oficial los aplica; en Linux, consulta la nota del paso 8.
Options error: ... No such file or directory al arrancar el servicio
Falta alguno de los archivos del paso 3 en /etc/openvpn/server/ o el nombre no coincide con el de server.conf.
Conclusión
Has montado un servidor OpenVPN en Ubuntu 24.04 con su propia CA, cifrado moderno y protección tls-crypt, has configurado el NAT con UFW, has generado un perfil .ovpn para un cliente y sabes revocar certificados. Como siguientes pasos, puedes crear un perfil por cada usuario con make-client.sh, limitar la VPN a una red privada en lugar de enrutar todo el tráfico, o añadir soporte IPv6 dentro del túnel con la directiva server-ipv6.
