OpenVPN/Configuración con claves asimétricas

Introducción

editar

En el presente trabajo mostraremos con un ejemplo práctico la implementación de una red privada virtual tanto del lado del cliente como del servidor, incluyendo la generación de certificados de seguridad. Tomaremos como caso de estudio una situación bastante común como es la de un usuario remoto que necesita conectarse a la red de la oficina mediante Internet pasando a tomar parte de dicha red como si fuese un puesto más de la misma. Instalación del software Se necesita instalar lo siguiente:

Paquete en Debian o Ubuntu en otro Linux
OpenSSL aptitude install openssl Descargar de http://www.openssl.org y seguir las instrucciones
LZO (opcional si se quiere compresión ) aptitude install liblzo1 http://www.oberhumer.com/opensource/lzo/
OpenVPN aptitude install openvpn http://prdownloads.sourceforge.net/openvpn/openvpn-1.6.0.tar.gz
Controlador tun/tap Ya incluido en kernel superior a 2.4.7


Preparando la prueba

editar

Para poder hacer las pruebas sin tener que contar con varias máquinas reales, vamos a valernos de máquinas virtuales, que en este caso generaremos con vmware-server, aprovechando que recientemente lo liberaron como “free”. Instalaremos linux en una máquina virtual y luego la cloraremos 3 veces de modo de contar con dos servidores y dos clientes. Es decir, para hacerlo más interesante, estaremos suponiendo entonces que el usuario remoto no se conectará directamente a Internet sino que en su hogar también tiene una red doméstica que sale al mundo a través de un router/firewall, como suele verse cada vez con más frecuencia, sobre todo cuando tenemos hijos que quieren jugar con la computadora de la familia mientras nosotros queremos trabajar con el notebook y todos necesitamos salir a Internet. Eso permitirá mostrar alguna configuración adicional que se necesita implementar a los efectos de que todos los pc's de la casa puedan conectarse transparentemente a la oficina, aunque tal vez no sea lo más adecuado si los demás pc's son los de los niños.


Arquitectura

editar

Router de Casa: ifconfig eth0 192.168.6.1 netmask 255.255.255.252 ifconfig eth1 192.168.1.1 netmask 255.255.255.0

Router de la Oficina ifconfig eth0 192.168.6.2 netmask 255.255.255.252 ifconfig eth1 10.66.0.1 netmask 255.255.255.0

En este caso no tenemos Internet en medio, por lo que las interfaces eth0 de cada router las pusimos en realidad en la misma red para que se puedan “ver”.

NOTA: Para que los paquetes puedan pasar de una interfaz a otra en los routers/firewalls se debe habilitar el ruteo entre ellas. En el caso de Linux bastará con decirle al kernel que queremos que dicho ruteo se lleve a cabo, lo cual lograremos con el siguiente comando: echo 1 > /proc/sys/net/ipv4/ip_forward Eso solo tendrá efecto hasta que apaguemos la computadora, con lo cual si se desea rutear permanentemente debemos indicarlo en algún script de inicio del sistema. En el caso de Ubuntu podemos indicarlo simplemente cambiando un 0 por un 1 en la línea correspondiente de /etc/sysctl.conf Ej. net/ipv4/ip_forward=1 También es posible habilitar el “forwarding” desde el script de OpenVPN.


Certificados y claves RSA

editar

Como explicamos en la aproximación teórica previa, existen dos formas de lograr seguridad, uno basado en SSL/TLS mediante certificados y claves RSA y otro en mediante claves estáticas pre-compartidas. En este caso usaremos SSL/TLS ya que es más seguro.

Para construir certificados y claves RSA usamos el comando “openssl”.

Para poder generar certificados vamos a necesitar un “certificado raíz”. En nuestro caso generaremos uno propio y por lo tanto seremos nuestra propia CA (Autoridad Certificadora).


Hoja de ruta

editar

1. Crear un certificado-CA con el cual firmaremos y revocaremos certificados de clientes.
2. Crear un certificado y una clave pública para los clientes.
3. Firmar ese certificado usan el certificado-CA.
4. Distribuir la clave y certificados a los clientes.
5. Configurar los scripts del servidor y de los clientes.
Para los primeros 3 pasos vamos a utilizar una serie de scripts que nos facilitarán la vida dado que invocan los comandos aa decuados con unos cuantos parámetros por default.


Generales
1. mkdir /etc/openvpn
2. cp /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
3. cd /etc/openvpn/easy-rsa
4. editar el archivo vars y cambiar las ultimas 5 variables a nuestro gusto sin dejar ninguna vacía:

export KEY_COUNTRY=URUGUAY
export KEY_PROVINCE=MO
export KEY_CITY=Montevideo
export KEY_ORG="OpenVPN-TEST"
export KEY_EMAIL="yo@mihost.midominio"

5 .. vars
6 ../clean-all


Clave Diffie-Hellman y CA

Ahora creamos la clave Diffie-Hellman con el script build-dh lo cual tardará varios minutos.

# cd /etc/openvpn/easy-rsa
# ./build-dh
Generating DH parameters, 1024 bit long safe prime, generator 2
This is going to take a long time
....+........+.+......+.......................+..................(...)


Creamos el certificado para la CA

# cd /etc/openvpn/easy-rsa
# ./build-ca</nowiki>
Generating a 1024 bit RSA private key
......................................++++++
writing new private key to 'ca.key
-----


A esta altura deben haber quedado creados los siguientes archivos en el subdirectorio keys:

dh1024.pem
ca.crt
ca.key


Par Certificado/Clave del servidor

De los diferentes datos que se irán preguntando el que realmente importa es el “Common Name” dado que el mismo será utilizado “textualmente” en la configuración de los clientes. Usaremos Common Name = openvpn-server
También aparecerán dos preguntas a las que responderemos afirmativamente.

# cd /etc/openvpn/easy-rsa
# ./build-key-server
# openvpn-server

Eso creará los archivos:

openvpn-server.crt
openvpn-server.key
openvpn-server.csr

Hasta ahora hemos logrado tener el certificado de la CA y el certificado y clave para el primer PC de la red virtual.


Par Certificado/Clave de los clientes

Es muy similar a lo realizado para el servidor pero con otro script. Nuevamente poner atención al Comman Name = openvpn-client1

# cd /etc/openvpn/easy-rsa
# ./build-key
# openvpn-client1

Eso creará los archivos:

openvpn-client1.crt
openvpn-client1.key
openvpn-client1.csr


Distribución de claves y certificados

El paso siguiente será determinar cuales archivos de los generados deberán quedar en el servidor y cuales deben ser enviados a los clientes. ATENCIÓN: Necesitará enviar algunos de los archivos por algún canal seguro a sus clientes, para lo cual debe asegurarse que el mecanismo de seguridad de dicho envío sea adecuado, dado que de otro modo de nada servirá todo el trabajo que nos estamos tomando.

A continuación se presenta una tabla en la que se muestra en donde va cada archivo y si debe ser celosamente guardado en secreto o no.

Archivo Descripción Ubicación Secreto
dh1024.pem Parámetros Diffie Hellman servidor -
ca.crt Certificado raíz CA servidor y todos los clientes No
ca.key Clave raíz CA únicamente la máquina encargada de firmar Si
openvpn-server.crt Certificado del servidor servidor No
openvpn-server.key Clave del servidor servidor Si
openvpn-client1.crt Certificado del cliente cliente No
openvpn-client1.key Clave del cliente cliente Si


Configuración de script del Servidor

# cd /etc/openvpn
# mkdir ccd
# gzip -d /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz

Con eso tendremos un archivo llamado server.conf al que le haremos varias modificaciones para adaptarlo a nuestras necesidades:

Variable Valor Comentario
port 1194 puede cambiarse por cualquier otro que queramos, pero los clientes deben saber dicho valor para saber a donde conectarse
proto tcp también pude ser udp pero el cliente debe configurarse de la misma forma
dev tun tun se usa para conexiones de clave asimétrica.

tap puede ser usado para configuraciones más sencillas de clave simétrica pre-compartida

ca ca.crt El certificado CA que generamos
cert openvpn-server.crt El certificado del servidor que generamos
key openvpn-server.key La clave privada que generamos
dh dh1024.pem Parámetros Diffie – Hellman
server 10.8.0.0 255.255.255.0 Red virtual a utilizar.

Cada cliente debe poder alcanzar dicha red

push “route 10.66.0.0 255.255.255.252” Provocará que el cliente cuando se conecte agregue una ruta adecuada para alcanzar la red de la oficina
client-config-dir ccd Directorio en donde se agregarán archivos con información de ruteo para cada cliente que se conecte
route 192.168.1.0 255.255.255.0 Agregará una ruta del lado del servidor para alcanzar la red de la casa

Además será necesario para cada cliente potencial que se conecte, crear un archivo en /etc/openvpn/ccd con el mismo nombre del “Common Name” de los mismos. Esto solo es necesario para los casos en que el cliente no es un puesto conectado directo a Internet sino que se tratad de una red doméstica, tal cual es el ejemplo que venimos siguiendo.

Ejemplo: echo “iroute 192.168.1.0 255.255.255.0” > /etc/openvpn/ccd/openvpn-client1


Configuración del script del cliente

# cd /etc/openvpn
# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf  .

Con eso tendremos un archivo llamado client.conf al que le haremos varias modificaciones para adaptarlo a nuestras necesidades:

Variable Valor Comentario
client Indica que es una configuración cliente
proto tcp también pude ser udp pero debe coincidir con la configuración del servidor
dev tun tun se usa para conexiones de clave asimétrica.

tap puede ser usado para configuraciones más sencillas de clave simétrica pre-compartida

ca ca.crt El certificado CA que generamos
remote 192.168.6.2 443 IP de la interfaz pública del servidor de la oficina y puerto en el que está escuchando el OpenVPN instalado allí
cert openvpn-client.crt El certificado que generamos en el servidor y copiamos en el cliente por algún método “seguro”
key openvpn-client.key La clave privada que nos generaron en el servidor

Retoques en los firewalls

editar

Hay que tener en cuenta que en este ejemplo trabajamos con máquinas virtuales, dos de ellas haciendo las veces de router pero sin firewall.
Cuando tenemos firewall en los servidores hay que tener en cuenta que se necesita agregar reglas que permitan el flujo por el nuevo túnel.
Eso es muy fácil de hacer, ya que cuando se establece el túnel, se crean interfaces virtuales “tunX”, que podremos usar en reglas de iptables para filtrar por ellas.
También es seguro, ya que el túnel solo permite tráfico desde puntos autorizados, con lo cual tranquilamente podemos permitir todo el tráfico en dichas interfaces.

Ej.
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A OUTPUT  -o tun+ -j ACCEPT
iptables -A FORWARD -o tun+ -j ACCEPT

Arranque automático El servidor puede arrancarse de forma manual como se explicará en el siguiente párrafo o también puede ejecutar como demonio.
Para ello existen dos caminos tradicionales.
1.Configurar el servicio xinetd para que escuche en el puerto configurado e invoque al openvpn cuando ingresa alguna conexión.
2.Crear un script de inicio en /etc/init.d y configurarlo en los runlevels adecuados.

Personalmente me gusta más la segunda opción y en sitio de OpenVPN hay varios ejemplos para diversas distribuciones.
En dicho script sería conveniente tener una línea similar a la siguiente:

En SuSE: startproc $OPENVPN_BIN --cd $OPENVPN_DIRCONFIG --config $OPENVPN_FILECONFIG –log-append $log

En Debian / Ubuntu: openvpn --daemon --writepid $piddir/$bn.pid --config $c --cd $work --log-append $log

A probar – Por fin !!!

editar

Para probar, levantaremos la VPN en forma manual.
En el lado del servidor:

# cd /etc/openvpn
# openvpn --config server.conf

En el lado del cliente:

# cd /etc/openvpn
# openvpn --config client.conf

Abrir una terminal en cualquier pc de la casa y hacer algunas pruebas:

ping 10.66.0.1
ping 10.66.0.202
ssh 10.66.0.202

Bibliografía

editar

OpenVPN: Building and Integrating Virtual Private Networks – Markus Feilner – ISBN 1-904811-85 Sito web de OpenVPN. http://openvpn.net/howto.htm Sitio web de Ubuntu. http://www.ubuntu-es.org/node/5290 http://laurel.datsi.fi.upm.es/~rpons/openvpn_como/ En Linux: /usr/share/doc/openvpn man opoenvpn