Translate

domingo, junio 14, 2015

Openvpn - Instalar un servidor OpenVPN en Fedora Linux 20-22 y configurar clientes

OpenVPN

Para mas informacion, ver https://community.openvpn.net/.

Security note

    The configuration snippets here will produce a working server and client config. But take certain precautions if you want to use this approach in a production environment. Important things to avoid are:
  • Do not store the easy-rsa CA files on the OpenVPN server.
    • The server only needs ca.crt, server.crt, server.key and dh*.pem files
    • The client only needs ca.crt, client.crt and client.key
  • Avoid creating the encryption keys in a virtualized environment, as the random entropy may not be random enough to guarantee safe keys.

Working with systemd

With the transition to systemd, OpenVPN no longer has a single monolithic init script, where every connection with a configuration file in /etc/openvpn/ is started automatically. Instead, individual connections can be started and stopped with systemctl.
For example, to start a connection, run systemctl start openvpn@foo.service, where the connection is defined in /etc/openvpn/foo.conf.

Setting up an OpenVPN server

  1. yum install openvpn easy-rsa
  2. Copy /usr/share/easy-rsa/2.0 somewhere (like root's home directory with cp -ai /usr/share/easy-rsa/2.0 ~/easy-rsa).
  3. cd ~/easy-rsa
  4. Edit vars appropriately.
  5. . vars
  6. ./clean-all
  7. Before continuing, make sure the system time is correct. Preferably, set up NTP .
  8. ./build-ca
  9. ./build-key-server $( hostname | cut -d. -f1 )
  10. ./build-dh
  11. mkdir /etc/openvpn/keys
  12. cp -ai keys/$( hostname | cut -d. -f1 ).{crt,key} keys/ca.crt keys/dh*.pem /etc/openvpn/keys/
  13. cp -ai /usr/share/doc/openvpn*/sample/sample-config-files/roadwarrior-server.conf /etc/openvpn/server.conf
  14. Edit /etc/openvpn/server.conf appropriately to set your configuration and key paths, which are found in /etc/openvpn/keys/.
  15. Fix selinux context of files: restorecon -Rv /etc/openvpn
  16. ln -s /lib/systemd/system/openvpn\@.service /etc/systemd/system/multi-user.target.wants/openvpn\@server.service (Note that 'server' corresponds with the configuration name in /etc/openvpn/ such as server.conf; that is, 'server' corresponds to whatever name your configuration file has)
  17. systemctl -f enable openvpn@server.service
  18. systemctl start openvpn@server.service
  19. Verify that firewall rules allow traffic in from tun+, out from the LAN to tun+, and in from the outside on UDP port 1194. Para comprobar que el puerto 1194 esta a la escucha: netstat -uapn | grep 1194

Loa siguientes puntos son para habilitar openvpn en el firewall, si queremos saltarlo para probar que funciona podemos parar el firewall con el siguiente comando: systemctl stop firewalld
The following should work (assuming an outside interface is eth1 and an inside interface is eth0, no usar en Fedora 20, los comandos que me han funcionado son los de firewalld:
iptables -A INPUT -i eth1 -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A FORWARD -i eth0 -o tun+ -j ACCEPT
iptables -A FORWARD -i eth1 -o tun+ -m state --state ESTABLISHED,RELATED -j ACCEPT
These commands should work for firewalld, estos comandos me han funcionado correctamente en fedora 20:
firewall-cmd --add-service=openvpn  (si agregamos --permanent queda fijo en arranque)
firewall-cmd --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
Or for genfw (my firewall-generation script, not currently available in Fedora), this in /etc/sysconfig/genfw/rules:
append INPUT -i eth1 -p udp --dport 1194 -j ACCEPT
append INPUT -i tun+ -j ACCEPT
append FORWARD -i tun+ -j ACCEPT
append FORWARD -i eth0 -o tun+ -j ACCEPT
append FORWARD -i eth1 -o tun+ -j established
Or for system-config-firewall, you can add these custom rules:
-A INPUT -i eth1 -p udp --dport 1194 -j ACCEPT
-A INPUT -i tun+ -j ACCEPT
-A FORWARD -i tun+ -j ACCEPT
-A FORWARD -i eth0 -o tun+ -j ACCEPT
-A FORWARD -i eth1 -o tun+ -m state --state ESTABLISHED,RELATED -j ACCEPT
Create a file iptables-rules in /etc/sysconfig and add the above contents, then in system-config-firewall, choose the "Custom Rules" choice, click "Add", choose IPV4 for the protocol type, and filter for the firewall table. Then select /etc/sysconfig/iptables-rules for the File: choice. Then Apply the changes.

Setting up a Linux OpenVPN client

You need to generate new keys (or use existing other client/username keys) for the new client/username
On the server:
  1. cd easy-rsa
  2. . vars
  3. ./build-key username
On the client:
  • In the following, replace MyClient with a descriptive vpn connection name.
  1. Copy username.key, username.crt and ca.crt from server to /etc/openvpn/MyClient/.
  2. cp -ai /usr/share/doc/openvpn*/sample-config-files/client.conf /etc/openvpn/MyClient.conf
  3. Edit /etc/openvpn/MyClient.conf appropriately to set your configuration (just like server configuration, port, compression,..) and key paths.
  4. ln -s /lib/systemd/system/openvpn@.service /etc/systemd/system/openvpn@MyClient.service
  5. systemctl enable openvpn@MyClient.service
  6. systemctl start openvpn@MyClient.service
check /var/log/messages if things didn't work as expected
Alternatively, on the client, after copying the keys onto the client machine, you can use NetworkManager to add a vpn connection. Make sure you have the NetworkManager-openvpn package installed. Then just add a new VPN connection.
Should also test automatic starting at boot up, with password protected key files and maybe even --auth-user-pass. OpenVPN supports systemd's password passing if build with --enable-systemd via ./configure

Setting up a Windows OpenVPN client

On the server:
  1. cd easy-rsa
  2. . vars
  3. ./build-key username
On the client:
  1. Install the the OpenVPN Windows client.
  2. Copy username.crt, username.key, and ca.crt to C:\Program Files\OpenVPN\config\ on the client.
  3. Drop roadwarrior-client.conf into C:\Program Files\OpenVPN\config\ as whatever.ovpn and edit appropriately.
  4. Either use the GUI to start the connection, start the OpenVPN service manually, or set the OpenVPN service to start automatically.
Ideally the client should do some verification on the server key with tls-remote in the whatever.ovpn configuration file.

Using OpenVPN with Pacemaker

When using OpenVPN with Pacemaker and systemd a command like pcs resource create openvpn-foo systemd:openvpn@foo op monitor interval=60s --force is needed to create a new resource for OpenVPN, where the connection is defined in /etc/openvpn/foo.conf. Passing --force is required, otherwise the error message "Error: Unable to create resource 'systemd:openvpn@foo', it is not installed on this system (use --force to override)" is thrown even the OpenVPN configuration file exists.

miércoles, junio 10, 2015

Impresiones de uso sobre SystemD



Esquema de SystemD

Hace unos meses ya, hice el cambio de Debian (rama "testing") a Arch Linux. Uno de las distintas cosas a las que tuve que adaptarme en esa migración fue pasar de un sistema que por ese entonces aún utilizaba SysVinit como gestor de servicios a uno que utiliza SystemD. Para mí este era un punto importante, debido a las conocidas quejas que ha habido (y sigue habiendo) sobre SystemD. Hoy he querido compartir con vosotros mis impresiones sobre este sistema.

La experiencia de usuario de un gestor de servicios no es algo que se constate de la misma forma que, por ejemplo, la de un entorno de escritorio o una aplicación en concreto. El gestor de servicios es un elemento que, bajo funcionamiento normal, no se interpone en el funcionamiento del sistema: una vez que el sistema arranca el núcleo y este le pasa el relevo al proceso init, si no hay problemas (y no debería haberlos si todo está configurado como debe), se iniciará la entrada de usuario (ya sea login en una consola o el gestor gráfico) y, a partir de allí, las veces que será necesaria una interacción del usuario con el gestor de servicios serán muy contadas (básicamente, cuando se tiene que configurar un nuevo servicio y esto solo si el gestor de paquetes no lo hace ya por sí mismo). Así que no estamos hablando aquí de un componente que el usuario utilice constantemente, aunque el sistema sí.

Hay un par de cosas que se suelen de decir de SystemD que un usuario curioso notará enseguida cuando uno viene de SysVinit es que SystemD toma el control de una serie de elementos que su antecesor no, pero el que posiblemente más salte a la vista en un principio sea el hecho de que SystemD controle el registro del sistema. Para revisar el registro en un sistema que opera con SystemD, tendremos que conocer una herramienta nueva, journalctl, debido a que los registros se guardan en un formato binario, por lo que tenemos que abandonar el hábito de hacer pasar los registros por el paginador (less, generalmente) y usar grep para buscar la línea que nos interese.

Otra de las grandes diferencias está, evidentemente, en la gestión de los servicios. Este es un aspecto que será más o menos visible dependiendo de dos factores, según mi punto de vista: si la distribución que usamos gestiona la configuración de servicios de forma automatizada (mediante scripts de instalación ejecutados por el gestor de paquetes) y si somos usuarios que toqueteamos más o menos el sistema (si no lo hacemos y nos contentamos con lo que nos viene preconfigurado, ni nos interesará qué gestor de servicios tengamos). En mi caso estamos hablando de Arch Linux, una distribución que no configura automáticamente ningún servicio instalado por paquetes, por lo cual el usuario está obligado a tomar una decisión sobre si quiere ejecutar el servicio, cosa que me ha expuesto a SystemD bastante más que utilizando Fedora, por ejemplo.

Un aspecto interesante de SystemD es los cuatro estados que puede tener un servicio: habilitado/deshabilitado y iniciado/detenido. SysVinit solo compartía con SystemD la última pareja: un servicio estaba en ejecución o no y uno podía detenerlo y reiniciarlo a través de la línea de comandos (existía service o, simplemente, se podía invocar el script del servicio con los argumentos que uno quería). Si bien Fedora soportaba nativamente una interfaz algo más abstracta que simulaba la habilitación y deshabilitación de servicios (chkconfig) y Debian tiene update-rc.d(aunque tenga los días contados), la verdad es que SysVinit no conocía estos conceptos; es decir, SysVinit siempre ejecutaría todos los servicios que se encontraran bajo /etc/rc*.d y, por tanto, la única forma de evitar ejecutar un servicio era borrar el symlink que apuntaba al script alojado en /etc/init.d. SystemD, en cambio, implementa la idea de poder desactivar un servicio de forma nativa con una simple invocación a systemctl, sin implicar en la práctica una desinstalación del servicio (es que borrar el symlink lo que conllevaba era, justamente, una desinstalación por medio de cortar el acceso al script).

No soy de los que escriban servicios, así que no puedo opinar realmente sobre cuán cómodo es el nuevo formato que utiliza SystemD para definirlos (es un formato que recuerda bastante a los archivos INI de Windows; daros una vuelta por /usr/lib/systemd/system y /usr/lib/systemd/user). Lo que sí es evidente es que, habiendo dejado de lado el rudimentario sistema anterior basado enteramente en scripts de shell, se gana algo de seguridad y de eficiencia. El hecho de no tener que estar ejecutando scripts con privilegios de administrador es un riesgo: un script puede contener código arbitrario y todo lo que hacía SysVinit era, simplemente, ejecutarlos sin controlarlos. Por otro lado, es evidente que los servicios no pueden iniciarse en un orden aleatorio: por ejemplo, KDM siempre requerirá que el servidor X esté en marcha antes. SysVinit se las arreglaba con un complejo sistema de directorios y convenciones de nombres de archivo para determinar qué se tenía que ejecutar cuándo, cosa que solo pueden determinar los desarrolladores en el nivel de la distribución para evitar nombres duplicados o inconsistencias. En cambio, estos nuevos archivos de "unidades" (units, que pueden servicios u "objetivos", targets) de SystemD permiten especificar las dependencias del servicio en el propio archivo, por lo que se simplifica enormemente la jerarquía de directorios y, además, se evita la ejecución de código arbitrario directamente desde init. Obviamente el ejecutable al que se hace referencia en el archivo del servicio puede ser dañino (intencionadamente o no), pero el problema queda, entonces, aislado solo en el ejecutable que implementa el servicio; en cambio, con el sistema anterior, el problema debía buscarse en dos ejecutables (el script y el servicio en sí mismo).

Una de las críticas más extendidas contra SystemD es que viola la filosofía UNIX de "una sola herramienta, una sola funcionalidad (y hacerla bien)". Por ejemplo, una de las quejas concretas más extendidas es que SystemD controla los cronjobs en /etc/cron* que antiguamente controlaba(ana)cron independientemente del init utilizado. Aquí creo que hay que poner un poco de perspectiva, porque no es lo mismo SystemD que la interfaz a la que se accede para manipular su funcionamiento, es decir, el uso de systemctl y archivos de "unidades". En realidad, SystemD no es muy distinto a SysVinit, salvo por el hecho de que, en su momento, había cosas que, aún pudiendo hacerse, había ciertas cosas que los desarrolladores preferían mantener como separadas del gestor de servicios porque no consideraban que fueran parte del procedimiento de arranque del sistema. El problema es que las distribuciones fueron convergiendo, por ejemplo, en iniciar (ana)cron como un servicio, de manera que hoy se consideran parte del proceso de arrancar un sistema Linux más o menos "estándar". Y como son parte del proceso de arranque, los desarrolladores han querido implementar estos componentes como parte de SystemD, aunque en realidad están implementados como servicios que SystemD, simplemente, arranca cuando haga falta. Da igual que un servicio se configure para ejecutarse cada 24 horas, si para ello hace falta encender el contador al arrancar el sistema, entonces es un servicio que, aunque latente, requiere ser iniciado por init. Es por ello que el truco antiguo con SysVinit de delegar en (ana)cron la ejecución de los cronjobs no era más que una ilusión de abstracción.

Finalmente, creo que es imposible hablar de SystemD sin hablar de cgroups, la interfaz del núcleo Linux que permite controlar y gestionar una serie de propiedades de los procesos para evitar, por ejemplo, la colisión de números PID y restringir cuántos recursos pueden utilizar cada uno. El problema es que cgroups es una característica exclusiva del núcleo Linux que SystemD utiliza para brindar mayor seguridad y eficiencia, por lo que SystemD no podrá utilizarse jamás en BSD o GNU Hurd (salvo que se implemente cgroups en esos núcleos). Esta es una de las razones que llevó a Debian a dudar tanto tiempo en si convenía migrar o no de sistema de init. La cuestión es que, en parte, era inevitable que esto sucediera: los SysVinit utilizados en distribuciones Linux ya no eran totalmente compatibles con BSD y SystemD, en parte, intenta recoger usos y formas que se han ido "acumulando" en el arranque de un sistema Linux convencional. Es un proyecto creado para Linux: no podemos culparlo por ello y menos cuando la razón es para usar una muy buena característica propia de este núcleo en particular. Aun cuando la interoperabilidad siempre es bienvenida, dejar de aprovechar en un proyecto tan vital las ventajas de la plataforma subyacente solo para garantizar un uso potencial de una plataforma totalmente diferente no tiene mucho sentido.

En mi opinión y experiencia de uso, SystemD es un buen avance. Por supuesto, no se le puede negar la razón a Linus Torvalds cuando acusó a los desarrolladores de SystemD de invasivos por querer introducir modificaciones en el núcleo solo en beneficio de su proyecto. Es cierto que Lennart Poettering es un personaje complicado, muy vinculado a Red Hat, que ya protagonizó un momento polémico de la historia de Linux cuando creó Pulseaudio como reemplazo de ALSA. Es un personaje con muy buena visión de futuro, que crea muy buenos proyectos, pero muy arrogante en las formas de convencer a la gente de que su solución es interesante (él la considera la mejor posible, con la exclusión que eso conlleva). Sin embargo, como ya ocurrió con Pulseaudio, creo que SystemD está aquí para quedarse. Y los problemas que pueda tener, comparado con SysVinit, hay que ponerlos en el contexto de que SystemD es un gestor de servicios que no tiene más de 4 años y que en ese tiempo ha reemplazado en una buena cantidad de distribuciones a un veterano heredado de los sistemas UNIX de los años 80.