VPN con el protocolo SSL/TLS y OpenVPN

Rafa Morales 5 Noviembre 2013
14min
0
OpenVPN

Tener un servidor OpenVPN nos ofrecerá dos funcionalidades muy interesantes:

  • Realizar conexiones seguras (encriptadas).
  • Acceder a recursos internos de nuestra red local desde el exterior.

En el siguiente documento tenéis mucha más información sobre su funcionamiento (VPN remota con OpenVPN y SSL).

Podéis comparar las características de OpenVPN con el resto de protocolos en el siguiente enlace:

http://es.giganews.com/vyprvpn/compare-vpn-protocols.html

Podemos configurar tres esquemas de trabajo diferentes. Utilizaremos la estructura de red de las siguientes imágenes para explicar cada uno de dichos esquemas:

  • Arquitectura Host-to-Net (mediante túnel).
  • Arquitectura Host-to-Net (mediante bridge).
  • Arquitectura Net-to-Net (mediante túnel).

Openvpn Túnel

Openvpn Bridge

 

Crear una autoridad certificadora y generar certificados con easy-RSA

OpenVPN se basa en OpenSSL para implementar la criptografía SSL/TLS. Para ello tenemos dos opciones:

  • Configurar una clave privada compartida.
  • Configurar un certificado con el estándar X.509 basado en infraestructura de llave pública.

Para este tutorial utilizaremos la segunda opción, aprovechando que OpenVPN incorpora todo lo necesario para hacerlo.

 

Antes que nada deberemos proceder a instalar OpenVPN en el servidor:

apt-get install openvpn

 

Después de la instalación, si nos dirigimos a la carpeta /usr/share/doc/openvpn/examples encontraremos distintas carpetas con ejemplos de configuración, claves, scripts y lo que ahora nos ocupa, con la carpeta easy-rsa, que nos ayudará a crear nuestra propia autoridad certificadora con RSAAsí que procederemos a copiar esta carpeta de ejemplo a la ubicación que queramos para trabajar con ella:

cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0/* /etc/openvpn/

 

NOTA: Los siguientes comandos los vamos a ejecutar siempre teniendo como directorio de trabajo /etc/openvpn

El siguiente paso será editar el archivo vars llenándolo con nuestra información. Así que lo abrimos y lo rellenamos con nuestros datos.

nano /etc/openvpn/vars

export KEY_COUNTRY="ES"
export KEY_PROVINCE="CORDOBA"
export KEY_CITY="Cordoba"
export KEY_ORG="SudoSu"
export KEY_EMAIL="info@ticarte.com"
export KEY_CN=Info
export KEY_NAME=Info
export KEY_OU=IT

Después de esto ya estamos listos para exportar los datos del archivo vars y crear dichas variables de entorno. IMPORTANTE: ejecutarlo situados en el directorio de openvpn:

/etc/openvpn# source vars

 

Ahora ejecutaremos el script clean-all que se encargará de eliminar una posible carpeta de claves anteriormente creada. IMPORTANTE: ejecutarlo situados en el directorio de openvn:

/etc/openvpn# ./clean-all

 

Hecho esto vamos a crear el par de claves de la propia Autoridad Certificadora (CA). Que nos preguntará acerca de los datos configurados anteriormente:

/etc/openvpn/build-ca

 

Llegados aquí ya somos capaces de generar nuestros propios certificados firmados. Con ello crearemos nuestro certificado para el servidor VPN (clave privada) y los parámetros Diffie-Hellman utilizados para establecer la conexión SSL/TLS. Para el certificado del servidor ejecutamos lo siguioente, y se nos preguntarán los mismos datos que en el momento de la generación de los certificados de la CA, con lo que contestaremos con los datos deseados y seguiremos las instrucciones.

/etc/openvpn/build-key-server servidor

 

Ahora vamos con los parámetros Diffie-Hellman:

/etc/openvpn/build-dh

 

Y por último con la clave para cada uno de los usuarios que se conecten vía VPN. Y seguiremos los pasos rellenando los campos que se nos pregunten.

/etc/openvpn/build-key cliente

 

Si ahora nos vamos a la carpeta /etc/openvpn/keys (o la que hayamos asignado en el archivo vars) encontraremos un buen puñado de certificados y claves con distintos fines. Vamos ver qué nos interesa de aquí para esta parte del tutorial:

  • ca.crt: Este es el certificado público de la CA, que tendremos que usar en todos los clientes y en el servidor.
  • servidor.crt y servidor.key: Certificado público y privado respectivamente del servidor. Solo los usaremos en el servidor.
  • dh1024.pem: Los parámetros Diffie-Hellman que se ubicarán sólo en la carpeta de OpenVPN del servidor.
  • cliente.crt y cliente.key: Certificados público y privado de usuario que utilizaremos en los dispositivos de dicho usuario.

Así que vamos a distribuir los distintos archivos en su sitio dentro del servidor:

cp /etc/openvpn/keys/ca.crt /etc/ssl/certs/SudoSu.crt
cp /etc/openvpn/keys/servidor.crt /etc/ssl/certs/
cp /etc/openvpn/keys/servidor.key /etc/ssl/private/
cp /etc/openvpn/keys/dh1024.pem /etc/openvpn/

NOTA: La ubicación de los certificados se puede configurar a mano en el archivo de configuración correspondiente de OpenVPN que vamos a ver a continuación, pero los he copiado a los directorios donde se suelen almacenar normalmente en el sistema.

 

Configuración Host-to-Net del servidor OpenVPN

Con el tema de los certificados solucionado ahora toca afrontar la configuración del servidor OpenVPN en si.

OpenVPN al arrancar, por defecto, intenta iniciar todas las conexiones VPN configuradas en los archivos *.conf dentro de su directorio/etc/openvpn/.

Con su instalación, al igual que trae easy-RSA para no complicarnos mucho la vida con el tema de los certificados, también trae una configuración por defecto sobre la que podremos trabajar. Lo primero que haremos será copiar esta configuración a nuestro directorio de OpenVPN para trabajar sobre él y lo descomprimimos:

cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/

gunzip /etc/openvpn/server.conf.gz

 

Existe dos maneras diferentes de configurar el servidor a la hora de asignar IPs y trabajar con las conexiones de los clientes:

  • Modo enrutamiento, túnel o ruted: En este caso el servidor creará una red nueva para las conexiones VPN, diferente a las redes que se están usando tanto en el servidor como en los clientes, y realizará un enrutamiento entre una red y otra. Conlleva habilitar el enrutamiento en el servidor si queremos que el cliente conecte con el resto de la red (leer cómo habilitar el enrutamiento).
  • Modo puente o bridged: En este caso el servidor otorgará una IP de una de sus redes locales directamente, y tratará la conexión como si de un host más conectado al switch se tratara. Conlleva más uso de recursos del equipo y de configuración.

 

El archivo /etc/openvpn/server.conf que hemos descomprimido nos servirá para realizar ambas configuraciones. El archivo es bastante extenso pero está muy bien documentado, además incorpora una configuración “out of the box” funcional, por lo cual comentaremos las opciones que se deben tocar para funcione de manera básica.

Si elegimos la opción de enrutamiento, utilizando una red nueva, el fichero debe quedar de la siguiente manera:

# Tipo de interfaz que se creará
dev tun

# Los certificados anteriormente creados y ubicados
# El archivo "servidor.key" debería mantenerse en secreto
ca /etc/ssl/certs/SudoSu.crt
cert /etc/ssl/certs/servidor.crt
key /etc/ssl/private/servidor.key
 
# Parámetros Diffie-Hellman
dh /etc/openvpn/dh1024.pem

# Red que se asignará a la VPN
# El servidor tomará automáticamente la IP 1 de esa red
server 10.10.10.0 255.255.255.0

# Habilitamos a los clientes conectados para que puedan acceder a la subnet interna
# mediante una ruta estática que se le creará al conectarse a la VPN
# o a cualquier otra red que se utilice en el destino
push "route 10.0.1.0 255.255.255.0"

Si elegimos la opción de puente, utilizando la misma red del servidor, el fichero debe quedar de la siguiente manera (ATENCIÓN que hay que comentar líneas):

# Tipo de interfaz que se creará (comentar "dev tun")
# dev tun
dev tap0

# Los certificados anteriormente creados y ubicados
# El archivo "servidor.key" debería mantenerse en secreto
ca /etc/ssl/certs/SudoSu.crt
cert /etc/ssl/certs/servidor.crt
key /etc/ssl/private/servidor.key

# Parámetros Diffie-Hellman
dh /etc/openvpn/dh1024.pem

# Red que se asignará a la VPN (comentar)
# server 10.10.10.0 255.255.255.0

# Habilitamos a los clientes conectados para que puedan acceder a la subnet interna
# mediante una ruta estática que se le creará al conectarse a la VPN (comentar)
# push "route 10.0.1.0 255.255.255.0"

# Configuramos la IP que ya tiene el servidor, la máscara de red de esa misma red,
# la IP inicial y final para definir un rango de donde otorgar direcciones IP a los clientes.
# Tener en cuenta que ese rango no debe pertenecer al servidor DHCP que haya en la red.
server-bridge 10.0.1.1 255.255.255.0 10.0.1.200 10.0.1.220

 

Si hemos elegido la configuración de enrutamiento, ya tendremos la parte de configuración del servidor OpenVPN completa, ahora sólo nos falta reiniciar el servicio OpenVPN, lo que cargará todos los archivos *.conf de la carpeta /etc/openvpn, con lo cual quedará creada nuestra interfaz tun0.

/etc/init.d/openvpn restart

 

Si hemos elegido la configuración en puente, SÓLO EN ESTE CASO, tendremos que preparar la interfaz eth como interfaz br, para que permita el modo bridge. Para ello comenzamos instalando el paquete que permita este modo de trabajo en el sistema:

apt-get install bridge-utils

Copiamos los scripts de inicio y parada del modo bridge. Estos ficheros ya tienen permisos de ejecución asignados por defecto.

cp /usr/share/doc/openvpn/examples/sample-scripts/bridge-start /etc/openvpn/
cp /usr/share/doc/openvpn/examples/sample-scripts/bridge-stop /etc/openvpn/

Y configuramos el script de inicio, /etc/openvpn/bridge-start, con los parámetros de la red en la que deseemos configurar el modo puente:

eth="eth1"
eth_ip="10.0.1.1"
eth_netmask="255.255.255.0"
eth_broadcast="10.0.1.255"

Iniciamos el modo puente ejecutando el script:

/etc/openvpn/bridge-start

La configuración del servidor OpenVPN ya estaría completa, ahora solo nos falta reiniciar el servicio OpenVPN, lo que cargará todos los archivos *.conf de la carpeta /etc/openvpn, con lo cual quedará creada nuestra interfaz br0 y tap0.

/etc/init.d/openvpn restart

 

Configuración Net-to-Net del servidor OpenVPN

En el caso anterior, el servidor nunca va a poder acceder a la subred del cliente, ya que no posee las rutas necesarias para encaminar los paquetes a dicha red. En el caso de que quisiéramos conseguir dicho objetivo, tendríamos que AÑADIR a la configuración sel servidor en modo Host-to-Net que se ha explicado anteriormente, los siguientes parámetros.

 

Al fichero /etc/openvpn/server.conf le añadimos la siguiente configuración:

# Habilitamos que cada cliente pueda tener su propio fichero de configuración personalizado
client-config-dir ccd
# Permite que los clientes se vean entre ellos
client-to-client
# Añadimos la ruta para que el servidor encuentre la red del cliente
route 10.0.2.0 255.255.255.0
push "route 10.0.2.0 255.255.255.0"

 

Creamos el directorio de configuración personalizada para los clientes:

mkdir /etc/openvpn/ccd

 

En dicho directorio tenemos que crear un fichero con el nombre igual que el "Common Name" que le pusimos al certificado que generamos para el cliente:

touch /etc/openvpn/ccd/cliente

Y añadimos a ese fichero las siguientes líneas:

# La ruta que hay que añadir al servidor para alcanzar la red del cliente
iroute 10.0.2.0 255.255.255.0
# Las IPs fijas que queramos asignar al cliente (opcional)
ifconfig-push 10.10.10.61 10.10.10.62

 

Se necesita repetir varias veces la ruta porque una indica la ruta al paquete desde el kernel a OpenVPN, y otra desde OpenVPN al kernel.

Sólo nos quedará reiniciar el servicio en el servidor y volver a lanzar la conexión VPN en el cliente.

 

Configuración del cliente VPN

La instalación del cliente OpenVPN en GNU/Linux guarda muchas similitudes con la de la parte servidor, de hecho el paquete que instalaremos será exactamente el mismo. La configuración del cliente es independiente de si en el servidor se utiliza el modo de enrutamiento o el modo puente, sólo modificando un parámetro como veremos a continuación.

Previamente, necesitaremos poseer los siguientes certificados necesarios para la conexión SSL/TLS:

  • Clave pública de la CA: SudoSu.crt.
  • Clave pública de usuario: cliente.crt.
  • Clave privada de usuario: cliente.key.

Los certificados los ubicaremos igual que en el anterior tutorial:

cp /directorio_con_certificados/SudoSu.crt /etc/ssl/certs/
cp /directorio_con_certificados/cliente.crt /etc/ssl/certs/
cp /directorio_con_certificados/cliente.key /etc/ssl/private/

 

Instalamos OpenVPN con el gestor de paquetes:

apt-get install openvpn

 

Como se dijo en el artículo de la parte servidor el comportamiento de OpenVPN por defecto es el de cargar todos los archivos *.conf de su directorio /etc/openvpn al ejecutarse el servicio. Si no quisiéramos este comportamiento, editaríamos el archivo de configuración de OpenVPN para que la conexión sólo se establezca cuando se le solicite.

nano /etc/default/openvpn

Y descomentamos la línea:

AUTOSTART="none"

 

Lo siguiente que haremos es copiar el archivo de configuración de cliente de ejemplo que podemos encontrar en el directorio de documentación del programa al directorio de trabajo del mismo.

Podemos copiar el fichero con diferentes nombres, uno para cada una de las conexiones VPN que queramos lanzar desde el equipo.

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf \
   /etc/openvpn/conexion.conf

Aquí básicamente deberemos configurar tres cosas: la dirección de nuestro servidor OpenVPN, la ruta hacia los certificados anteriormente citados y forzar que todo el tráfico se envíe a través de la VPN.

# Tipo de interfaz que se creará 
# tun para enrutamiento, tap para puente (elegir una u otra)
# dev tap
dev tun

# Nombre o dirección IP del servidor, y el puerto
remote servidor.com 1194
 
# Ruta de los certificados
ca /etc/ssl/certs/SudoSu.crt
cert /etc/ssl/certs/cliente.crt
key /etc/ssl/private/cliente.key

 

Si queremos lanzar manualmente la conexión VPN al servidor, ejecutaremos el siguiente comando. Podemos lanzarlo en segundo plano si queremos seguir utilizando la misma terminal en la que estamos trabajando. Si la lanzamos en primer plano la cancelaremos con Ctrl+C, pero si la lanzamos en segundo plano la cancelaremos con el comando kill y su PID (leer más sobre procesos).

openvpn /etc/openvpn/conexion.conf &

Lo que debería acabar dándonos el siguiente mensaje por pantalla:

Initialization Sequence Completed

 

En el momento en el que esto pase ya estará establecida la VPN. Para comprobarlo podemos hacer ping a la IP por defecto que hayamos asignado al servidor en la interfaz tun0 o tap0:

ping 10.10.10.1

 

Registro de sucesos y errores

Podemos consultar todos los sucesos y errores de OpenVpn en el siguiente archivo de registro por defecto:

cat /var/log/syslog

 

Basado en los artículos de http://sobrebits.com y http://tuxjm,net.