¡Bienvenidos a una nueva entrada!

En esta entrada, voy a mostrar como configurar, paso a paso, un servidor OpenVPN en routers cuyo sistema operativo sea EdgeOS.
El objetivo de tener un servidor VPN instalado no es más que poder acceder a la red de nuestra casa/oficina/empresa (donde tengamos el router instalado) desde el exterior de una forma segura.

En mi caso, el router usado es Ubiquiti EdgeRouter-X cuya versión de sistema operativo EdgeOS es 1.10.9.

Generación certificados y claves

Como primer paso, debemos entrar por SSH a nuestro router y cambiar de usuario a root para continuar con el proceso.

ssh ubnt@<ip-router>
sudo su -

Una vez dentro de nuestro router, debemos crear una CA (Certification Authority) para poder crear los certificados que usarán los clientes (dispositivos) para conectarse a nuestro servidor desde fuera de casa.

cd /usr/lib/ssl/misc/
./CA.sh -newca

Para poder crear la CA, debemos rellenar los datos que nos va a pedir.

PEM Passphrase: Abc123..(creamos una contraseña, en mi caso Abc123..)
Country Name: ES (código del pais, en mi caso es ES)
State Or Province Name: Malaga (Nombre de la comunidad autónoma, en mi caso Malaga)
Locality Name: Malaga (Nombre de la ciudad, en mi caso Malaga)
Organization Name: Jeronimo Diaz (Nombre de la organización)
Organizational Unit Name: (Nombre de la unidad de la organización)
Common Name: UBNT Server
Email Address: email@example.com (Introducimos un email)

Una vez hemos creado la CA, debemos crear el certificado que el servidor (router) va a ofrecer a los clientes que se conecten:

./CA.sh -newreq

Al igual que al crear una CA, se nos va a solicitar ciertos datos.

Country Name: ES
State Or Province Name: Malaga
Locality Name: Malaga
Organization Name: Jeronimo Diaz
Organizational Unit Name:
Common Name: Server
Email Address: email@example.com

Para que este certificado sea valido (el servidor lo reconozca como un certificado autentico creado por nosotros), debe ser firmado por la CA que está siendo usada por el router. Por tanto, debemos firmarlo.

./CA.sh -sign

Una vez hemos firmado el certificado, vamos a copiar estos ficheros a la ruta que, posteriormente, vamos a indicar al servicio de OpenVPN que debe leer.

cp /usr/lib/ssl/misc/demoCA/cacert.pem /config/auth/
cp /usr/lib/ssl/misc/demoCA/private/cakey.pem /config/auth/
mv /usr/lib/ssl/misc/newcert.pem /config/auth/server.pem
mv /usr/lib/ssl/misc/newkey.pem /config/auth/server.key

Para poder transmitir los datos de forma segura desde el cliente, el cual está fuera de casa, y el servidor (nuestro router), debemos configurar una clave, denominada clave Diffie-Hellman. Con este sistema de cifrado, conseguimos que la información que se va a enviar desde el cliente hasta el servidor, se cifre antes de salir del cliente y, una vez está en el servidor, se descifre, para así evitar que esta información pueda ser leída por terceros.
La generación de esta clave llevará un rato. Por tanto, paciencia al ejecutar el siguiente comando.

openssl dhparam -out /config/auth/dh2048.pem -2 2048

El siguiente paso es desencriptar la clave que se ha generado al crear el certificado que nuestro servidor va a ofrecer.

openssl rsa -in /config/auth/server.key -out /config/auth/server-decrypted.key
mv /config/auth/server-decrypted.key /config/auth/server.key

Aunque, de momento, no tenemos ningún cliente configurado, en el futuro, nos puede surgir que queramos revocar algún certificado (prohibir que se conecte un cliente). Por ello, debemos generar un fichero que contiene una lista de clientes a los que prohibimos que se conecten. Esta lista debe ser regenerada de forma periódica y cada vez que queramos prohibir el acceso a un cliente. De forma predeterminada, debe regenerarse cada 30 días aunque si se revoca un certificado antes de que pase este periodo, se debe regenerar esta lista.

openssl ca -gencrl -out crl.pem
cp crl.pem /config/auth

Para poder comprobar cuando ha de renovarse de nuevo, podemos hacerlo con el siguiente comando:

openssl crl -in /config/auth/crl.pem -noout -text

Por ultimo, antes de comentar a configurar nuestro servidor OpenVPN, para securizar más nuestro servidor OpenVPN, vamos a generar una clave TLS para evitar que OpenVPN responda a paquetes que no contengan esta clave.

openvpn --genkey --secret ta.key
cp ta.key /config/auth

Configuración OpenVPN

Tras realizar estos pasos, ya tenemos todo lo necesario para poder configurar nuestro servidor OpenVPN. Para ello, ejecutamos los siguientes comandos:

configure
set interfaces openvpn vtun0 mode server
set interfaces openvpn vtun0 server subnet X.X.X.X/X
set interfaces openvpn vtun0 server push-route X.X.X.X/X
set interfaces openvpn vtun0 server name-server X.X.X.X
set interfaces openvpn vtun0 tls ca-cert-file /config/auth/cacert.pem
set interfaces openvpn vtun0 tls cert-file /config/auth/server.pem
set interfaces openvpn vtun0 tls key-file /config/auth/server.key
set interfaces openvpn vtun0 tls dh-file /config/auth/dh2048.pem
set interfaces openvpn vtun0 tls crl-file /config/auth/crl.pem
set interfaces openvpn vtun0 description "OpenVPN server"
set interfaces openvpn vtun0 encryption aes256
set interfaces openvpn vtun0 hash sha256
set interfaces openvpn vtun0 openvpn-option "--port 1194"
set interfaces openvpn vtun0 openvpn-option --tls-server
set interfaces openvpn vtun0 openvpn-option "--tls-auth /config/auth/ta.key 0"
set interfaces openvpn vtun0 openvpn-option "--comp-lzo yes"
set interfaces openvpn vtun0 openvpn-option --persist-key
set interfaces openvpn vtun0 openvpn-option --persist-tun
set interfaces openvpn vtun0 openvpn-option "--keepalive 10 120"
set interfaces openvpn vtun0 openvpn-option "--user nobody"
set interfaces openvpn vtun0 openvpn-option "--group nogroup"
set interfaces openvpn vtun0 openvpn-option "--ifconfig-pool-persist /var/log/ipp.txt"
set interfaces openvpn vtun0 openvpn-option "--status /var/log/openvpn-status.log"
set service dns forwarding listen-on vtun0

Hay que tener en cuenta que:
subnet: Rango de red que vamos a asignar a los clientes que se conecten al servidor OpenVPN
push-route: Rangos de red que queremos que los clientes que se conecten tengan acceso
name-server: IP del gateway de salida de la subnet que hemos asignado a los clientes que se conecten al servidor OpenVPN

Una vez hemos configurado el servidor OpenVPN, debemos configurar las reglas de firewall para que acepte conexiones entrantes cuyo destino es el servidor OpenVPN.

set firewall name WAN_LOCAL rule 30 action accept
set firewall name WAN_LOCAL rule 30 description OpenVPN
set firewall name WAN_LOCAL rule 30 destination port 1194
set firewall name WAN_LOCAL rule 30 protocol udp
commit
save
exit

Con esto, ya tendríamos nuestro servidor OpenVPN configurado. Ahora es el turno de generar un certificado para que se pueda conectar un cliente. Los siguientes pasos hay que realizarlos para cada cliente que queramos que pueda conectarse a nuestro servidor OpenVPN.

cd /usr/lib/ssl/misc
./CA.sh -newreq
./CA.sh -sign
mv newcert.pem /config/auth/client1.pem
mv newkey.pem /config/auth/client1.key
openssl rsa -in /config/auth/client1.key -out /config/auth/client1-decrypted.key
mv /config/auth/client1-decrypted.key /config/auth/client1.key

Al igual que cuando hemos creado nuestra CA y nuestro certificado para el servidor, nos va a pedir todos los atributos que va a contener el certificado. Hay que tener en cuenta que, para cada cliente, el atributo Common Name (CN) debe ser diferente ya que es el atributo utilizado para poder distinguir cada cliente.

Fichero cliente

Por ultimo, para que el cliente pueda conectarse a nuestro servidor, debemos generarle un fichero en formato .ovpn ya que, la aplicación OpenVPN usada para conectarse a nuestro router, es el lenguaje que comprende.

client
dev tun
proto udp
remote dominio\ip 1194
cipher AES-256-CBC
redirect-gateway def1
auth SHA256
resolv-retry infinite
nobind
comp-lzo yes
persist-key
persist-tun
user nobody
group nogroup
verb 3
key-direction 1
<ca>
pegar contenido /config/auth/cacert.pem
</ca>
<cert>
pegar /config/auth/client.pem
</cert>
<key>
pegar /config/auth/client.key
</key>
<tls-auth>
pegar /config/auth/ta.key
</tls-auth>

Una vez generado este fichero, se lo mandamos al cliente para que pueda conectarse a nuestro router.

Revocar certificado

Anteriormente, he mencionado que podemos prohibir el acceso a un cliente. Para poder ello, debemos conocer cual es el CN de este cliente. Esto lo podemos saber en la lista de clientes que se almacena en el servidor.

cat /usr/lib/ssl/misc/demoCA/index.txt

V       231101212507Z           89A35FBCB65F3220        unknown /C=ES/ST=Malaga/O=Jeronimo Diaz/CN=UBNT Jeronimo Diaz Server/emailAddress=xxxxxxxx
V       211101213123Z           89A35FBCB65F3221        unknown /C=ES/ST=Malaga/L=Malaga/O=Jeronimo Diaz/CN=VPN Server/emailAddress=xxxxxxxxxx
V       211101213503Z           89A35FBCB65F3222        unknown /C=ES/ST=Malaga/L=Malaga/O=Jeronimo Diaz/CN=Example Common Name/emailAddress=xxxxxxxx

Una vez tenemos localizado el cliente al que queremos prohibir el acceso (en nuestro caso será a Example Common Name, debemos anotar el ID que le corresponde (89A35FBCB65F3222) para poder revocar este certificado. Esto se hace con el siguiente comando:

cd /usr/lib/ssl/misc
openssl ca -revoke demoCA/newcerts/<id_certificado>.pem # En nuestro caso 89A35FBCB65F3222

Una vez hemos revocado el certificado, tal y como hemos dicho anteriormente, debemos regenerar la lista de certificados revocados y copiarla en la ruta donde OpenVPN busca dicha lista.

openssl ca -gencrl -out crl.pem
cp crl.pem /config/auth

Esto sería todo lo necesario para una configuración básica de un servidor OpenVPN en EdgeOS junto con la creación/revocación de certificados de cliente.

Espero que os haya servido. Cualquier duda, dejádmela en los comentarios e intentaré ayudaros.

¡Hasta la próxima!