7.4.3.1.1. Preparativos

7.4.3.1.1.1. Instalación

openvpn es el mismo en el servidor y el cliente, así que nuestra instalación en ambos casos se reduce[1] a:

# apt-get install openvpn

Además, exclusivamente para el servidor deberemos modificar en /etc/sysctl.conf la línea:

net.ipv4.ip_forward=1

para permitir que acepte paquetes que no son para él. Esta necesidad obedece a que el cliente, para conectar con otros dispositivos de la sede, envía sus paquetes a través del servidor, por lo que este debe aceptar paquetes ajenos,

Advertencia

Si en el servidor VPN hay cortafuegos, debemos asegurarnos de que sus reglas no interfieren en nuestro tráfico.

Nota

El cambio anterior opera automáticamernte cada vez que arranquemos el servidor, pero si queremos que tenga efecto en la ejecución actual debemos ejecutar a mano:

# sysctl -p

7.4.3.1.1.2. Carga de la configuración

La configuración de openvpn se encuentra toda dentro de /etc/openvpn. Dentro de ese fichero puede haber ficheros y subdirectorios, pero aquellos con extensión .conf serán considerados por debian como ficheros que almacen una configuración para establecer un túnel. Un servidor o un cliente tienen capacidad para establecer tantos túneles como se quiera, así que puede haber múltiples ficheros con esta extensión.

En principio, el establecimiento de un túnel puede hacerse ejecutando manualmente:

# openvpn --config /etc/openvpn/mi_tunel.conf

pero debian nos provee con su paquete de algunas facilidades para el establecimiento y parada de los túneles VPN.

7.4.3.1.1.2.1. Como servicio

El primer método de gestión de los túneles VPN es tratarlos como un servicio, esto es, que se gestionan a través de invoke-rc.d o systemctl. Para ello, existe el fichero /etc/default/openvpn que define como ejecutar openvpn para establecer los túneles. Especialmente relevante es la variable AUTOSTART cuyo valor define el nombre de los ficheros de definición que se arrancarán automáticamente. Por ejemplo:

AUTOSTART="trabajo casa"

haría que que arrancar el servicio estableciera los túneles definidos por /etc/openvpn/trabajo.conf y /etc/openvpn/casa.conf. Hay, además, dos nombres especiales:

  • all, que arranca todos los túneles definidos.

  • none, que no arranca ninguno.

Así, pues, para prescindir de esta forma automática de ejecución podemos, o bien deshabilitar el servicio, o bien dejar la línea:

AUTOSTART="none"

7.4.3.1.1.2.2. Como interfaz

El otro modo de tratar cómodamente nuestra configuración es usar el fichero /etc/network/interfaces.

Advertencia

En distribuciones derivadas de ubuntu hay un bug relacionado con esto.

La idea en este caso es establecer y cerrar el túnel al levantar y bajar respectivamente la interfaz virtual asociada al túnel:

iface tun0 inet manual
   openvpn  trabajo

Donde «trabajo» hace referencia al fichero de configuración /etc/openvpn/trabajo.conf. De este modo, podemos establecer el túnel al hacer:

# ifup tun0

y cerrarlo al hacer la operación contrario con la interfaz:

# ifdown tun0

Advertencia

Asegúrese de que el nombre de la interfaz coincide con el que se ha declarado dentro del fichero.

Una variante, si queremos poder establecer (servidor) o tener establecido (cliente) el túnel siempre que sea posible, es incluir la referencia al túnel dentro de la configuración de la interfaz física que se usa para establecerlo. Por ejemplo:

allow-hotplug eth0
iface eth0 inet dhcp
   openvpn client

En este caso, al levantar la interfaz física eth0 también levantamos el túnel y, en consecuencia, se crea la interfaz virtual tun0. Por contra, si se desactiva la interfaz, se parará un servicio VPN que no funcionará en modo alguno si eth0 no nos proporciona conexión.

Nota

Por lo general, el arraque como servicio o esta segunda variante son más apropiados para el servidor, en el que lo habitual es que queremos que brinde siempre la oportunidad de establecer túneles; y la primera variante más apropiada para el cliente, ya que permite desactivar el túnel, pero tener activa la interfaz física.

Nota

Todo lo referido ipara ambos mecanismos de arranque (servidor o interfaz) utiliza el método tradicional de *debian* para la gestión de servicios. Este método usa internamente el servicio de systemd llamado openvpn y espera que los ficheros de configuración se incluyan dentro de /etc/openvpn. No obstante, debian trae también los servicios openvpn-server y openvpn-client. pensados para que la configuración se escriba dentro de los directorios /etc/openvpn/server y /etc/openvpn/client.

7.4.3.1.1.3. Preparación

Antes de pasar a ver cómo se configura openvpn (o sea, ver cómo se escriben los ficheros .conf) es conveniente indicar cómo dejar preparada la máquina.

7.4.3.1.1.3.1. Servidor

En el servidor debemos generar las claves del servidor. Para ello tenemos dos alternativas:

  1. Generar las claves firmándolas con un certificado de entidad certificadora autogenerado. Este mismo certificado de entidad certificadora es el que se usa para generar los certificados de los clientes, si es que queremos que éstos usen este mecanismo de autenticación. Para este método, lo más sencillo es valerse de easy-rsa.

  2. Utilizar un certificado de servidor fiable del que ya dispongamos. Por ejemplo, el obtenido con letsencrypt. La desventaja de esta vía es que no podemos generar certificados de cliente y, en consecuencis, el método de autenticación tendrá que ser a través de usuario y contraseña.

7.4.3.1.1.3.1.1. Usando easy-rsa

Advertencia

easy-rsa va ya por su versión 3, pero Stretch (la versión estable) a la redacción de estos párrafos es aún la 2. En ambas cambian el procedimiento de generación de certificados. Se ilutrará aquí el procedimiento para la versión 2.

Lo primero es instalar los scripts:

# apt-get install easy-rsa

para a continuación preparar el directorio dentro del cual generaremos certificados gracias a ellos:

# make-cadir /etc/openvpn/ca
# cd /etc/openvpn/ca
# ln -s openssl-1.0.0.cnf openssl.cnf

Hecho esto, conviene editar el fichero /etc/openvpn/ca/vars y definir algunas variables, a fin de que sea más cómodo generar luego certificados:

export KEY_COUNTRY="ES"
export KEY_PROVINCE="HU"
export KEY_CITY="IslaCristina"
export KEY_ORG="IESPadreJoseMiravent"
export KEY_EMAIL="administrador@infomiravent.es"
export KEY_OU="DptoInformatica"

Con estos cambios, ya se está en condiciones de empezar la generación:

# source vars
# ./clean-all

Debemos generar el certificado de entidad certificadora, la clave del servidor, los parámetros Diffie-Hellman y el fichero ta.key:

# ./build-ca
# ./build-key-server server
# ./build-dh
# openvpn --genkey --secret keys/ta.key

Creados todos los ficheros necesarios, deben moverse a una ubicación adecuada:

# mkdir ../{certs,keys}
# chmod 700 ../keys
# cp keys/{ca,server,ta}.key ../keys
# cp keys/{ca,server}.crt ../certs
# cp keys/dh2048.pem ../keys

En caso de que usemos este método, podemos optar porque los clientes se identifiquen mediante certificado o mediante usuario/contraseña. En el primer caso, es necesario que en el servidor se genere el cerficado de cada cliente del siguiente modo:

# cd /etc/openvpn/ca
# source vars
# ./build-key cliente1

lo cual generará los ficheros keys/cliente1.key y keys/cliente1.crt que deberán copiarse en el cliente.

El segundo caso lo trataremos bajo el siguiente epígrafe.

7.4.3.1.1.3.1.2. Usando letsencrypt

En este caso, en vez de generar un certificado de entidad certificadora y usarlo para firmar un certificado de servidor, se usa el certificado de letsencrupt como certificado de servidor. La obtención del certificado ya se discutió bajo el epígrafe correspondiente y. obtenido. se tiene dentro de /etc/letsencrypt/live/www.example.net:

  • La clave privada del servidor en privkey.pem.

  • La clave pública del servidor en cert.pem.

  • La clave pública de Let’s Encrypt en chain.pem.

Ahora bien, el certificado de Let’s Encrypt no es un certificado raíz, sino que está firmado por una entidad de nivel superior:

# openssl x509 -in chain.pem -text -noout | grep 'Issuer:'
        Issuer: O = Digital Signature Trust Co., CN = DST Root CA X3

Lo que nos obliga a encadenar ambos certificados para obtener el ca.crt que requiere openvpn:

# mkdir -p /etc/openvpn/certs
# cat /etc/ssl/certs/DST_Root_CA_X3.pem /etc/letsencrypt/live/www.example.net/chain.pem > /etc/openvpn/certs/ca.crt

También debemos pasar la clave pública y privada del servidor:

# mkdir -pm 700 /etc/openvpn/keys
# ln -s /etc/openvpn/keys/server.key /etc/letsencrypt/live/www.example.net/privkey.pem
# ln -s /etc/openvpn/keys/server.crt /etc/letsencrypt/live/www.example.net/cert.pem

y generar los parámetros Diffie-Helman y ta.key:

# openssl dhparam -out keys/dh2048.pem 2048
# openvpn --genkey --secret keys/ta.key

El uso de este certificado, exige que en la configuración del servidor (el .conf) añadamos la línea:

tls-verify "/usr/share/openvpn/verify-cn /etc/openvpn/allowed-cns"

e incluyamos dentro del fichero allowed-cns el nombre con el que se creó el certificado[2]:

# echo "www.exanple.net" > /etc/openvpn/allowed-cns

Además, debe parchearse una línea del script[3] verfy-cn para que funcione con los certificados de Let’s Encrypt:

if ($x509 =~ /( |^)CN=([^,]+)/) {

Por último, este modo de proceder obliga a que los clientes se autentiquen mediante usuario y contraseña para lo cual el fichero de configuración que ya se tratará, deberá contener estas líneas:

verify-client-cert none
username-as-common-name
tmp-dir "/etc/openvpn/tmp/"
plugin /usr/lib/openvpn/openvpn-auth-pam.so /etc/pam.d/login

Además debe crearse el directorio citado en esas líneas:

# mkdir -m 1777 /etc/openvpn/tmp

7.4.3.1.1.3.2. Cliente

En el cliente, en cualquier, caso debemos copiar el certificado de la entidad certificadora y el fichero ta.key. Supuesto que ya los hayamos trasmitido al cliente por algún medio (ssh, por ejemplo), podemos hacer lo siguiente:

# mkdir -p /etc/openvpn/client/example
# mv ca.crt /etc/openvpn/client/example
# mv ta.key /etc/openvpn/client/example

Por otro lado, si la autenticación es mediante certificado, deberemos también hacer llegar al cliente sus claves pública y privada generadas en el servidor y copiarlas en lugar adecuado:

# mkdir /etc/openvpn/client/example
# mv cliente1.crt /etc/openvpn/client/example
# mv cliente1.key /etc/openvpn/client/example
# chmod 700 /etc/openvpn/client/example/cliente1.key

y, en su momento, deberán añadirse un par de líneas en la configuración para declarar que estas son las claves:

cert client/examnple/cliente.crt
key client/example/cliente.key

Si, por el contrario, la autenticación es mediante contraseña, es necesario incluir la línea:

auth-user-pass client/example/ident

para declarar el fichero que almacenará las claves[4] e incluir dentro de este el usuario y contrasña de acceso (cada cosa en una línea distinta):

# cat > /etc/openvpn/client/example/ident
usuario
contraseña

# chmod 600 /etc/openvpn/client/example/ident

El otro aspecto que afecta al cliente es la forma en que hayamos generado el certificado del servidor, porque varía la forma de verificar la autenticidad del certificado que nos ofrece. Si el certificado se obtuvo a través de una entidad certificada autogenerada, es necesario incluir en la configuración la línea:

remote-cert-tls server

y si se usó el certificado de Let’s Encrypt:

verify-x509-name "CN=www.example.net"

Notas al pie