# OpenVPN/Ejemplo de configuración con claves asimétricas

En el presente trabajo se mostrará 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.
Se tomará 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

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”.
Instalamos linux en una máquina virtual y luego la clonamos 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

Archivo:Arquitectura prueba.png
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

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

* 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 adecuados con unos cuantos parámetros por default.
Generales
* 1. usr@ubusrv:~$ mkdir /etc/openvpn
* 2. usr@ubusrv:~$ cp /usr/share/doc/openvpn/examples/easy-rsa /etc/openvpn
* 3. usr@ubusrv:~$ 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. usr@ubusrv:~$ . vars
* 6. usr@ubusrv:~$ ./clean-all
Clave Diffie-Hellman y CA
Ahora creamos la clave Diffie-Hellman con el script build-dh lo cual tardará varios minutos
usr@ubusrv:~$ ./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
usr@ubusrv:~$ ./build-ca
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.
usr@ubusrv:~$ ./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
usr@ubusrv:~$ ./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
* 1. usr@ubusrv:~$ cd /etc/openvpn
* 2. usr@ubusrv:~$ mkdir ccd
* 3. usr@ubusrv:~$ 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:
usr@ubusrv:~$ echo “iroute 192.168.1.0 255.255.255.0” > /etc/openvpn/ccd/openvpn-client1
Configuración del script del cliente
* 1. usr@ubusrv:~$ cd /etc/openvpn
* 2. usr@ubusrv:~$ 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

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. P ara 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 !!!

Para probar, levantaremos la VPN en forma manual.
En el lado del servidor:
* 1. usr@ubusrv:~$ cd /etc/openvpn
* 2. usr@ubusrv:~$ openvpn --config server.conf
En el lado del cliente:
* 1. usr@ubusrv:~$ cd /etc/openvpn
* 2. usr@ubusrv:~$ 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

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@ubusrv:~$ /usr/share/doc/openvpn
usr@ubusrv:~$ man openvpn
Eso es todo amigos!!!