Supongamos que hemos montado un servidor OpenVPN accesible libremente desde Internet (desde cualquier dirección IP). Este, por ejemplo, es el caso en el que deseamos que clientes conectados desde cualquier ubicación (usuarios remotos y con movilidad) puedan acceder a nuestra red local corporativa.

El problema es que tener un acceso público a nuestra VPN nos vuelve blanco de todo tipo de ataques, con lo cual deseamos mejorar la seguridad de su instalación (hardening). Afortunadamente es posible recurrir al mecanismo de autenticación TLS para crear un firewall HMAC (hash-based message authentication code). Esto permite bloquear ataques de tipo DoS (Denial of Service) y flooding de puertos UDP antes de que se establezca efectivamente la conexión con el servidor OpenVPN.

La opción --tls-auth utiliza una clave estática pre-compartida (PSK, pre-shared key), la cual debe ser generada antes de configurar los clientes y luego distribuida entre los mismos. Esta característica agrega una protección adicional al canal TLS, al requerir que los paquetes entrantes incluyan una firma válida generada utilizando dicha clave PSK.

El beneficio principal es que un cliente sin autenticación no es capaz de causar la misma carga criptográfica de CPU contra el servidor, dado que el tráfico es descartado mucho antes de siquiera intentar validar su certificado. Lo cual ayuda a mitigar ataques DoS.

La desventaja de utilizar esta característica es que si la clave necesita ser cambiada, deberá ser redistribuida por todos los clientes al mismo tiempo. Por otro lado esto agrega una sobrecarga al protocolo TLS/SSL para el tráfico válido, ya que cada paquete debe ser firmado y verificado en cada extremo. Sin embargo esta mejora de seguridad es indispensable para un servidor OpenVPN accesible públicamente a través de Internet.

Por otro lado cabe destacar que esta característica de por sí no mejora en nada la configuración de TLS, sino que agrega una capa de protección adicional.

Este artículo demuestra como cambiar un setup para habilitar autenticación TLS, modificando la configuración del cliente a través de la misma VPN (modo kamikaze=on). Es decir, modificando la configuración de la VPN al mismo tiempo en que es el único medio para acceder a los clientes de la misma. En definitiva, si algo falla: chau. Nos quedamos afuera, perdimos el acceso a los clientes.

Creación de la clave PSK

El primer paso consiste en generar la clave de autenticación TLS (PSK):

root@vpn:~# cd /etc/openvpn/
root@vpn:/etc/openvpn# openvpn --genkey --secret ta.key

Copiar la clave de autenticación a cada clientes a través de la VPN:

root@vpn:/etc/openvpn# scp -P 2222 ta.key user@10.8.0.100:~

Configuración en los clientes

Loguearse en cada cliente a través de la VPN e instalar la clave en su ubicación definitiva:

root@vpn:/etc/openvpn# ssh user@10.8.0.100
user@client:~$ sudo su
root@client:/home/user# mv ta.key /etc/openvpn/
root@client:/home/user# cd /etc/openvpn/
root@client:/etc/openvpn# chown root:root ta.key

A continuación, modificar la configuración de todos los clientes de la VPN:

root@client:/etc/openvpn# nano client.conf

Simplemente se debe agregar la siguiente línea:

tls-auth ta.key 1

Guardar los cambios y verificar que todo esté correcto antes de proseguir:

root@client:/etc/openvpn# ll ta.key 
-rw------- 1 root root 636 Jun 26 15:44 ta.key

ADVERTENCIA: al reiniciar el cliente se pierde temporalmente (al menos si la configuración es correcta) la conexión con la VPN.

Reiniciar el cliente:

root@client:/etc/openvpn# service openvpn restart

En este punto la conexión a través de la VPN se pierde, porque el servidor utiliza una configuración incompatible (sin autenticación TLS). Sin embargo, mantener la sesión abierta (aunque quede "freezada").

Configuración del servidor:

Habiendo configurado todos los clientes, ahora es posible configurar el servidor:

root@vpn:~# nano /etc/openvpn/server.conf

Agregar al línea tls-auth ta.key 0:

# For extra security beyond that provided
# by SSL/TLS, create an "HMAC firewall"
# to help block DoS attacks and UDP port flooding.
#
# Generate with:
#   openvpn --genkey --secret ta.key
#
# The server and each client must have
# a copy of this key.
# The second parameter should be '0'
# on the server and '1' on the clients.
tls-auth ta.key 0 # This file is secret

Finalmente, reiniciar el servidor:

root@vpn:~# service openvpn restart

Si todo es correcto, los clientes vuelven a la vida (se restablecen las conexiones con la VPN):

root@vpn:~# ping 10.8.0.100
PING 10.8.0.100 (10.8.0.100) 56(84) bytes of data.
64 bytes from 10.8.0.100: icmp_seq=1 ttl=64 time=174 ms
64 bytes from 10.8.0.100: icmp_seq=2 ttl=64 time=168 ms
64 bytes from 10.8.0.100: icmp_seq=3 ttl=64 time=167 ms
64 bytes from 10.8.0.100: icmp_seq=4 ttl=64 time=173 ms
^C
--- 10.8.0.100 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 167.857/171.148/174.672/2.941 ms

Si se mantuvieron las sesiones con los clientes abiertas, es posible comprobar que han "resucitado":

root@client:/etc/openvpn# service openvpn restart
root@client:/etc/openvpn#

Esto es fantástico. Al restablecerse el acceso a la VPN, la sesión SSH continúa como si nada hubiese ocurrido. Claro que esto se verifica siempre que estemos dentro del intervalo ClientAliveCountMax ser servidor SSH (ver la página de manual de sshd_config).

Tal como mencionaba la advertencia anterior, en caso de un error en la configuración de un cliente, el acceso a la VPN se pierde por completo y habrá que encontrar otra forma (que no sea a través de la VPN) de abrir una sesión en el mismo para solucionarlo.

Esta tarea es mucho más simple y menos arriesgada cuando se tiene acceso directo en ambos sistemas (cliente y servidor de VPN). Por supuesto no hace falta aclarar que jamás se debe realizar este tipo de cambios en una VPN en producción, porque los riesgos son elevados. Imaginen un cliente de viaje por China que pierde su acceso a la VPN corporativa. La clase de errores que cuestan la cabeza de Jr. SysAdmin. En este caso se trataba de una VPN en desarrollo/testeo con un único cliente, con lo cual el riesgo era mínimo.

Referencias


Tal vez pueda interesarte


Compartí este artículo