lunes, 27 de julio de 2020

CenTOS 8 | Ubuntu 20.04: OpenVPN 2.4.9 Server y Cliente



OpenVPN 2.4.9 Server y Cliente con certificados TLS 

Situación Presentada

Una amigo me preguntó, si había una forma de asegurar la conexion a la red local de su microempresa para que la gente que forma parte de ella, pudiera conectarse desde su casa.

Y qué hacemos entonces?
Naturalmente, le propuse implementar una solucion open source, ya que el disponia de un servidor extra, y no tenia presupuesto para pagar licencias o comprar otro equipo.
La propuesta fue, instalar un servidor con Linux ( CentOS o Ubuntu )  e implementar OpenVPN server 2.4.9.


Componentes del articulo

1. Pre-requisitos para instalación
  1.1 Requisitos CenTOS 8
  1.2 Requisitos Ubuntu 20.04
2. Firewall
  2.1 Ubuntu 
  2.2 CentOS 
3. Instalación de paquetes
  3.1 Ubuntu 
  3.2 CentOS
4. Preparacion de ambiente (Forwarding, Masquerade)
  4.1 Ambas Distros
  4.2 Ubuntu
  4.3 CentOS
5. Crear CA local.
  5.1 Ambas Distros
6. Crear Certificados
  6.1 Crear par de llaves y CSR para server.
  6.2 Firmar CSR y generar certificado de server
  6.3 Crear certificado para usuario de prueba.
7. Configurar servicio OpenVPN
  7.1 Editar archivo de configuracion
8. Crear archivo de Configuracion para Cliente OpenVPN
9. Pruebas de conexión Cliente OpenVPN
  9.1 Desde Linux
  9.2 Desde Windows



1. Pre-requisitos para instalación


•Un PC con CentOS 8 o Ubuntu 20.04, usados en este tutorial.
•Una conexión de red a internet (cableada preferiblemente)
•Una IP Publica para hacer las pruebas de conexion.
•Un servidor DNS corriendo (usar DNSMasq o DNS configurado en este post )
•Conocimiento basico de shell de Linux

  1.1 Pre-requisitos CentOS 8

•Actualizar repositorios e instlara el repositorio EPEL tambien.

   sudo yum install epel-release
   sudo yum update
   sudo yum update

* Nota: Si aparece un error indicando que no puede sincronizar, ejecutar lo siguiente:

   sudo dnf update -y --releasever=8

  1.2 Pre-Requisitos Ubuntu 20.04


• Actualizar repositorios:

   sudo apt update


2. Configurar Firewall
Si no está hecho ya, se debe abrir los puertos udp y tcp /1194 (openvpn) , aunque se puede configurar el openvpn server para que escuche en otro puerto, como por ejemplo, el 443.
 
Si no se está usando firewall, omitir paso, sin embargo es fuertemente aconsejable, y casi mandatorio tenerlo activo.

**NOTA: La red que uso en mi laboratorio es la 172.26.7.89/20 que es NATeada por la 54.81.48.202 (la ip publica que usare.

Permitir Inbound:

tcp/1194    - OpenVPN TCP
udp/1194   - OpenVPN UDP

2.1 Ubuntu 
La configuracion que se usará para el servidor vpn, será la siguiente (en caso de ya estar configurados algunas reglas, omitirlas y pasar a la de openvpn, la última).

En Ubuntu El firewall esta deshabilitado por default. 
Para habilitarlo, y configurarlo a lo minimo, ejecutaremos los siguientes comandos:

Crear las reglas generales con el principio de Denegacion Implicita para prevenir accesos no autorizados.
sudo ufw default allow outgoing
sudo ufw default deny incoming

Agregar excepcion para conectarnos por SSH, desde nuestra red:
sudo ufw allow 22/tcp comment 
'aceptar trafico SSH a NUESTRA red'

Agregar excepcion para el servicio web que habrá (OpenVPN), desde nuestra red:
sudo ufw allow 1194/tcp comment 'aceptar trafico OpenVPN TCP'
sudo ufw allow 1194/udp comment 'aceptar trafico OpenVPN UDP'

2.2 CentOS
Se ejecutará lo mismo que en el inciso anterior para Ubuntu, pero con la sintaxis del firewall para CentOS:

Agregar reglas con excepciones:
SSH:
sudo firewall-cmd --zone=public --permanent --add-port=22/tcp


OpenVPN
sudo firewall-cmd --zone=public --permanent --add-port=1194/tcp
sudo firewall-cmd --zone=public --permanent --add-port=1194/udp

sudo firewall-cmd --reload

Se confirman los cambios:
sudo firewall-cmd --zone=public --list-all

3. Instalación de Paquetes

Se debe instalar tanto el OpenVPN como el Easy RSA para generar las llaves. Aunque se puede hacer con OpenSSL directo, Easy RSA contiene muchos scripts que automatizan y facilitan el proceso.

3.1 Ubuntu
sudo apt install openvpn easy-rsa

3.2 CentOS
sudo yum install openvpn easy-rsa -y



Ambos Distros

sudo ln -s /usr/share/easy-rsa/3.0.7 /etc/openvpn/easy-rsa
*Nota: Depende la version que fue instalada, es el link que se creara.

4. Preparacion de ambiente (Forwarding, Masquerade)

4.1 Ambos Distros

Para ambas Distro, tenemos que habilitar el IP Forwarding.

sudo vim /etc/sysctl.conf

Y se agrega la siguiente linea:
net.ipv4.ip_forward = 1

Luego se recarga la configuracion.
sudo sysctl -p

4.2 Ubuntu

sudo vim /etc/ufw/before.rules

La siguiente información que agregaremos al script file del firewall (ufw) servirá para establecer la politica default en la cadena POSTROUTING de la tabla de NAT para enmascarar (masquerade) el trafico que venga de la VPN. El nombre de la interfaz a usarse esta en color azul (puede cambiar dependiendo el ambiente)
# reglas de NAT *nat :POSTROUTING ACCEPT [0:0]
#Permitir que se pase el trafico de OpenVPN por medio de nuestra interfaz eth0 -A POSTROUTING -s 10.8.0.0/8 -o eth0-j MASQUERADE COMMIT
Hay que decirle al firewall que permita pasar paquetes reenviados de manera default tambien. Para hacerlo, abrimos el archivo siguiente:

sudo vim /etc/default/ufw
Dentro hay que buscar la directiva,DEFAULT_FORWARD_POLICY y ponerle ACCEPT en vez de DROP DEFAULT_FORWARD_POLICY="ACCEPT"
Y reiniciar. sudo ufw disable sudo ufw enable

4.3 CentOS

Hay que agregar el servicio OpenVPN y la interface que crea (tun0) a la zona que estamos usando (publica en mi caso) sudo firewall-cmd --permanent --zone=public --add-interface=tun0 Luego agregar el MASQUERADE a la zona default que tenemos. sudo firewall-cmd --permanent --add-masquerade Luego ejecutar lo siguiente para enmascarar el trafico de internet viniendo de la red VPN (10.8.0.0/24) a la interfaz local de red eth0. sudo firewall-cmd --permanent --direct --passthrough ipv4 -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE Y recargar la configuracion: sudo firewall-cmd --reload


5. Crear CA local   
Tomar nota que este paso no es necesario si estamos utilizando un CA Authority externo. El ejemplo es un Standalone, por lo que en este caso, si es requerido.

5.1 Ambos Distros

Crear el archivo /etc/openvpn/easy-rsa/vars

sudo vim /etc/openvpn/easy-rsa/vars

Y agregar los siguientes valores (notar que los valores en azul son diferentes para cada ambiente)

set_var EASYRSA                 "$PWD"
set_var EASYRSA_PKI             "$EASYRSA/pki"
set_var EASYRSA_DN              "cn_only"
set_var EASYRSA_EXT_DIR         "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF        "$EASYRSA/openssl-easyrsa.cnf"
set_var EASYRSA_DIGEST          "sha256"
set_var EASYRSA_REQ_COUNTRY     "HN"
set_var EASYRSA_REQ_PROVINCE    "Cortes"
set_var EASYRSA_REQ_CITY        "Puerto Cortes"
set_var EASYRSA_REQ_ORG         "PlecaEtc Blog "
set_var EASYRSA_REQ_OU          "PlecaEtc standalone CA"
set_var EASYRSA_REQ_EMAIL "admin@plecaetc.local"
set_var EASYRSA_KEY_SIZE        2048
set_var EASYRSA_ALGO            rsa
set_var EASYRSA_CA_EXPIRE 7500
set_var EASYRSA_CERT_EXPIRE     365
set_var EASYRSA_NS_SUPPORT "no"

Iniciar el modulo de easyrsa para hacer nuestro CA Authority local

cd /etc/openvpn/easy-rsa/
sudo ./easyrsa init-pki


sudo ./easyrsa build-ca
Y presionar enter, no llenar valores que ya estan llenos desde el archivo vars
Nota: la contraseña que usemos aqui será usada para firmar los certificados futuros.



6. Crear  Certificados 
Se deben crear ahora el par de llaves (privada y publica) del servidor y una solicitud de certificado (csr) .

6.1 Crear Par de llaves y CSR para server 

cd /etc/openvpn/easy-rsa/

sudo ./easyrsa gen-req vpn-server nopass


6.2 Firmar CSR y generacion de certificado de server

sudo ./easyrsa sign-req server vpn-server

Escribir "yes" cuando lo solicite

Escribir la contraseña del paso 5 (al crear la CA ) cuando lo solicite.

Ya con esto fue creado el Certificado de nuestro servidor VPN y sus llaves.
Se pueden verificar en caso de duda.

sudo openssl verify -CAfile pki/ca.crt pki/issued/vpn-server.crt


Se crea una llave con algoritmo Diffie-Hellman para el intercambio de llaves.

sudo ./easyrsa gen-dh


Se copian todos los archivos que generamos que son necesarios para el servidor OpenVPN que estamos montando

sudo cp -v pki/ca.crt pki/private/vpn-server.key pki/issued/vpn-server.crt pki/dh.pem /etc/openvpn/server/

6.3 Crear certificado para un usuario de prueba.
crea


cd /etc/openvpn/easy-rsa
sudo ./easyrsa gen-req UsuarioVPN nopass


sudo ./easyrsa sign-req client UsuarioVPN 

Escribir "yes" cuando se solicite y la contraseña de la llave de nuestro CA (paso 5)


Copiar los archivos generados al directorio de clientes del openvpn .

sudo cp -v pki/ca.crt pki/private/UsuarioVPN.key pki/issued/UsuarioVPN.crt /etc/openvpn/client/





7. Configurar servicio OpenVPN
Copiar el archivo de configuracion de muestra al directorio server de openvpn .

sudo cp -v $(locate /server.conf | grep openvpn) /etc/openvpn/server/


7.1 Editar archivo de configuracion
sudo vim /etc/openvpn/server/server.conf 

En el archivo de configuracion modificar los siguientes valores a nuestro ambiente y preferencia:

cert /etc/openvpn/server/vpn-server.crt
key /etc/openvpn/server/vpn-server.key
dh /etc/openvpn/server/dh.pem

Y descomentar (remover el ; ) del inicio de la linea:

push "redirect-gateway def1 bypass-dhcp"
push "dhcp-option DNS 208.67.222.222" push "dhcp-option DNS 208.67.220.220"

Si se desea utilizar el mismo cn (nombre) para varios certificados descomentar:

;duplicate-cn

Comentar las siguientes linea (con ; al inicio ) :

;tls-auth ta.key 0 # This file is secret

y escribir debajo los cifrados seguros que usaremos en su lugar sumado al diffie helman cert:

tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
auth SHA512
auth-nocache

Descomentar:

compress lz4-v2
user nobody group nobody
log-append openvpn.log

Para conectar por TCP en vez de UDP (opcional a preferencia):

# TCP or UDP server? proto tcp ;proto udp
explicit-exit-notify 0

Bueno deberia quedar algo asi al correr:

cat /etc/openvpn/server/server.conf | grep -v -E "(^;|^#)" | sed '/^$/d'



7.2 Levantar servicio openvpn 

sudo systemctl enable openvpn-server@server
sudo systemctl start openvpn-server@server

Y verificamos el estado del servicio.
sudo systemctl status openvpn-server@server


Tambien confirmamos que este arriba la nueva interfaz de tunel.
ifconfig tun0


8. Crear archivo de Configuracion para Cliente OpenVPN
El archivo de configuracion para los clientes, es muy similar al archivo de configuracion del servidor,
por lo que es preciso lanzar el siguiente comando para crear uno nuevo, pero sin tanta informacion innecesaria:

sudo cat /etc/openvpn/server/server.conf | grep -v -E "(^;|^#)" | sed '/^$/d' > /etc/openvpn/client/client.ovpn


Luego editar los valores eliminando todo lo que esta en rojo:

Agregar los valores en verde y editar el nombre del certificado del cliente (en este caso es UsuarioVPN.crt):


Quedará algo así:

client dev tun proto tcp remote test.dcastt.com 1194 remote-cert-tls server ca /etc/openvpn/client/ca.crt cert /etc/openvpn/client/UsuarioVPN.crt key /etc/openvpn/client/UsuarioVPN.key cipher AES-256-CBC auth SHA512 tls-version-min 1.2 tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256 auth-nocache resolv-retry infinite compress lz4-v2 nobind persist-key persist-tun mute-replay-warnings verb 7

9. Pruebas de conexión Cliente OpenVPN

9.1 Desde Linux
En otro equipo de Linux ejecutar lo siguiente para instalar el cliente openvpn:

sudo apt install openvpn -y

Y copiar el folder /etc/openvpn/client desde el servidor al equipo cliente
(se puede hacer por scp o copiando manualmente con otra herramienta):

(Nota: Aqui se utiliza la copia con metodo scp , ya que lo tengo permitido en mi server,
de no ser asi se tendrá que copiar manualmente)

Una vez copiado, preparamos el servicio para iniciarlo normalmente:

sudo nano /usr/lib/systemd/system/openvpn.service

Y lo dejamos a manera que seleccione nuestro nuevo archivo de configuracion modificando los valores en azul.

[Unit] Description=OpenVPN service After=network.target [Service] Type=notify RemainAfterExit=yes ExecStart=/usr/sbin/openvpn --config /etc/openvpn/client/client.ovpn ExecReload=/usr/sbin/openvpn --config /etc/openvpn/client/client.ovpn WorkingDirectory=/etc/openvpn/client [Install] WantedBy=multi-user.target

Se recarga el daemon del systemctl para que tenga los nuevos cambios y se habilita e inicia el servicio:.

sudo systemctl daemon-reload
sudo systemctl enable openvpn;systemctl start openvpn

Se confirma que haya levantado revisando que la interfaz tun0 este arriba con una IP.

systemctl status openvpn 


ifconfig tun0


Verificamos que nuestra IP publica ha cambiado (debe ser la misma ip publica del server) con el siguiente comando:
host myip.opendns.com resolver1.opendns.com 

Nota: si no esta el programa host en el sistema, instalarlo con el bind-utils (yum o apt)


9.2 Desde Windows

Descargar la version community que nos corresponda, desde el sitio oficial de OpenVPN

E instalar como adminisatrador debido al adaptador de red que habiltirá.

Copiar el mismo contenido del folder /etc/openvpn/client al folder de windows C:\Program Files\OpenVPN\config

De
Hacia

Se debe modificar la configuracion para windows, hay que removerle las rutas a los archivos de certificados y llaves dentro del archivo client.ovpn a maner que quede asi.



Iniciar el servicio.



Nuevamente la IP publica que tenemos es la del servidor VPN.


10. Referencias

Cambiar modo de autenticacion a PAM (usuario/password)
https://openvpn.net/vpn-server-resources/authentication-options-and-command-line-configuration/

How To Set Up and Configure an OpenVPN Server on Ubuntu 20.04
https://www.digitalocean.com/community/tutorials/how-to-set-up-and-configure-an-openvpn-server-on-ubuntu-20-04

How To Install OpenVPN on CentOS/RHEL 8
https://tecadmin.net/install-openvpn-centos-8/

CentOS 8 Set Up OpenVPN Server In 5 Minutes
https://www.cyberciti.biz/faq/centos-8-set-up-openvpn-server-in-5-minutes/