Introducción

El siguiente artículo explica como configurar OpenVPN.

Es un proceso complicado y en el que tendréis que poner algo de imaginación para resolver algunos de los problemas que os van a aparecer.

Instalación

Linux, Raspberry y asimilados:

# apt-get install openvpn

Windows

https://openvpn.net/index.php/open-source/downloads.html

Generar certificados

Se trata de generar un certificado digital (clave pública y una privada) autofirmada por una autoridad de certificación (CA) que previamente crearemos nosotros.

Este proceso está explicado en el post sobre generación de certificados autofirmados.

Al final de este artículo, puedes ver un script para facilitarlo todo.

Además de lo anterior, hay que generar un DiffieHellman:
openssl dhparam -out dh2048.pem 2048

Generados los certificados, tendremos los siguientes ficheros.

  • Clave privada de nuestra CA – Solo usado para firmar el resto de certificados
  • Clave pública de nuestra CA – En el servidor y en el cliente
  • Clave privada de nuestro servidor – Solo en el servidor
  • Clave pública de nuestro servidor – Solo en el servidor
  • Clave privada de nuestro cliente – Solo en el cliente
  • Clave pública de nuestro cliente – Solo en el cliente
  • DiffieHellman – En el servidor y en el cliente

Cada uno de esos ficheros los tendremos que copiar donde se indica, según el rol que vaya a tener el equipo (cliente o servidor)

En linux, el directorio debería ser /etc/openvpn/server para el servidor o /etc/openvpn/client para el cliente

En windows esa carpeta debería estar en:

C:\Program Files\OpenVPN\config

Nota importante sobre la clave privada de nuestro servidor: Después de muchos problemas para arrancar como servicio server.conf, lo más sencillo es crear este certificado sin clave.

Si lo has creado con clave, puedes ejecutar el siguiente comando para quitarle dicha clave:

openssl rsa -in server_priv.pem -out server_priv_nokey.pem

Configuración del fichero .conf del servidor

Si estan comprimidas,  descomprimir una configuración de ejemplo de servidor. Si no, copiar el fichero.

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz |sudo tee /etc/openvpn/server.ovpn

Modificar los parámetros con los nombres de los ceritificados
ca ca_pub.pem
cert server_pub.pem
key server_priv.pem
dh dh2048.pem

Configuración del fichero .conf del cliente

Si estan comprimidas, descomprimir una configuración de ejemplo de cliente. Si no, copiar el fichero.

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/client.conf.gz |sudo tee /etc/openvpn/client.conf

Modificar los parámetros con los nombres de los ceritificados del fichero de confiuguración


# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote 192.168.1.20 1194
ca ca_pub.pem
cert client_pub.pem
key client_priv.pem
dh dh2048.pem

En este caso 192.168.1.20 será la dirección del servidor. También podría ser un nombre DNS.

Probando el servicio

Antes de lanzar el servicio lo mejor es que lo pruebes desde la consola. De esta manera podrás ver qué está pasando, seguramente nada bueno. Desde la carpeta donde tengas el fichero .conf del servidor

openvpn server.conf

Así mismo podrás probar el fichero del cliente en el mismo equipo antes de probar desde otros equipos (así puedes depurar préviamente errores de configuración antes de depurar problemas de conexión)

openvpn client.opvn

Arrancar servicio

systemctl start openvpn@server

Como a la primera no va a funcionar, tendrás que revisar el log:
journalctl -xe

Es muy recomendable, si quieres usar openvpn como servidor y no quieres  complicarte la vida, que no uses clave en el certificado privado del servidor.

En todo caso, se puede investigar en este enlace los parámetros auth-users-pass: https://www.smarthomebeginner.com/configure-openvpn-to-autostart-linux/

El enrutamiento

Vale, ahora ya se puede conectar el cliente. Quizás quieras que tu LAN sea visible desde fuera. Para ello, después de dar muchas vueltas, donde mejor se explica es en esta pregunta de serverfault.

Hay que comprobar los siguientes puntos:

1. Instruir a los clientes para que redirijan todo el tráfico por el túnel.

Para ello habrá que añadir esta línea al fichero de configuración del servidor:

push "redirect-gateway def1"
push "dhcp-option DNS 192.168.1.1" # Dirección del router
push "route 192.168.1.0 255.255.255.0" # Red de la LAN

2. Permitir al servidor enrutar el tráfico

Podemos comprobar el estado del reenvío de paquetes. Si el siguiente comando devuelve un 1, está activado. Si devuelve un 0, desactivado:

# cat /proc/sys/net/ipv4/ip_forward

En nuestro caso queremos activarlo, lanzand desde el servidor el siguiente comando:

# echo 1 > /proc/sys/net/ipv4/ip_forward

Para hacer el cambio permanente se puede hacer editando /etc/sysctl.conf

3. Asegurarse que iptables no bloquea el tráfico

# iptables -I FORWARD -j ACCEPT

4. Hacer un NAT para que el tráfico dentro de nuestro túnel pueda ser redirigido a nuestra LAN

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

Ojo en el punto 4 con la tarjeta que vamos a usar para enrutar (el interface “eth0” en este caso)

Para hacer pesistentes los cambios en iptables

# apt-get install iptables-persistent
# iptables-save > /etc/iptables/rules.v4
# ip6tables-save > /etc/iptables/rules.v6

Script

Un script vale más que mil palabras. En concreto éste:

  1. Crea una clave pública y privada de nuestro CA
  2. Para nuestro servidor OpenVPN, crear una clave privada y una petición de clave pública que será firmada por nuestra CA
  3. Para nuestro cliente OpenVPN, crear una clave privada y una petición de clave pública que será firmada por nuestra CA
  4. Firma la petición del certificado digital del servidor, añadiendo las extensiones de poder usarlo como autenticación en servidor TLS
  5. Firma la petición del certificado digital del cliente

Primero debemos crear el fichero cert-server-extensions.cnf

[ server ]
# Para poder usarlo de certificado en el servidor
extendedKeyUsage = serverAuth
keyUsage = digitalSignature, keyEncipherment

Y a continuación lanzar el siguiente script. En negrita se muestran los parámetros que debemos revisar.

#!/bin/bash
ca_pass=clave_de_la_ca
server_pass=clave_del_servidor
client_pass=clave_del_cliente

echo ———————
echo CREANDO CA
echo ———————
openssl req -x509 -newkey rsa:2048 -passout pass:”$ca_pass” -keyout ca_priv.pem -out ca_pub.pem -days 365

echo ——————————–
echo CREANDO CERTIFICADO DEL SERVIDOR
echo ——————————–
echo Generando petición del certificado del servidor para ser firmado
openssl req -newkey rsa:2048 -subj “/DC=mi,/DC=dominio,/DC=com,/CN=server” -passout pass:”$server_pass” -keyout server_priv.pem -out server_pet.pem

echo ———————————————
echo FIRMANDO EL CERTIFICADO DE SERVIDOR CON LA CA
echo ———————————————
openssl x509 -extfile cert-server-extensions.cnf -extensions ‘server’ -CA ca_pub.pem -passin pass:”$ca_pass” -CAkey ca_priv.pem -req -in server_pet.pem -days 3650 -sha1 -CAcreateserial -out server_pub.pem

echo ——————————-
echo CREANDO CERTIFICADO DEL CLIENTE
echo ——————————-
echo Generando petición del certificado del cliente para ser firmado
openssl req -newkey rsa:2048 -subj “/DC=mi,/DC=dominio,/DC=com,/CN=client” -passout pass:”$client_pass” -keyout client_priv.pem -out client_pet.pem

echo ———————————————
echo FIRMANDO EL CERTIFICADO DE CLIENTE CON LA CA
echo ———————————————
openssl x509 -CA ca_pub.pem -passin pass:”$ca_pass” -CAkey ca_priv.pem -req -in client_pet.pem -days 3650 -sha1 -CAcreateserial -out client_pub.pem

echo ———————————————
echo CREANDO DIFFIE-HELLMAN
echo ———————————————
openssl dhparam -out dh2048.pem 2048

Si no quieres crear el certificado de servidor privado con clave, cosa que como ya se ha comentado facilita un montón la instalación como servicio, tendrás que modificar la línea de creación de la clave privada del certificado privado de servidor:

openssl req -nodes -newkey rsa:2048 -subj "/DC=mi,/DC=dominio,/DC=com,/CN=server" -keyout server_priv.pem -$

Como ves, solo hay que añadir el parametro -nodes