Preparativos ************ Instalación =========== :program:`openvpn` es el mismo en el servidor y el cliente, así que nuestra instalación en ambos casos se reduce\ [#]_ a:: # apt-get install openvpn Además, **exclusivamente para el servidor** deberemos modificar en :file:`/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, .. warning:: Si en el servidor |VPN| hay cortafuegos, debemos asegurarnos de que sus reglas no interfieren en nuestro tráfico. .. note:: 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 Carga de la configuración ========================= La configuración de :program:`openvpn` se encuentra toda dentro de :file:`/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|. 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 :ref:`invoke-rc.d ` o :ref:`systemctl `. Para ello, existe el fichero :file:`/etc/default/openvpn` que define como ejecutar :command:`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 :file:`/etc/openvpn/trabajo.conf` y :file:`/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" Como interfaz ------------- El otro modo de tratar cómodamente nuestra configuración es usar el fichero :file:`/etc/network/interfaces`. .. warning:: 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 :file:`/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 .. warning:: 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. .. note:: 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. .. note:: Todo lo referido ipara ambos mecanismos de arranque (servidor o interfaz) utiliza el :ref:`método tradicional de *debian* para la gestión de servicios `. Este método usa internamente el servicio de :ref:`systemd ` llamado *openvpn* y espera que los ficheros de configuración se incluyan dentro de :file:`/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 :file:`/etc/openvpn/server` y :file:`/etc/openvpn/client`. Preparación =========== Antes de pasar a ver cómo se configura :program:`openvpn` (o sea, ver cómo se escriben los ficheros *.conf*) es conveniente indicar cómo dejar preparada la máquina. Servidor -------- En el servidor debemos generar las claves del servidor. Para ello tenemos dos alternativas: a) 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 `_. b) 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. Usando easy-rsa """"""""""""""" .. warning:: :program:`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 :file:`/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 :file:`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 :file:`keys/cliente1.key` y :file:`keys/cliente1.crt` que deberán copiarse en el cliente. El segundo caso lo :ref:`trataremos bajo el siguiente epígrafe `. 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ó :ref:`bajo el epígrafe correspondiente ` y. obtenido. se tiene dentro de :file:`/etc/letsencrypt/live/www.example.net`: * La clave privada del servidor en :file:`privkey.pem`. * La clave pública del servidor en :file:`cert.pem`. * La clave pública de *Let's Encrypt* en :file:`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 :file:`ca.crt` que requiere :program:`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 :file:`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 :file:`allowed-cns` el nombre con el que se creó el certificado\ [#]_:: # echo "www.exanple.net" > /etc/openvpn/allowed-cns Además, debe parchearse una línea del script\ [#]_ :file:`verfy-cn` para que funcione con los certificados de *Let's Encrypt*:: if ($x509 =~ /( |^)CN=([^,]+)/) { .. _openvpn-auth-up: 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 .. _openvpn-auth-cli: Cliente ------- En el cliente, en cualquier, caso debemos copiar el certificado de la entidad certificadora y el fichero :file:`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\ [#]_ 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" .. rubric:: Notas al pie .. [#] En realidad, dependiendo de nuestras intenciones, deberemos instalar en el cliente algún paquete más. Se verá más adelante. .. [#] El nombre con el que se creo el certificado puede comprobarse del siguiente modo:: $ openssl x509 -in certs/server.crt -text -noout | grep Subject: Subject: CN = www.example.net El nombre es, pues, *www.example.net*. .. [#] Mejor que modificar el *script* original es hacer una copia dentro de un subdirectorio :file:`bin` y hacer el parcheo ahí:: # nkdir -p /etc/openvpn/bin # cp /usr/share/openvpn/verify-cn /etc/openvpn/bin .. [#] Si se ñade la directiva sin expresar fichero alguna, la identificación se hará de modo interactivo. También puede incluirse sólo el nombre de usuario en el fichero para que no se pida este, pero sí su contraseña.