Cómo salir a internet a través de 2 vpns?

 

Recientemente tuve una amistad que me pidió ayuda. Él quiere conectar la PC de su casa a un servidor VPN (1), y que luego ese servidor se conecte a otro servidor VPN (2); siendo su objetivo final salir a internet con el IP público del servidor VPN 2.

La solución a su problema tiene nombre y es MULTI-HOP VPN. Pero que es MULTI-HOP VPN?

Como su nombre lo indica es una VPN de múltiples saltos que agrega una capa adicional de cifrado y un servidor adicional a su conexión VPN normal al «encadenar» o «conectar en cascada» dos o más servidores VPN juntos. El propósito es aumentar la seguridad y la privacidad proporcionadas por una conexión VPN estándar de un solo servidor.

Las VPN de múltiples saltos a veces se denominan VPN dobles, aunque se puede incluir cualquier cantidad de servidores VPN en la cadena. Esta guía le explicará todo lo que necesita saber sobre las VPN multisalto y como implementar una.

Así es como funciona una VPN típica de doble salto:

  • Sus datos se cifran en su dispositivo una vez, luego encriptada en su dispositivo por segunda vez (dos capas de encriptación).
  • Los datos cifrados se envían al primer servidor VPN. Se elimina la segunda capa de cifrado.
  • Los datos cifrados se envían al segundo servidor VPN.
  • Se elimina la primera capa de cifrado y los datos se descifran por completo.
  • Los datos descifrados se envían a su destino final.

Tenga en cuenta que cada capa de cifrado se elimina en el orden inverso al que se aplicó: el último en entrar, el primero en salir. La primera VPN en cifrar datos en el dispositivo será el último servidor de la cadena, y el último en cifrar datos será el primero de la cadena. Este túnel dentro de un túnel resuelve algunos de los problemas que pueden afectar a las conexiones VPN normales.

Este embrollo de palabras tal vez sea más fácil de entender en el siguiente esquema:

Pues bien, planteado el problema toca aplicar la solución.

  • La solución vpn a utilizar es el OpenVPN, pero puede utilizarse cualquier vpn (WireGuard, Outline…).
  • El cliente, por cuestiones de comodidad, será una VM con Ubuntu 22.04 corriendo localmente en mi propia laptop
  • El servidor VPN1 será una VM corriendo en un IaaS que ofrece buenos precios llamado Virtalus. Correrá Ubuntu 20.04. La misma tiene el IP público 144.168.40.133.
  • El servidor VPN2 será una instancia de EC2 en AWS. Correrá Ubuntu 20.04. La misma tiene el IP público 99.79.50.37.

NOTA: Recuerde siempre que cree alguna VM en algún Cloud Provider abrir los protocolos/puertos en los que va a ofrecer los servicios. En este caso específico son UDP/1194.

Debido a que los CloudProvider cobran por recursos utilizados y esto es un “home” lab, la RAM y CPU de cada VM son los mínimos (512 RAM y 1vCPU).

Comenzamos por la parte más fácil: instalar openvpn en cada una de nuestras VMs:

apt update && apt install openvpn -y

Configuración del VPN2

El siguiente paso es configurar el servidor OpenVPN en la instancia EC2 de AWS (VPN2). Para configurar servidores openvpn hay muchos artículos en línea, el presente tutorial no está enfocado en mejorar la velocidad ni la seguridad de la conexión, así que utilizo un script que me levanta un servidor openvpn en cuestión de segundos. El código del script no me pertenece, pero es libre de usar y está aquí.

Así que, entre a su VPN2 utilizando su cliente SSH de preferencia:

curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh && \
chmod +x openvpn-install.sh && \
./openvpn-install.sh

El script te hace algunas preguntas que te llevarán a configurar el servidor OpenVPN por ti, respóndalas a placer. Son preguntas simples y fáciles de responder y en todos los casos vienen con opciones pre-configuradas. Personalmente siempre dejo las opciones por defecto. Algo a tomar en cuenta es que en el caso específico de este script configura la vpn para utilizar la subred 10.8.0.0/24, detalle que será de importancia en la configuración del VPN1 (Virtalus).

En el proceso del propio script, en el penúltimo paso pregunta si quiere crear los criptomateriales para una conexión, basta con escribir un nombre cualquiera, por ejemplo “vpn1”, y en el paso final pregunta si quieres generarlos con contraseña, la opción por defecto es NO, pero es a gusto del consumidor si utilizar contraseña o no. Una vez termina el proceso sólo queda copiar los criptomateriales generados, si lee bien el output del script, los mismos estarán situados en /root/$nombre_que_introdujo. Hágale un cat, y cópielos en su editor de textos favorito.

Configuración del VPN1

Ahora vamos con la configuración del VPN1 (Virtalus). Primeramente, dentro de la VM, pegue en algún archivo de texto el contenido que copió previamente de /root/$nombre_que_introdujo del VPN2. Puede utilizar su editor de preferencia (nano rules!!!).  O:

cat << EOF > aws.ovpn 
client
proto udp
explicit-exit-notify
remote 99.79.50.37 1194
dev tun
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verify-x509-name server_T0GIeh2k4iadzPG6 name
auth SHA256
auth-nocache
cipher AES-128-GCM
tls-client
tls-version-min 1.2
tls-cipher TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256
ignore-unknown-option block-outside-dns
setenv opt block-outside-dns # Prevent Windows 10 DNS leak
verb 3
<ca>
-----BEGIN CERTIFICATE-----
MIIB1jCCAX2gAwIBAgIUEjODUqaBjx6j/o7NlCtR2eiavoAwCgYIKoZIzj0EAwIw
HjEcMBoGA1UEAwwTY25fQ3o0ZWNCQ1h4Y29oNG5ENDAeFw0yMzAzMDMwMTA3MDBa
Fw0zMzAyMjgwMTA3MDBaMB4xHDAaBgNVBAMME2NuX0N6NGVjQkNYeGNvaDRuRDQw
WTATBgcqhkjOPQIBAATCfi0I9sdt5jXsHek9U/xFUxVahu9t
Fe4rNxhQSM4NSpoGPHqP+js2UK1HZ6Jq+gDALBgNVHQ8E
BAMCAQYwCgYIKoZIzj0EAwIDRwAwRAIgTAkg5zjZDZSbckMnKcpHbVusWtI2N2+O
ulQqKve5GN8CIHLBhldYtNlAGrlj2jjfjj+Yz61grjIy20pEBCUX1WGD
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIIB2TCCAX6gAwIBAgIQeiajnD5gZhfP41efFymPFTAKBggqhkjOPQQDAjAeMRww
GgYDVQQDDBNjbl9DejRlY0JDWHhjb2g0bkQ0MB4XDTIzMDMwMzAxMDcxMloXDTI1
MDYwNTAxMDcxMlowETEPMA0GA1UEAwwGY2xpZW50MFkwEwYHKoZIzj0CAQYIKoZI
zj0DAQcDQgAEx3De0wOu9Rqt+3zcGlG7oiZEJt9Ay/a0NRbQhbslzm763NLH9OKa
lzF4/tQSzWWuyxk7eITFBiQ291GAZNlHmKOBqjCBpzAJBgNVHRMEAjAAMB0GA1Ud
DgQWBBTQ4MkIs0fxZEsalAJWujFhzpy+VDBZBgNVHSMEUjBQgBQqZCjeVgWHWRo6
l+RxdocmHnDcoaEipCAwHjEcMBoGA1UEAwwTY25fQ3o0ZWNCQ1h4Y29oNG5ENIIU
EjODUqaBjx6j/o7NlCtR2eiavoAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0P
BAQDAgeAMAoGCCqGSM49BAMCA0kAMEYCIQDJcxYgqtEvgsItBNAKIzA+ZQ+uIFq9
agOikJxvEImTmwIhAPqdSYiCK7wuD/aXzO5joBNWhjLkSjVhwXGyfH+zNJNL
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg9dPiuNa9E/3NNkVh
aXFoPbhaPo2zqGBuK87Dcl4KcwehRANCAATHcN7TA671Gq37fNwaUbuiJkQm30DL
9rQ1FtCFuyXObvrc0sf04pqXMXj+1BLNZa7LGTt4hMUGJDb3UYBk2UeY
-----END PRIVATE KEY-----
</key>
<tls-crypt>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
3b664d17a7f00280f7455e41cc984456
7c491b34a557305b52673539fa6690bd
ab7dac2e982e61dac78fe5a14048e55a
97493dc8158413e96bd1bd33cc4ee2ab
95a19e5c60cca0be557f708191b83cce
74b918530e7331fb18b298d6dbe24f64
b99df95bdfee7945ae4e1ab5b0a2e1d2
2885139ffc03ce3fa0b40fd069d30de2
4732b0da0c966bfeaca44d36eb909a2a
94e79c141fb49721b7b941ebde906576
6ce2ce4bf65686f12d67d8c94fd877e6
7d44abc3d600e731a44e8dfa73bb9f04
852234dc784a819dcb128b74f78245f1
faa4d95317a990e45132dddb147c273b
4d18332a082b0dfd5292e2fc6eb5335e
90117550dc2f1b1a7cc8c1406f125232
-----END OpenVPN Static key V1-----
</tls-crypt>
EOF

NOTA: Lo anterior es sólo un ejemplo de cómo se vería un archivo de criptomateriales de openvpn

Para probar el servidor OpenVPN corriendo en el VPN1 intente realizar una conexión:

tmux new -s vpn

Una vez dentro de la sesión de tmux:

openvpn aws.ovpn

NOTA: Lo más seguro es que en este punto pierda la conexión con el VPN1, esto ocurre a que al conectarse a un servidor OpenVPN, este le configura las rutas por defecto para salir al internet usando la conexión del VPN2. En este caso solamente tiene que abrir una consola a esa VM desde el servicio web que contrató para instanciarla, en el caso de Virtalus el proceso es sencillo. Les dejo los links para los casos de AWS, Linode y Azure. Una vez dentro de la consola virtual abre la sesión de tmux llamada (en mi caso) vpn y solamente envía Ctrl+C, esto detendrá la conexión y podrá volver a conectarse a su VPN1 usando el cliente SSH de preferencia.

Probada que la conexión fue satisfactoria ahora queda configurar el servidor OpenVPN en VPN1, para ello hacemos la misma operación que en el caso del VPN2:

curl -O https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh && \
chmod +x openvpn-install.sh && \
./openvpn-install.sh

Recuerde que el script genera un archivo con el nombre que usted le escriba, en dicho archivo están los criptomateriales para la conexión openvpn. Cópielos en algún editor de texto y téngalo a mano!

Ahora, aquí deberemos de hacer un pequeño arreglo en la configuración del servidor OpenVPN, así que detenga el servicio y abra el archivo de configuración:

systemctl stop openvpn@server &&\
nano /etc/openvpn/server.conf

En este archivo tenemos que buscar la línea siguiente:

server 10.8.0.0 255.255.255.0

Y cambiar la subred 10.8.0.0, por alguna otra de su preferencia. En mi caso en particular utilicé la 10.10.0.0. Hecho este cambio puede proceder a iniciar el servicio que detuvo:

systemctl start openvpn@server

NOTA: El cambio es requerido hacerlo debido a que ambos servidores vpn (VPN1 y VPN2 como servidor ambos) van a estar en el mismo segmento de red, y eso creará errores de configuraciones.

Aún falta por hacer algunos pequeños cambios. Si escribimos ip a veremos que nuestro servidor VPN1 tiene una interfaz de red llamada tun0:

5: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 100
    link/none
    inet 10.10.0.1/24 brd 10.10.0.255 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::fb6b:910f:fa01:9a43/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

Bien, esa interfaz hace referencia a la creada por el servidor OpenVPN. Cuando nos conectemos de VPN1 a VPN2 se creará otra interfaz de red llamada (usualmente) tun1, tenemos que hacer que nuestro servidor VPN1 enrute todo el tráfico que le entra por la interfaz tun0 hacia la tun1. Esto lo hacemos utilizando iptables de la siguiente forma:

iptables -t nat -I POSTROUTING 1 -s 10.10.0.0/24 -o eth0 -j MASQUERADE
iptables -A FORWARD -i tun0 -o tun1-j ACCEPT
iptables -t nat -A POSTROUTING -o tun1-j MASQUERADE

Lo siguiente debería de hacerlo automáticamente el script, pero nunca está de más comprobar:

sysctl -w net.ipv4.ip_forward=1

Y listo! Ahora que tiene configurado el servidor VPN1 correctamente sólo resta conectarse como cliente al VPN2, para ello abra la sesión de tmux que dejó en segundo plano, y reconecte la vpn que utilizó de prueba anteriormente. Perderá la conexión hacia el VPN1 si está utilizando algún cliente SSH (PuTTY, XShell, MobA…) como se explicó anteriormente.

NOTA: Antes de conectar el cliente, recuerde haber obtenido y copiado en algún lugar los criptomateriales generados por el servidor OpenVPN de VPN1!!!

Configuración del Cliente

La configuración del cliente es la más sencilla. Si ya instaló el paquete de openvpn solamente queda pegar en algún archivo los criptomateriales generados por VPN1 y conectar el cliente (en mi caso llamé el archivo de texto vpn1.ovpn):

openvpn vpn1.ovpn

Para comprobar que, en efecto, estamos saliendo a internet a través de VPN2 y no de VPN1, basta con, desde el cli de nuestro cliente, ejecutar algo como:

curl https://ipinfo.io/ip

public ip

Y listo todo!!!

El tutorial es muy básico, puede mejorarse en muchos aspectos, sobre todo de seguridad, pero ofrece un punto de inicio para los que deseen hacer algo similar.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Autores:

  • Frank Morales
  • Franco Díaz

¿De cuánta utilidad te ha parecido este contenido?

¡Haz clic en una estrella para puntuar!

Promedio de puntuación 5 / 5. Recuento de votos: 8

Hasta ahora, ¡no hay votos!. Sé el primero en puntuar este contenido.