VPN en nuestro VPS


Para este artículo usaremos Ubuntu 16.04 y comandos mayormente relacionados con la distribución básica Debian.

Instalación de OpenVPN:

Para instalar OpenVPN y Easy-RSA debemos ejecutar:

# apt update && apt upgrade 
# apt install easy-rsa openvpn -y

Por comando se actualizará el VPS, segundo instalamos un servidor VPN.

Configuramos el directorio CA:

OpenVPN es un TLS/SSL VPN. Esto quiere decir que utiliza certificados para encriptar el tráfico entre el servidor y clientes. Para generar certificados confiables, tendremos que configurar nuestra propia autoridad certificada simple (CA).

Para comenzar, podemos copiar el directorio de plantillas Easy-RSA dentro de nuestro directorio principal con el comando make-cadir:

$ make-cadir ~/openvpn-ca

Lo movemos dentro el directorio que creamos para comenzar a configurar el CA:

$ cd ~/openvpn-ca

Configurar las variables del CA:

Para configurar las variables que usará nuestro CA, es necesario editar el archivo de variables dentro del directorio. Abra ese archivo en editor de texto:

$ nano vars

Adentro, encontrará algunas variables que se pueden ajustar para determinar cómo sus certificados serán creados. Sólo es necesario ocuparse de algunas de estas. Hacia la parte inferior del archivo, encuentre los ajustes que definen los campos por defecto para nuevos certificados. Debe lucir como esto: 

. . .
export KEY_COUNTRY="US"
export KEY_PROVINCE="CA"
export KEY_CITY="SanFrancisco"
export KEY_ORG="Fort-Funston"
export KEY_EMAIL="me@myhost.mydomain"
export KEY_OU="MyOrganizationalUnit"
. . .

Edite los valores en rojo a cualquiera de su preferencia, pero no los deje vacíos:

. . .
export KEY_COUNTRY="PL"
export KEY_PROVINCE="Warsaw"
export KEY_CITY="Warsaw"
export KEY_ORG="ABC Hosting"
export KEY_EMAIL="admin@cba.pl"
export KEY_OU="Community"
. . .

Mientras estamos aquí, también editaremos el valor KEY_NAME, justo abajo de esta sección, que establece el campo asunto. Para hacerlo simple, lo llamaremos server en esta guía:

export KEY_NAME="server"

Cuando termine, guarde y cierre el archivo. Para cerrar y guardar en nano use: ctrl + o y presione enter para guardar el archivo actual y control + x para salir del editor.

Crear la autoridad certificada:

Ahora, podemos usar las variables que configuramos y las herramientas de easy-rsa para crear la autoridad certificada.

Asegúrese de estar en el directorio CA, luego localice el origen del archivo de variables que acaba de editar:
$ cd ~/openvpn-ca
$ source vars

Debería ver lo siguiente si se hizo correctamente:
Nota: si ejecuta ./clean-all, se estará haciendo un rm - rf en /home/sammy/openvpn-ca/keys
asegúrese de estar trabajando en un ambiente limpio escribiendo:

$ ./clean-all

Ahora, podemos construir el root del CA escribiendo:

$ ./build-ca

Esto iniciará el proceso de creación del root de la llave de autoridad certificada. Al haber escrito el archivo de variables, todos los valores deberían establecerse automáticamente. Solo presione ENTER a las sugerencias para confirmar las selecciones:

Ejemplo de salida:
Generating a 2048 bit RSA private key
..........................................................................................+++
...............................+++
writing new private key to 'ca.key'
-----
Pronto se le pedirá que ingrese la información que será incorporada dentro de su solicitud de certificado. Lo que está a punto de ingresar es lo que se llama nombre distinguido o un DN. Hay algunos campos pero puede dejar algunos sin completar. Para algunos campos habrá un valor inicial, Si ingresa '.', el campo será dejado sin completar.
-----
Country Name (2 letter code) [PL]:
State or Province Name (full name) [Warsaw]:
Locality Name (eg, city) [Warsaw]:
Organization Name (eg, company) [ABC Hosting]:
Organizational Unit Name (eg, section) [Community]:
Common Name (eg, your name or your server's hostname) [ABC Hosting CA]:
Name [server]:
Email Address [admin@cba.pl]:

Ahora tenemos un CA que puede ser usado para crear el resto de los archivos que necesitamos.

Crear el certificado del servidor, llave y archivos de encriptación

Siguiente, generaremos nuestro certificado del servidor y la llave par, así como archivos adicionales usados durante el proceso de encriptación.

Comience por generar el certificado del servidor OpenVPN y la llave par. Podemos hacer esto escribiendo:

Nota: si elige un nombre diferente a server aquí, deberá ajustar algunas de las instrucciones abajo. Por ejemplo, copiando el archivo generado al directorio /etc/openvpn , tendrá que sustituir los nombres correctos. Además tendrá que modificar el archivo /etc/openvpn/server.conf más tarde para apuntar a los archivos .ctr y .key correctos.

$ ./build-key-server server

Una vez más, las sugerencias tendrán valores por defecto basados en los argumentos que acabamos de mencionar (en server) y los contenidos del archivo de variables que creamos.

Siéntase libre de aceptar los valores por defecto presionando ENTER. No ingrese una contraseña complicada para esta configuración. Al final, tendrá que ingresarlo y dos preguntas para firmar y confirmar el certificado:

Ejemplo de salida:
. . .

Certificate is to be certified until May  1 17:51:16 2026 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

A continuación, generamos algunos otros items. Podemos generar unas llaves Diffie-Hellman fuertes para usarlas durante el cambio de llave al escribir:

$ ./build-dh

Esto tal vez tome algunos minutos para completarse.

Después, podemos generar una firma HMAC para fortalecer el TLS del servidor, capacidades de verificación e integridad:

$ openvpn --genkey --secret keys/ta.key

Genere un certificado de cliente y su llave par.

Luego podemos generar un certificado de cliente y una llave par. Sin embargo esto puede realizarse del lado del cliente y luego autorizarse por el servidor/CA por razones de seguridad. Para esta guía generaremos la llave registrada en el servidor por simplicidad. Generaremos una sola llave/certificado de cliente para esta guía, pero si usted tiene más de un cliente, puede repetir este proceso tantas veces como quiera. Pass es un valor único del código de cada cliente. 

Debido a que tal vez vuelva a este paso más adelante, volveremos a generar el archivo de variables. Usaremos clien1 como valor para nuestro primer certificado/llave par en esta guía.

Para producir credenciales sin una contraseña, ayudar en conexiones automatizadas, use el comando build-key de esta forma:
$ cd ~/openvpn-ca
$ source vars
$ ./build-key client1

Si en lugar de eso usted desea crear un conjunto de credenciales protegidas por contraseña, use el comando build-key-pass:

$ cd ~/openvpn-ca
$ source vars
$ ./build-key-pass client1

Una vez más, los valores por defecto deben ser establecidos presionando ENTER para continuar. Deje la contraseña de desafío vacía y asegúrese de completar las sugerencias que se solicitan para registrar y crear el certificado.

Configurar el servicio OpenVPN:

Ahora podemos comenzar a configurar el servicio OpenVPN, usando las credenciales y archivos que hemos generado.

Copie los archivos al directorio OpenVPN

Para comenzar, se deben copiar los archivos que necesitamos al directorio de configuración /etc/openvpn.

Podemos empezar con todos los archivos que acabamos de generar. Estos se situaron en el directorio ~/openvpn-ca/keys al ser creados. Es necesario mover el certificado CA y llave, el certificado del servidor y la llave, registro HMAC y el archivo Diffie-Hellman:

$ cd ~/openvpn-ca/keys
$ sudo cp ca.crt ca.key server.crt server.key ta.key dh2048.pem /etc/openvpn

Siguiente, es necesario copiar y descomprimir un ejemplo del archivo de configuración de OpenVPN dentro del directorio de configuración de forma que podamos usarlo como base para nuestra configuración.

# gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz | sudo tee /etc/openvpn/server.conf

Ajuste la configuración de OpenVPN

Ahora que nuestros archivos están en su lugar, podemos modificar el archivo de configuración del servidor.

$ sudo nano /etc/openvpn/server.conf

Configuración básica
Primero, encuentre la sección HMAC buscando la directiva tls-auth. Elimine el ";" para quitar el comentario de la línea tls-auth. Abajo de esto, agregue el parámetro key-direction en "0":

/etc/openvpn/server.conf:
tls-auth ta.key 0 # This file is secret
key-direction 0

Luego, encuentre la sección sobre los cifras criptográficas buscando entre las líneas cipher. El AES-128-CBC cipher ofrece un buen nivel de encriptación y es bien soportado. Elimine el ";" para quitar el comentario de la línea del chiper AES-128-CBC:

/etc/openvpn/server.conf:
cipher AES-128-CBC

Abajo, agregue una línea auth para seleccionar el mensaje de digestión algorítmica HMAC. Para éste, SHA256 es una buena opción:
/etc/openvpn/server.conf:
auth SHA256

Finalmente, ubique el usuario y ajustes de grupo, quite el ";" al comienzo para quitar el comentario de esas líneas:

/etc/openvpn/server.conf:
user nobody
group nogroup

(Opcional) haga los cambios de DNS para redirigir todo el tráfico a través del VPN
Los ajustes de arriba crearán la conexión VPN entre dos máquinas, pero no forzará a ninguna conexión para que use el túnel. Si desea usar la VPN para enrutar todo el tráfico, probablemente quiera hacer todos los ajustes de DNS a las computadoras de los clientes.

Puede hacer esto, quite el comentario de algunas directivas que configurarán el dispositivo del cliente para redirigir todo el tráfico web a través del VPN. 
Encuentre la sección redirect-gateway y remueva el ";" del comienzo del redirect-gateway para quitar el comentario.

/etc/openvpn/server.conf:
push "redirect-gateway def1 bypass-dhcp"

Justo abajo, ubique la sección dhcp-option. Una vez más, remueva el ";" del frente en ambas líneas para quitarles el comentario: 

/etc/openvpn/server.conf:
push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

Esto debería asistir a los clientes en la re-configuración de los ajustes DNS para usar el túnel VPS como puerta de enlace predeterminada.

(Opcional) Ajuste el puerto y protocolo
Por defecto, el servidor OpenVPN usa el puerto 1194 y el protocolo UDP para aceptar las conexiones de los clientes. Si usted necesita usar un puerto diferente debido a las restricciones de los ambientes de redes en las que tal vez estén sus clientes, puede cambiar la opción de puerto. Si usted no está hospedando el contenido de su servidor OpenVPN, el puerto 443 es una opción popular desde que es permitida a través de las reglas de los firewall.

/etc/openvpn/server.conf:
# Opcional!
port 443

Ahora si el protocolo está restringido para ese puerto también, cambie el protocolo de UDP a TCP:

/etc/openvpn/server.conf:
# Opcional!
proto tcp

Si no tiene la necesidad de usar un puerto diferente, lo mejor es dejar estos dos ajustes por defecto.

(Opcional) Apuntar a credenciales Non-Default 
Si usted selecciono un nombre diferente durante el comando ./build-key-server antes, modifique el certificado y las líneas key que ve para apuntar al archivo .crt y .key apropiado. Si uso el servidor por defecto, este debería estar colocado correctamente: 

/etc/openvpn/server.conf:
cert server.crt
key server.key

Cuando haya terminado, guarde y cierre el archivo. 

Ajustar la configuración de red del servidor

Seguidamente, es necesario ajustar algunos aspectos de red del servidor para que OpenVPN pueda desviar el tráfico correctamente.

Permitir redireccionamiento IP

Lo primero, es necesario permitirle al servidor el redireccionamiento del tráfico. Esto es muy esencial para la funcionalidad que necesitamos que provea nuestro VPN. 

Podemos ajustar esta configuración modificando el archivo /etc/sysctl.conf:

# sudo nano /etc/sysctl.conf

Adentro, busque la línea que establece net.ipv4.ip_forward. Remueva el caracter "#" del comienzo de la línea para eliminar el comentario de esa configuración:

/etc/sysctl.conf:
net.ipv4.ip_forward=1

Guarde y cierre el archivo cuando termine. Para leer el archivo y ajustar los valores para la sección actual, escriba:

# sudo sysctl -p

Luego es necesario instalar tablas IP y ajustar las reglas del firewall:

# apt install iptables

Para ajustar las reglas ejecute los siguientes comandos:
# iptables -A INPUT -i eth0 -m state --state NEW -p udp --dport 1194 -j ACCEPT
# iptables -A INPUT -i tun+ -j ACCEPT
# iptables -A FORWARD -i tun+ -j ACCEPT
# iptables -A FORWARD -i tun+ -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
# iptables -A FORWARD -i eth0 -o tun+ -m state --state RELATED,ESTABLISHED -j ACCEPT
# iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
# iptables -A OUTPUT -o tun+ -j ACCEPT

También, por favor ejecute lo siguiente para ajustar archivo systemd service para la OpenVPN:

$ sudo sed -i 's/LimitNPROC=10 /#LimitNPROC=10 /' /lib/systemd/system/openvpn@.service

Será necesario arrancar el servidor del OpenVPN especificando el nombre de nuestro archivo de configuración como una variable de instancia luego del nombre de archivo unitario systemd. El archivo de configuración para nuestro servidor tiene por nombre /etc/openvpn/server.conf, añadiremos @server al final de nuestro archivo unitario al llamarlo:

$ sudo systemctl start openvpn@server

Si todo salió bien, el resultado debería ser algo parecido a lo que ve a continuación:

● openvpn@server.service - OpenVPN connection to server
   Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2016-05-03 15:30:05 EDT; 47s ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
  Process: 5852 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 
2 --config /etc/openvpn/%i.conf --writepid /run/openvpn/%i.pid (code=exited, sta
 Main PID: 5856 (openvpn)
    Tasks: 1 (limit: 512)
   CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
           └─5856 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 
2 --config /etc/openvpn/server.conf --writepid /run/openvpn/server.pid

May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip addr add dev tun0 local 10.8.0.1 peer 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
May 03 15:30:05 openvpn2 ovpn-server[5856]: GID set to nogroup
May 03 15:30:05 openvpn2 ovpn-server[5856]: UID set to nobody
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link local (bound): [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: UDPv4 link remote: [undef]
May 03 15:30:05 openvpn2 ovpn-server[5856]: MULTI: multi_init called, r=256 v=256
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
May 03 15:30:05 openvpn2 ovpn-server[5856]: IFCONFIG POOL LIST
May 03 15:30:05 openvpn2 ovpn-server[5856]: Initialization Sequence Completed

Usted puede también comprobar que la interfaz tun0 del OpenVPN esté disponible escribiendo:

$ ip addr show tun0

Usted debería ver una interfaz configurada:

4: tun0: POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP mtu 1500 qdisc noqueue state UNKNOWN group default qlen 100
    link/none 
    inet 10.8.0.1 peer 10.8.0.2/32 scope global tun0
       valid_lft forever preferred_lft forever

Crear Infraestructura de Configuración del Cliente:

Es necesario configurar un sistema que nos permita crear los archivos de configuración fácilmente. Es decir, creando la estructura del directorio de configuración del cliente.

Para crear un directorio de estructura dentro del directorio raíz y así almacenar los archivos:

$ mkdir -p ~/client-configs/files

Debido a que los archivos de configuración del cliente tendrán las llaves del cliente incorporadas, debemos bloquear los permisos en nuestro directorio interno.

$ chmod 700 ~/client-configs/files

Creando una configuración base

Siguiente, copiemos un ejemplo de la configuración del cliente dentro de nuestro directorio para usarlo como nuestra configuración base.

$ cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ~/client-configs/base.conf

Abra este nuevo archivo en su editor de texto:

$ nano ~/client-configs/base.conf

Adentro, es necesario hacer algunos ajustes

Primero, ubique la directiva remota. Este apunta el cliente a nuestra dirección de servidor OpenVPN. Esto debería ser la dirección IP pública de su servidor OpenVPN. Si ha cambiado el puerto que el servidor OpenVPN, cambie a 1194 el puerto que seleccionó: 

~/client-configs/base.conf:
. . .
# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote server_IP_address 1194
. . .

Asegúrese que el protocolo coincida al valor que está usando en el servidor de configuración:

~/client-configs/base.conf:
proto udp

Siguiente, quite el comentario de las directivas de usuario y grupo eliminando el ";":

~/client-configs/base.conf:
# Downgrade privileges after initialization (non-Windows only)
user nobody
group nogroup

Encuentre las directivas que establecen el CA, cert y key. Comente estas directivas ya que estaremos añadiendo los certificados y llaves dentro del mismo archivo:

~/client-configs/base.conf:
# SSL/TLS parms.
# See the server config file for more
# description.  It's best to use
# a separate .crt/.key file pair
# for each client.  A single ca
# file can be used for all clients.
#ca ca.crt
#cert client.crt
#key client.key

Iguale la configuracion del cipher y auth que colocamos en el archivo /etc/openvpn/server.conf:

~/client-configs/base.conf:
cipher AES-128-CBC
auth SHA256

Siguiente, añada la directiva key-direction en algún lugar del archivo. Esto debe estar establecido a "1" para trabajar con el servidor:

~/client-configs/base.conf:
key-direction 1

Finalmente, añada algunas líneas de salida comentadas. Se quiere incluir estas con cada confif, pero se debe habilitar solo para clientes Linux que envían con un archivo /etc/openvpn/update-resolv-conf. Este script usa la utilidad resolvconf para actualizar la información de los DNS de clientes Linux.

~/client-configs/base.conf:
# script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf

Si su cliente está corriendo Linux y tiene un archivo /etc/openvpn/update-resolv-conf, debería quitar el comentario de las líneas del archivo configuración de cliente OpenVPN creado. Guarde el archivo cuando termine.

Creando un Script de Generación de Configuración

Siguiente, crearemos un script simple para compilar nuestra configuración base con el certificado relevante, la llave y archivos de cifrado. Éste colocará la configuración generada en el directorio ~/client-configs/files.

Cree y abra un archivo llamado make_config.sh dentro del directorio ~/client-configs: 

$ nano ~/client-configs/make_config.sh

Dentro, pegue el siguiente script:

~/client-configs/make_config.sh:
#!/bin/bash

# First argument: Client identifier

KEY_DIR=~/openvpn-ca/keys
OUTPUT_DIR=~/client-configs/files
BASE_CONFIG=~/client-configs/base.conf

cat ${BASE_CONFIG} \
    <(echo -e '') \
    ${KEY_DIR}/ca.crt \
    <(echo -e '\n') \
    ${KEY_DIR}/${1}.crt \
    <(echo -e '\n') \
    ${KEY_DIR}/${1}.key \
    <(echo -e '\n') \
    ${KEY_DIR}/ta.key \
    <(echo -e '') \
    > ${OUTPUT_DIR}/${1}.ovpn

Guarde y cierre el archivo cuando termine.

Marque el archivo como ejecutable escribiendo:

$ chmod 700 ~/client-configs/make_config.sh

Paso 11: Genere las Configuraciones del Cliente

Ahora, podemos fácilmente generar los archivos de configuración del cliente. Si siguió la guía, creo un certificado de cliente y una llave llamada client1.crt y client1.key respectivamente, al ejecutar el comando ./build-key client1 en el paso 6. Podemos generar un config para estos credenciales al moverlos dentro de nuestro directorio ~/client-configs y usando el script que hicimos:

$ cd ~/client-configs
$ ./make_config.sh client1

Si todo salió bien, deberíamos tener un archivo client1.ovpn en nuestro directorio ~/client-configs/files:

$ ls ~/client-configs/files

Salida:
client1.ovpn

Transfiriendo la Configuración a los Dispositivos del Cliente

Necesitamos transferir el archivo de configuración del cliente al dispositivo correspondiente. Por ejemplo, éste puede estar en su computadora local o en un dispositivo móvil. Mientras que las mejores aplicaciones usadas para realizar esta transferencia dependerán de su elección y sistema operativo del dispositivo, usted requiere la aplicación para usar SFTP (SSH file transfer protocol) O SCP (Secure Copy) en el backend. Éste transportará los archivos de autentificación del VPN de su cliente sobre una conexión encriptada.

Aquí está un ejemplo del comando SFTP usando nuestro client1.ovpn. Este comando puede ejecutarse desde su computadora local (OS X o Linux), ubica el archivo .ovpn en su directorio raíz:

$ scp sammy@openvpn_server_ip:client-configs/files/client1.ovpn ~/

A continuación varias herramientas para transferir archivos de forma segura desde el servidor a una computadora local:

WinSCP
FileZilla

El archivo OVPN puede ser usado si cliente es GUI para OpenVPN en Windows o Sistema operativo Mac. Linux tiene un administrador de red GUI que puede trabajar con archivos .ovpn.