OpenVPN: Instalar y configurar un servidor VPN

Una red VPN (Virtual Private Network), es una red cifrada segura. Esto es muy útil a la hora de crear conexiones entre redes que no se ven entre sí, de una manera segura. Es decir, si por ejemplo se quiere tener visibilidad entre la red de casa y la red de trabajo, se puede crear un túnel VPN conectando ambas. De este modo (habilitando las rutas correspondientes) se podría acceder de una red a otra sin problemas. Otro caso en el que se puede utilizar, es para acceder a Internet de una manera segura, por ejemplo, si te conectas a la red wifi de un bar o de un establecimiento del estilo, se puede establecer un túnel VPN contra un servidor de confianza para que todo el tráfico esté cifrado y de este modo, nadie pueda ver los datos.
La herramienta mas utilizada para este tipo de cosas, es OpenVPN. Es una herramienta libre y totalmente gratuita.

Instalación servidor

Instalar openvpn y easy-rsa

apt -y install openvpn easy-rsa iptables-persistent

Crear el archivo de configuración del servidor vpn

gunzip -c /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz > /etc/openvpn/server.conf

Configuración

Editar el archivo de configuración

vim /etc/openvpn/server.conf

Cambiar la clave DH a 4096

dh dh4096.pem

Si se quiere redirigir todo el tráfico a través de la VPN, descomentar la siguiente línea (opcional)

push "redirect-gateway def1 bypass-dhcp"

Si se quiere forzar el cambio de DNSs descomentar las siguientes líneas (opcional):

push "dhcp-option DNS 208.67.222.222"
push "dhcp-option DNS 208.67.220.220"

También se le puede indicar el nombre con el que levante la interfaz

dev ethvpn

Un ejemplo de un archivo de configuración de OpenVPN sería:

#Tipo de interfaz
dev-type tap

#Nombre de la interfaz
dev ethvpn

#Modo servidor
mode server

#Protocolo que se usa
proto udp

#Puerto que se utiliza. 
port 1194

#Comprimir los paquetes
comp-lzo

#El keepalive hace que cada 10 segundos mande un ping y si no llega lo intente despues de 120.
keepalive 10 120

#Configuración IP para la interfaz VPN
ifconfig 192.168.10.1 255.255.255.0

#Servidor tls y clave DH
tls-server
dh dh4096.pem
tls-auth /etc/openvpn/easy-rsa/keys/ta.key 0

#Comentar esta linea para que no pueda haber nombres duplicados
;duplicate-cn

#Comentar para que los clientes no puedan verse entre sí
;client-to-client

#Configuraciones de los clientes (opcional)
client-config-dir /etc/openvpn/client
ccd-exclusive

#Para que se comprueben los certificados revocados. Esto puede dar error de permisos.
crl-verify /etc/openvpn/crl.pem

#Para los logs
status /var/log/openvpn-status.log
log-append /var/log/openvpn.log

#Configuracion Cipher recomendada
auth SHA512
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA

#Hacer persistentes
persist-key
persist-tun

#Para que no corra como root una vez iniciado
user nobody
group nogroup

#Especificar los certificados del servidor
ca ca.crt
cert server.crt
key server.key

En el caso de que se quiera dar una IP en concreto a cada cliente, habría que crear una carpeta en /etc/openvpn/ y meter la configuración de cada cliente en ficheros.

mkdir /etc/openvpn/client

Y hay que indicar en el archivo de configuración del servidor donde están las configuraciones de los clientes, y que van a ser exclusivas.

client-config-dir /etc/openvpn/client
ccd-exclusive

Certificados servidor

Copiar la carpeta de easy-rsa a openvpn

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

Crear la carpeta de keys

mkdir /etc/openvpn/easy-rsa/keys

Editar los parámetros para cuando se creen los certificados

vim /etc/openvpn/easy-rsa/vars
export KEY_COUNTRY="ES"
export KEY_PROVINCE="AL" 
export KEY_CITY="Vitoria" 
export KEY_ORG="ichasco" 
export KEY_EMAIL="info@ichasco.com" 
export KEY_OU="ichasco.com"

Cambiar el nombre por defecto del servidor

export KEY_NAME="server"

Crear el enlace simbolico a la versión de openssl que se quiera

ln -s /etc/openvpn/easy-rsa/openssl-1.0.0.cnf /etc/openvpn/easy-rsa/openssl.cnf

Ahora hay que empezar a crear los certificados para el servidor

cd /etc/openvpn/easy-rsa

Cambiar el entorno

source ./vars

Limpiar todos los certificados existentes por si los hubiese

./clean-all

Crear el CA

./build-ca

Crear los certificados para el servidor openvpn. En este caso se llamarán server.*

./build-key-server server

Copiar los certificados a la carpeta openvpn

cp /etc/openvpn/easy-rsa/keys/{server.crt,server.key,ca.crt} /etc/openvpn

Crear el archivo de establecimiento de claves Diffie-Helman (esto tardará un rato)

openssl dhparam -out /etc/openvpn/dh4096.pem 4096

Generar la key HMAC

openvpn --genkey --secret /etc/openvpn/easy-rsa/keys/hmac.key

Para utilizar el clr verify, si se tiene en la carpeta keys de easy-rsa, dará problemas de permisos. Por lo tanto lo mejor es pasarla a la carpeta principal de openvpn y crear un enlace simbólico a la carpeta de keys.
Nota: Para que esté este fichero, hay que haber creado previamente la clave de un cliente y borrarlo.

Crear un usuario para forzar el clr

./build-key client

Eliminar el usuario

./revoke-full client
mv /etc/openvpn/easy-rsa/keys/crl.pem /etc/openvpn/
ln -s /etc/openvpn/crl.pem /etc/openvpn/easy-rsa/keys/

Para ver el estado de los certificados emitidos, revisar el siguiente archivo:

less /etc/openvpn/easy-rsa/keys/index.txt

Habilitar el servicio OpenVPN e iniciarlo

systemctl enable openvpn.service
systemctl start openvpn.service

Routing

Habilitar el enrutado en el servidor:

echo 1 > /proc/sys/net/ipv4/ip_forward

Para que esto sea permanente, hay que editar el archivo sysctl.conf

vim /etc/sysctl.conf

Y descomentar:

net.ipv4.ip_forward=1

Iptables

Para que el servidor permita el tráfico, hay que añadir ciertas reglas en iptables

iptables -A INPUT -i eth0 -p udp -m state --state NEW -m udp --dport 1194 -j ACCEPT
iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o eth0 -j MASQUERADE
iptables -A INPUT -i ethvpn -j ACCEPT
iptables -A OUTPUT -o ethvpn -j ACCEPT

Y una vez esto, guardar las reglas para que sean efectivas cuando se reinicie

iptables-save > /etc/iptables.rules

Cliente

Crear el archivo de configuración

cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/client/cliente.conf

Editar el archivo de configuración y configurar la IP del servidor VPN

vim /etc/openvpn/client/cliente.conf
remote <IP del servidor VPN> 1194

Para crear los certificados para el cliente VPN, hay que realizar los mismos pasos que para el servidor pero ahora lo llamaremos client (este nombre puede cambiar dependiendo del nombre que se le quiera dar)

cd /etc/openvpn/easy-rsa
source ./vars
./build-key cliente

Para añadir los certificados, hay 2 formas. Una es como en el servidor, llamarlos directamente y la otra es hacer un inline de estos en el propio archivo.

Crear variable

client=cliente
echo '<ca>' >> /etc/openvpn/client/$client.conf
cat /etc/openvpn/easy-rsa/keys/ca.crt >> /etc/openvpn/client/$client.conf
echo '</ca>' >> /etc/openvpn/client/$client.conf
echo '<cert>' >> /etc/openvpn/client/$client.conf
cat /etc/openvpn/easy-rsa/keys/$client.crt >> /etc/openvpn/client/$client.conf
echo '</cert>' >> /etc/openvpn/client/$client.conf
echo '<key>' >> /etc/openvpn/client/$client.conf
cat /etc/openvpn/easy-rsa/keys/$client.key >> /etc/openvpn/client/$client.conf
echo '</key>' >> /etc/openvpn/client/$client.conf

Ejemplo de configuración de cliente:

#Modo cliente
client

#Nombre de la intefaz
dev ethvpn

#Protocolo
proto udp

#Tipo de la interfaz
dev-type tap

#Servidor VPN
remote <IP VPN> 1194

#Puerto que escucha el cliente
port 3002

#Indicar que es un cliente TLS
tls-client

#Hacer un inline del certificado HMAC
key-direction 1
<tls-auth>
CERTIFICADO HMAC
</tls-auth>

#El keepalive hace que cada 10 segundos mande un ping y si no llega lo intente despues de 120.
keepalive 10 120

#Comprimir los paquetes
comp-lzo

#Traerse la conf del server
pull

#Para no mostrar la IP local y el puerto
nobind

#Para que no corra como root una vez iniciado (comprobar que existan tanto el usuario como el grupo)
user nobody
group nogroup

#Hacer persistentes
persist-key
persist-tun

#Configuracion Cipher recomendada
auth SHA512
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-256-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA:TLS-DHE-RSA-WITH-AES-128-CBC-SHA:TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA

#Evitar problemas con el MTU
mssfix

#Indicarle que compruebe con el servidor
remote-cert-tls server

#LOGGING
log-append /var/log/openvpn.log
status /var/log/openvpn-status.log

#Aquí se especifican los certificados del modo inline. También se podrían llamar a los certificados externos.
<ca>
CA
</ca>
<cert>
CERT
</cert>
<key>
KEY
</key>

Truco: Para hacer esto mas fácil, es recomendable automatizarlo. Para eso dejo aquí un script que he creado.

Por último, crear la configuración de red del cliente. Esto luego al realizar la conexión el cliente, lo detectará por el nombre de certificado.

vim /etc/openvpn/client/cliente

Y dentro de este, hacer un push con la configuración que nos interese. En este caso se le pasará una IP concreta.

ifconfig-push 192.168.10.10 255.255.255.0

Cliente

Ahora, hay que ir al cliente e instalar el cliente OpenVPN

apt install openvpn

Y pasar el archivo de configuración desde el servidor VPN

scp root@vpnserver:/etc/openvpn/client/cliente.conf /etc/openvpn/

Y por último habitar al inicio openvpn y iniciar el servicio

systemctl enable openvpn.service
systemctl start openvpn@cliente

En un futuro post, explicaré como utilizar el protocolo BGP para enrutar de manera automática.

Fuentes:

OpenVPN: tun y tap

https://www.digitalocean.com/community/tutorials/how-to-set-up-an-openvpn-server-on-debian-8

https://www.linode.com/docs/networking/vpn/set-up-a-hardened-openvpn-server

Leave a Reply

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *