Cómo proteger sus conexiones de red con OpenVPN

Nos dicen que vivimos en un mundo hipermóvil. No que yo sepa: rara vez salgo de mi oficina en casa. Pero, por supuesto, solo puedo disfrutar de las comodidades de mi oficina en casa porque todos los recursos del servidor que pueda necesitar están disponibles de forma remota.

Aparentemente no estoy solo. Casi todas las personas cuyo trabajo toca TI accederán a sus herramientas profesionales desde ubicaciones remotas de vez en cuando. Y dado que las redes públicas a través de las cuales accede a esas ubicaciones remotas son inseguras por naturaleza, querrá controlar cuidadosamente esas conexiones.

El cifrado de sitios web consiste en asegurarse de que los datos consumidos por sus clientes remotos se transfieran de manera confiable y sean invisibles para cualquiera que pueda estar al acecho en la red de conexión. Las VPN, por el contrario, se enfocan en asegurarse de que los datos consumidos por sus clientes remotos se transfieran de manera confiable y sean invisibles para cualquiera que pueda estar al acecho en la red de conexión. ¿Ves la diferencia? Yo tampoco.

De hecho, existen todo tipo de tecnologías dedicadas a asegurar la comunicación en red, y el principio de _defensa en profundidad_ nos enseña que nunca debes confiar en una sola. Entonces, aquí es donde aprenderá a agregar nuevas capas de protección para sus actividades remotas. Específicamente, el uso de cifrado para construir un túnel de red privada virtual (VPN) para permitir conexiones remotas invisibles y seguras.

Construyendo un túnel OpenVPN

Mi libro Linux en acción, del cual se extrajo este artículo, habla mucho sobre el cifrado. SSH y SCP pueden proteger los datos transferidos a través de conexiones remotas (capítulo 3), el cifrado de archivos puede proteger los datos en reposo (capítulo 8) y los certificados TLS / SSL pueden proteger los datos en tránsito entre sitios web y navegadores de clientes (capítulo 9). Pero a veces sus requisitos exigen protección en una gama más amplia de conexiones, porque a veces tiene que hacer diferentes tipos de trabajo.

F'rinstance? Algunos miembros de su equipo deben trabajar desde la carretera utilizando puntos de acceso WiFi públicos. Definitivamente no es inteligente asumir que los puntos de acceso WiFi aleatorios son seguros, pero su gente necesita una forma de conectarse con los recursos de la empresa. VPN al rescate.

Un túnel VPN diseñado adecuadamente proporciona una conexión directa entre clientes remotos y un servidor de una manera que oculta los datos a medida que se transfieren a través de una red insegura. ¿Y qué? Ya ha visto muchas herramientas que pueden hacerlo mediante cifrado. El valor real de una VPN es que una vez que ha abierto un túnel, es posible conectar redes remotas como si estuvieran todas juntas localmente. En cierto modo, estás eludiendo ese lugar de moda de la cafetería poco fiable.

Con una red tan extendida, los administradores pueden realizar su trabajo en sus servidores sin importar dónde se encuentren. Pero lo que es más importante, como puede ver en la figura, una empresa con recursos distribuidos en varias sucursales puede hacerlos visibles y accesibles para todos los equipos que los necesiten ... estén donde estén.

La mera existencia de un túnel por sí sola no garantiza la seguridad. Pero uno de varios estándares de cifrado puede incorporarse al diseño, mejorando mucho las cosas. Los túneles construidos con el paquete OpenVPN de código abierto utilizan el mismo cifrado TLS / SSL que ya ha visto en uso en otros lugares. OpenVPN no es la única opción disponible para tunelización, pero se encuentra entre las más conocidas, y se asume que es un poco más rápido y probablemente más seguro que el protocolo de túnel de capa 2 alternativo que usa cifrado IPsec.

Para que su equipo pueda conectarse de forma segura entre sí desde la carretera o entre varios campus, va a crear un servidor OpenVPN para permitir compartir ambas aplicaciones y acceder al entorno de red local del servidor. Para que funcione, debería ser suficiente iniciar dos VM o contenedores. Uno para desempeñar el papel de servidor / host y el otro de cliente.

La construcción de una VPN implica bastantes pasos, por lo que probablemente valga la pena tomarse unos minutos para pensar en el panorama general de cómo va a funcionar.

Configurar un servidor OpenVPN

Antes de comenzar, aquí hay un consejo útil. Si va a seguir este proceso por su cuenta, y le recomiendo encarecidamente que lo haga, probablemente se encontrará trabajando con varias ventanas de terminal abiertas en su escritorio, cada una de las cuales inició sesión en una máquina diferente. Créame: en algún momento ingresará un comando en la ventana incorrecta y arruinará totalmente su entorno.

Puede usar el comando de nombre de host para cambiar el nombre de la máquina que se muestra en la línea de comando a algo que le recuerde visualmente dónde se encuentra. Una vez hecho esto, deberá salir del servidor y volver a iniciar sesión para que la nueva configuración surta efecto.

[email protected]:~# hostname OpenVPN-Server [email protected]:~$ exit $ ssh [email protected] [email protected]:~# 

Seguir ese enfoque para asignar nombres apropiados a cada una de las máquinas con las que está trabajando debería ayudarlo a realizar un seguimiento de dónde se encuentra.

Prepare su servidor para OpenVPN

La instalación de OpenVPN en su servidor requiere dos paquetes: openvpn y, para administrar el proceso de generación de claves de cifrado, easy-rsa. Los usuarios de CentOS deben, si es necesario, instalar primero el repositorio de epel-release de la forma en que lo hizo en el capítulo 2. Para brindarle una manera fácil de probar el acceso a una aplicación de servidor, también puede instalar el servidor web Apache (apache2 para Ubuntu y httpd en CentOS).

Mientras configura su servidor, también puede hacerlo bien y activar un firewall que bloquea todos los puertos además del 22 (SSH) y 1194 (el puerto OpenVPN predeterminado). Este ejemplo ilustra la forma en que funcionará en ufw de Ubuntu, pero estoy seguro de que aún recuerda el firewalld de CentOS del capítulo 9.

ufw enable ufw allow 22 ufw allow 1194

To permit internal routing between network interfaces on the server you’ll need to uncomment a single line (net.ipv4.ip_forward=1) in the /etc/sysctl.conf file. This will allow remote clients to be redirected as needed once they’re connected. To load the new setting, run sysctl -p.

nano /etc/sysctl.conf sysctl -p

The server environment is now all set up, but there’s still a way to go before you’re ready to flip the switch.

Generate encryption keys

When you installed OpenVPN, a /etc/openvpn/ directory was automatically created, but there isn’t a whole lot in it just yet. However, both the openvpn and easy-rsa packages come with sample template files that you can use as a base for you configuration. To jump start the certification process, copy the easy-rsa template directory from /usr/share/ to /etc/openvpn/ and then change to the new easy-rsa/ directory.

cp -r /usr/share/easy-rsa/ /etc/openvpn cd /etc/openvpn/easy-rsa

The first file you’ll work with is called simply vars, and contains environment variables that easy-rsa will use when it generates its keys. You will want to edit the file to substitute your own values for the sample defaults that are already there. Here’s what my file would look like:

export KEY_COUNTRY=”CA” export KEY_PROVINCE=”ON” export KEY_CITY=”Toronto” export KEY_ORG=”Bootstrap IT” export KEY_EMAIL=”[email protected]” export KEY_OU=”IT”

Running the vars file will pass its values to the shell environment from where they’ll be incorporated into the contents of your new keys. When that’s done, the script will encourage you to run the clean-all script to delete any existing contents in the /etc/openvpn/easy-rsa/keys/ directory.

cd /etc/openvpn/easy-rsa/ . ./vars NOTE: If you run ./clean-all, I will be doing a rm -rf on /etc/openvpn/easy-rsa/keys

Naturally, your next step will be to run that clean-all script…followed by build-ca that will use the pkitool script to create your root certificate. You’ll be asked to confirm the identification settings provided by vars.

./clean-all ./build-ca Generating a 2048 bit RSA private key

Next, the build-key-server script, since it uses the same pkitool script along with the new root certificate, will ask you the same confirmation questions to generate a key pair. The keys will be given names based on the argument you pass — which, unless you’re running multiple VPNs on this machine, would normally be server, as in this example.

./build-key-server server […] Certificate is to be certified until Aug 15 23:52:34 2027 GMT (3650 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated

OpenVPN will use parameters generated using the Diffie-Hellman algorithm (by running build-dh) to negotiate authentication for new connections. The file that will be created here does not need to remain secret, but must have been generated using the build-dh script against the RSA keys that are currently active. If you create new RSA keys at some time in the future, you’ll also need to update the Diffie-Hellman file.

build-dh

Your server-side keys will now have been written to the /etc/openvpn/easy-rsa/keys/ directory, but OpenVPN doesn’t know that. By default OpenVPN will lookfor them in /etc/openvpn/, so copy them over.

cp /etc/openvpn/easy-rsa/keys/server* /etc/openvpn cp /etc/openvpn/easy-rsa/keys/dh2048.pem /etc/openvpn cp /etc/openvpn/easy-rsa/keys/ca.crt /etc/openvpn

Prepare client encryption keys

As you’ve already seen, TLS encryption uses matching key pairs, one installed on the server and the other on a remote client. That means you’re going to need client keys, and our old friend pkitool is just the thing to cook some up. This example, run while still in the /etc/openvpn/easy-rsa/ directory, passes client as an argument to generate files called client.crt and client.key.

./pkitool client

The two client files, along with the original ca.crt file that’s still in the keys/ directory, will now have to be securely transferred to your client. Because of their ownership and permissions, this might be a bit complicated. The simplest approach is to manually copy the contents of the source file (and nothing but those contents) in a terminal running on your PC’s desktop (by highlighting the text, right-clicking over it, and selecting copy from the menu) and then pasting it into a new file of the same name you create in a second terminal logged into your client.

But anyone can cut and paste. Instead, think like an admin — especially since you won’t always have access to a GUI where cutting and pasting is possible. Instead, copy the files to your user’s home directory (so a remote scp operation can access them) and then use chown to change the ownership of the files from root to your regular, non-root user so that remote scp action can work. Make sure your files are all settled and comfy for now…you’ll move them over to the client a bit later.

cp /etc/openvpn/easy-rsa/keys/client.key /home/ubuntu/ cp /etc/openvpn/easy-rsa/keys/ca.crt /home/ubuntu/ cp /etc/openvpn/easy-rsa/keys/client.crt /home/ubuntu/ chown ubuntu:ubuntu /home/ubuntu/client.key chown ubuntu:ubuntu /home/ubuntu/client.crt chown ubuntu:ubuntu /home/ubuntu/ca.crt

With a full set of encryption keys ready for action, you’ll need to tell your server how you want to build your VPN. That’s done using the server.conf file.

Configure server.conf file

How are you supposed to know what the server.conf file should look like? Well, remember the easy-rsa directory template you copied over from /usr/share/? Well there are more goodies where that came from. The OpenVPN installation left a compressed template configuration file which you can copy over to /etc/openvpn/.

I’ll use the fact that the template is compressed to introduce you to a useful tool: zcat. You’re already know about printing a file’s text contents to the screen with cat, but what if the file is compressed using gzip? Of course, you could always decompress the file and cat will then be happy to print it, but that’s one or two steps too many. Instead, as you’ve probably already guessed, you can use zcat to load the decompressed text into memory all in one step. In our case, rather than print it to the screen, you’ll redirect the text to a new file called server.conf.

zcat \ /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf cd /etc/openvpn

Leaving out the extensive and helpful documentation that comes with the file, here’s how it might look once you’re done editing. Note that a semicolon (;) tells OpenVPN _not_ to read and execute the line that follows.

port 1194 # TCP or UDP server? proto tcp ;proto udp ;dev tap dev tun ca ca.crt cert server.crt key server.key # This file should be kept secret dh dh2048.pem server 10.8.0.0 255.255.255.0 ifconfig-pool-persist ipp.txt push “route 10.0.3.0 255.255.255.0” keepalive 10 120 comp-lzo port-share localhost 80 user nobody group nogroup persist-key persist-tun status openvpn-status.log log openvpn.log ;log-append openvpn.log verb 3 

Let’s work through some of those one at a time.

  • By default, OpenVPN works over port 1194. You can change that — perhaps to further obscure your activities, or avoid conflicts with other active tunnels. But, because it will require the least coordination between clients, 1194 is normally your best choice.
  • OpenVPN can use either the Transmission Control Protocol (TCP) or User Datagram Protocol (UDP) for data transmissions. TCP might be a little bit slower, but it’s more reliable and more likely to get along with applications running at either end of the tunnel.
  • You specify dev tun when you want to create a simpler and more efficient IP tunnel that transfers data content and nothing much else. If, on the other hand, you’ll need to connect multiple network interfaces (and the networks they represent) by creating an _ethernet bridge_, then you’ll have to select dev tap. If you haven’t a clue what all that means, go with tun.
  • The next four lines pass OpenVPN the names of the three server authentication files and the dh2048 parameters file you created earlier.
  • The server line sets the subnet range and netmask that will be used for assigning IP addresses to clients when they log in.
  • The optional push “route 10.0.3.0 255.255.255.0” setting will allow remote clients to access private subnets “behind” the server. Making this work will also require network configuration on to server itself to ensure that the private subnet is aware of the OpenVPN subnet (10.8.0.0).
  • port-share localhost 80 allows client traffic coming in on port 1194 to be rerouted to a local web server listening on port 80. This will be useful in our case since we’re going to use a web server to test our VPN. This will only work when proto is set to tcp.
  • The user nobody and group nogroup lines should be enabled by removing the semicolons. Forcing remote clients to work as nobody and nogroup ensures that their sessions on the server will be unprivileged.
  • log sets current log entries to overwrite old entries every time OpenVPN starts up, while log-append appends new entries to the existing log file. The openvpn.log itself will be written to the /etc/openvpn/ directory.

In addition, it is also very common to add client-to-client to the config file so multiple clients will be able to see each other in addition to the OpenVPN server.

Once you’re satisfied with your configuration, you’re ready to fire up the OpenVPN server.

systemctl start openvpn

Running ip addr to list your server’s network interfaces should now include a reference to a new interface called tun0. This will have been created by OpenVPN for the use of incoming clients.

ip addr […] 4: tun0:  mtu 1500 qdisc […] link/none inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0 valid_lft forever preferred_lft forever

It is _possible_ that you’ll need to reboot the server before everything will fully function. Next stop: the client computer.

Configuring an OpenVPN client

Traditionally, tunnels are built with at least two ends (otherwise we prefer calling them caves). Having OpenVPN properly configured on the server directs traffic into and out of the tunnel at that end. But you’ll need some kind of software running on the client side as well.

In this section I’m going to focus on manually configuring a Linux computer of one sort or another to act as an OpenVPN client. But that’s not the only way you might want to consume the service. OpenVPN itself maintains client apps that can be installed and used on Windows or Mac desktop/laptops, or Android and iOS smart phones and tablets. See the //openvpn.net web site for details.

The OpenVPN package will need to be installed on the client machine, as it was on the server — although there’s no need for easy-rsa over here, because the keys you’ll use already exist. You will need to copy the client.conf template file over to the /etc/openvpn/ directory that the installation just created. This time, for some reason, the file won’t be compressed, so a regular cp will do the job just fine.

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

Most of the settings in your client.conf file will be fairly obvious: they’ll need to match the values used by the server. As you can see from the sample file below, one that’s unique is remote 192.168.1.23 1194 — which points the client to the server’s IP address. Again, make sure you use your server’s actual address. You should also force your client to verify the authenticity of the server certificate to prevent a possible man-in-the-middle attack. One way to do this is by adding the remote-cert-tls server line.

client ;dev tap dev tun proto tcp remote 192.168.1.23 1194 resolv-retry infinite nobind user nobody group nogroup persist-key persist-tun ca ca.crt cert client.crt key client.key comp-lzo verb 3 remote-cert-tls server 

Now you can move to the /etc/openvpn/ directory and pull those certification keys from the server. You will obviously substitute your server’s actual IP address or domain name for the one in the example.

cd /etc/openvpn scp [email protected]:/home/ubuntu/ca.crt . scp [email protected]:/home/ubuntu/client.crt . scp [email protected].168.1.23:/home/ubuntu/client.key .

Nothing exciting is likely to happen until you start up OpenVPN on the client. Because you’ll need to pass a couple of arguments, you’ll pull the trigger from the command line. — tls-client tells OpenVPN that you’ll be acting as a client and connecting via TLS encryption while — config points to your config file.

openvpn — tls-client — config /etc/openvpn/client.conf

Read the command output carefully to make sure you’re connected properly. If something does go wrong the first time, it’s probably either due to a setting mismatch between the server and client configuration files or perhaps a network connectivity/firewall issue. Here are some troubleshooting steps:

  • Carefully read the output from the OpenVPN operation on the client — it will often contain valuable hints to exactly what it couldn’t do and why.
  • Check for error-related messages in the openvpn.log and openvpn-status.log files in the /etc/openvpn/ directory on the server.
  • Check OpenVPN-related and timely messages in the system logs on both the server and client (journalctl -ce will print out a screenfull of the most recent entries).
  • Confirm that you’ve got an active network connection between the server and client (see chapter 14 for details).

This article is excerpted from my Manning “Linux in Action” book. There’s lots more fun where this came from, including a hybrid course called Linux in Motion that’s made up of more than two hours of video and around 40% of the text of Linux in Action. Who knows…you might also enjoy my Learn Amazon Web Services in a Month of Lunches.