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:
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