Introducción

En este post vamos a configurar una conexión VPN sitio a sitio entre dos equipos:

  • Cada equipo estará conectado a dos redes, una de ellas en común
  • Para la autenticación de los extremos se usarán obligatoriamente certificados digitales, que se generarán utilizando openssl y se almacenarán en el directorio /etc/openvpn, junto con con los parámetros Diffie-Helman y el certificado de la propia Autoridad de Certificación.
  • Se utilizarán direcciones de la red 10.99.99.0/24 para las direcciones virtuales de la VPN.
  • Tras el establecimiento de la VPN, una máquina de cada red detrás de cada servidor VPN debe ser capaz de acceder a una máquina del otro extremo.

Preparando el escenario

Vamos a dividir el escenario en dos, por una parte, un escenario que actuará de servidor:

Vagrant.configure("2") do |config|
    config.vm.provider :libvirt do |libvirt|
        libvirt.memory = 1024
    end
    config.vm.define :nodo1 do |nodo1|
      nodo1.vm.box = "debian/bullseye64"
      nodo1.vm.hostname = "Servidor"
      nodo1.vm.synced_folder ".", "/vagrant", disabled: true
      nodo1.vm.network :private_network,
        :libvirt__network_name => "privadavpn",
        :libvirt__dhcp_enabled => false,
        :ip => "172.30.0.10",
        :netmask => "255.255.255.0",
        :libvirt__forward_mode => "veryisolated"
    end
    config.vm.define :nodo2 do |nodo2|
      nodo2.vm.synced_folder ".", "/vagrant", disabled: true
      nodo2.vm.box = "debian/bullseye64"
      nodo2.vm.hostname = "Cliente"
      nodo2.vm.network :private_network,
        :libvirt__network_name => "privadavpn",
        :libvirt__dhcp_enabled => false,
        :ip => "172.30.0.11",
        :netmask => "255.255.255.0",
        :libvirt__forward_mode => "veryisolated"
     end
  end

Y por otra parte, un escenario que actuará de cliente:

Vagrant.configure("2") do |config|
    config.vm.provider :libvirt do |libvirt|
        libvirt.memory = 1024
    end
    config.vm.define :nodo1 do |nodo1|
      nodo1.vm.box = "debian/bullseye64"
      nodo1.vm.hostname = "Servidor2"
      nodo1.vm.synced_folder ".", "/vagrant", disabled: true
      nodo1.vm.network :private_network,
        :libvirt__network_name => "privadvpn2",
        :libvirt__dhcp_enabled => false,
        :ip => "172.20.0.10",
        :netmask => "255.255.255.0",
        :libvirt__forward_mode => "veryisolated"
    end
    config.vm.define :nodo2 do |nodo2|
      nodo2.vm.synced_folder ".", "/vagrant", disabled: true
      nodo2.vm.box = "debian/bullseye64"
      nodo2.vm.hostname = "Cliente2"
      nodo2.vm.network :private_network,
        :libvirt__network_name => "privadvpn2",
        :libvirt__dhcp_enabled => false,
        :ip => "172.20.0.11",
        :netmask => "255.255.255.0",
        :libvirt__forward_mode => "veryisolated"
     end
end

Configurando el servidor

Lo primero que tendremos que hacer es instalar el servicio openvpn y crearemos el fichero .vars que contendrá las variables que usaremos en el resto de la configuración:

apt install openvpn

cp /usr/share/easy-rsa/vars.example /etc/openvpn/easy-rsa/vars

Ahora, vamos a editar el fichero /etc/openvpn/easy-rsa/vars y vamos a modificar las siguientes variables:

set_var EASYRSA_REQ_COUNTRY     "ES"
set_var EASYRSA_REQ_PROVINCE    "Sevilla"
set_var EASYRSA_REQ_CITY        "Dos Hermanas"
set_var EASYRSA_REQ_ORG         "MJAR"
set_var EASYRSA_REQ_EMAIL       "mariajesus.alloza@outlook.es"
set_var EASYRSA_REQ_OU          "VPN site to site"

Creamos eldirectorio donde almacenaremos la Autoridad Certificadore (CA) y generamos la clave Diffie-Helman:

cd /usr/share/easy-rsa
./easyrsa init-pki
---
./easyrsa gen-dh

Terminado esto, construimos la Autoridad certificadora:

./easyrsa build-ca
#Frase de paso: admin

El siguiente paso será que, ya teniendo nuestra Autoridad Certificadora, crearemos y firmaremos el certificado para server:

./easyrsa gen-req server
./easyrsa sign-req server server

Ahora le toca el turno al segundo escenario, y comenzaremos firmando el certificado para server2:

./easyrsa gen-req server2
./easyrsa sign-req client server2

Copiamos los certificados y claves generadas al directorio /etc/openvpn/server:

#Copiamos los ficheros
cp -rp /etc/openvpn/easy-rsa/pki{ca.crt,dh.pem,issued/server.crt,private/server.key} /etc/openvpn/server

#Enviamos por scp los ficheros
scp -r /etc/openvpn/server vagrant@192.168.121.21:

Creamos el fichero de configuración del servidor VPN:

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

Y editamos el fichero /etc/openvpn/server/servidor.conf:

dev tun
ifconfig 10.99.99.1 10.99.99.2
route 172.20.0.0 255.255.255.0
tls-server
ca ca.crt
cert server.crt
key server.key
dh dh.pem
comp-lzo
keepalive 10 120
log /var/log/openvpn/server.log
verb 3
askpass contra.txt

Iniciamos el servicio y nos cercioramos de que está activo:

systemctl enable --now openvpn-server@servidor
systemctl start openvpn-server@servidor
systemctl status openvpn-server@servidor

Configuramos el bit de forwarding en el servidor:

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

Y configuramos el cliente del primer escenario cambiando la ruta por defecto:

ip route del default
ip route add default via 172.20.0.20

Configurando el cliente

Ahora le toca el turno a servidor2 y comenzaremos moviendo los ficheros de los certificados y claves generadas al directorio /etc/openvpn/client:

#Copiamos los ficheros
mv ca.crt /etc/openvpn/client
mv server2.crt /etc/openvpn/client
mv server2.key /etc/openvpn/client

Creamos el fichero de configuración tomando primero como referencia el fichero de configuración del servidor:

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

Y editamos el fichero /etc/openvpn/client/cliente.conf:

dev tun

remote 192.168.121.115
ifconfig 10.99.99.2 10.99.99.1
route 172.30.0.0 255.255.255.0
tls-client
ca ca.crt
cert server.crt
key server.key
comp-lzo
keepalive 10 120
verb 3
askpass contra2.txt

Iniciamos el servicio y nos cercioramos de que está activo:

systemctl start openvpn-client@cliente
systemctl status openvpn-client@cliente

Configuramos el bit de forwarding en el servidor:

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

Y configuramos el cliente del primer escenario cambiando la ruta por defecto:

ip route del default
ip route add default via 172.20.0.20

Comprobando la conexión

Comprobamos que el tunel se ha creado correctamente:

  • Rutas del escenario 1
  • Rutas del escenario 2
  • Conexión desde el cliente del escenario 1
  • Conexión desde el cliente del escenario 2

Conclusiones

Una VPN site to site es una solución muy útil para conectar dos redes privadas de forma segura. En este caso, hemos utilizado OpenVPN, pero existen otras soluciones como IPsec, que también son muy interesantes.

En este caso, hemos utilizado dos escenarios, pero también se podría utilizar un solo escenario, con dos clientes conectados a un servidor VPN.