top of page

Encapsulando VPN sobre TLS: Cómo camuflar tráfico como HTTPS

  • jogofus
  • 3 sept
  • 7 Min. de lectura

Siempre hemos hablado de la interconexión de sedes, de conexiones remotas a nuestras oficinas o incluso a nuestra casa.

Porque seamos sinceros, la gran mayoría de nosotros tiene sus propios servicios autohospedados en casa, o tiene un laboratorio de pruebas con el que cacharrea desde cualquier sitio.


Por ejemplo, yo en mi caso tengo mi propia nube, mi gestor de contraseñas, gestor documental, gestor de enlaces y mi propio servidor DNS privado. Porque sí, me gusta tenerlo todo organizado.


El problema viene cuando, de manera impositiva, nos encontramos con problemas a la hora de usar VPN.

ree

Situación actual a nivel mundial

Todos somos conocedores de la situación que actualmente se está viviendo en el mundo, y aunque este no es un blog sobre temas políticos, si que hay un tema que a nosotros, los que nos dedicamos a los sistemas y las redes, nos toca de bastante cerca.


Hay países, como China, en el que existe la censura en Internet y no hay posibilidad de uso de ciertas aplicaciones, visitar ciertas páginas o cosas por el estilo.


Ahora en Europa se ha vuelto a poner sobre la mesa el hecho del "control de Internet". Lo pongo entre comillas porque no es exactamente así, pero para resumirlo.

La idea principal es que, mediante una normativa, los gobiernos puedan acceder a las aplicaciones de comunicación (Whatsapp, Telegram, Instagram, Facebook, Signal...) antes de que se cifren los datos (es decir, dando permiso para que se pueda registrar la actividad desde nuestro dispositivo) o que se les abra una puerta trasera.


Muchos han sido los que han dicho que esto no es solo un problema en cuanto a protección de datos, sino que es abrir una puerta a cualquier "enemigo" que quiera hacer cosas malas. Bastantes ataques sufrimos ya como para encima ponerlo más fácil.


En Inglaterra ya se está poniendo en marcha este plan, como bien se cuenta en esta noticia: enlace a la noticia sobre la censura en Inglaterra.


ree

Además, en un comunicado oficial que se hizo, se dejó muy claro que el uso de las VPN no iba a funcionar (y dejo de lado los comentarios relacionados que se hicieron).


En Europa también se planteó algo así: quieren tener visibilidad de lo que pasa a través de las VPN, todo enmascarado con el titular de "proteger a los niños".


Y aquí es donde entramos nosotros, los que nos peleamos con routers, firewalls y switches. Los que miramos al dedillo las cabeceras de los paquetes del modelo OSI.

¿Qué pasará si se aprueba?

Bueno, es un tema a discutir.

Lo que yo tengo claro es que abrirá nuevos frentes para que nosotros tengamos que proteger nuestra información y la de nuestras empresas. Porque nadie quiere que sus datos caigan en manos de nadie.


Hace un par de semanas me puse a pensar: ¿y si verdaderamente esto se acaba aprobando y se prohíbe por ley las VPN autohospedadas? ¿Y si las VPN empresariales tienen que tener un backdoor?


Sinceramente, yo quiero poder seguir disponiendo de mis datos de casa en cualquier parte del mundo sin que nadie sepa mis contraseñas, por ejemplo.

Así que comencé a mirar la posibilidad de encapsular tráfico VPN y enmascararlo como si se tratara de tráfico TLS1.2, haciéndose pasar por una web normal y corriente.

Empezamos con el laboratorio: Wireguard a través de TLS

Dejémos de lado ya el tema político y empecemos con lo que de verdad nos interesa, que es lo técnico.


En este laboratorio vamos a encapsular tráfico Wireguard a través de TLS como si fueran WebSockets, de tal forma que si alguien hiciera un MITM vería peticiones a una API, con un certificado válido, además de que con el doble cifrado (TLS + Wireguard) es imposible el DPI.


Cabe resaltar que aquí me centro en tráfico VPN, pero vale para cualquier tipo de tráfico, tanto UDP como TCP.


¿Qué necesitamos?

Para empezar, necesitaremos una red a la que queramos conectarnos y un cliente. Este cliente puede ser la puerta de enlace de los equipos de su red a la otra, sin necesidad de ser el router de borde.


Esta es la infraestructura (virtual) que tengo preparada yo.


ree

Se ha añadido la red Net, que es puramente de gestión para poder conectar por SSH a los equipos, pero toda la comunicación entre ellos pasa por los routers R2-R1-R3.


Necesitaremos instalar Xray-core, y lo podremos hacer desde su github , además de instalar certbot para manejar certificados válidos. La otra alternativa sería pagar por los certificados.


¿Qué es Xray-core?

Xray-core es un núcleo de proxy de red escrito en Go (lo que nos asegura velocidad en procesamiento en cuanto a sockets). Permite tunelizar tráfico como TLS, WebSocket, Quic...


ree

Instalación del laboratorio

En mi caso voy a usar Let's Encrypt.


Instalamos lo necesario:

apt install certbot -y

Una vez lo hemos instalado, solicitaremos el certificado para nuestro dominio (que ha de ser válido) en modo standalone.

certbot certonly --standalone -d <dominio> -v

Una vez tengamos los certificados, a mi me gusta ponerlos en una ruta accesible y con permisos suficientes para ser leídos, aunque en este caso los he dejado donde certbot los deja por defecto.


Siguiente paso, instalamos Xray-core:

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install

La instalación es rápida, no lleva más de un minuto.

Esto lo deberemos instalar tanto el servidor (server1) como en el cliente (server2).


También deberemos instalar wireguard en ambos servidores.

apt install wireguard -y

Una vez instalado todo lo que necesitamos, procedemos a la configuración.


Configuración de Xray-core

La configuración se encuentra en /usr/local/etc/xray/config.json


En server1, la configuración es la siguiente:

{
  "inbounds": [{
    "listen": "0.0.0.0",
    "port": 443,
    "protocol": "vless",
    "settings": {
        "clients": [
        { "id": "<UUID único>"}
        ],
        "decryption": "none"
    },
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "tlsSettings": {
        "certificates": [{
          "certificateFile": "/ruta/al/certificado/certificado.pem",
          "keyFile": "/ruta/a/la/clave/privada/privkey.pem"
        }]
      },
      "wsSettings": { "path": "/wg" }
    }
  }],
  "outbounds": [{
    "protocol": "freedom",
    "settings": {
      "address": "127.0.0.1",
      "port": 51820,
      "network": "udp"
    }
  }]
}

En inbounds definimos las directivas de entrada.


"listen": IP por la que va a escuchar el servicio

"port": Puerto por el que va a escuchar el servicio. Típicamente será el 443 para aparentar ser una web.

"protocol": Aquí indicamos el protocolo que vamos a usar. Los protocolos que existen son:


vless

Protocolo ligero, sin cifrado propio (usa el de la capa de transporte, TLS/XTLS).

Ideal para túneles tipo WebSocket/TLS o QUIC.

Es el recomendado hoy en día porque es más simple y eficiente que VMess.


vmess

El “clásico” de V2Ray. Incluye cifrado en el propio protocolo.

Se usa menos en 2025 porque VLESS + TLS es más limpio y menos detectable.


socks

Crea un servidor SOCKS5 (proxy). Útil para que apps se conecten directamente.

Ejemplo: curl --socks5 127.0.0.1:1080.


http

Proxy HTTP normal.


dokodemo-door

“Captura todo” y lo reenvía a otro destino fijo.

Útil para interceptar tráfico local (como hicimos en el cliente Xray para WireGuard).


shadowsocks

Implementa Shadowsocks clásico.


trojan

Protocolo estilo Trojan-GFW (basado en TLS + contraseña).


vmesstls / xtls (según versiones)

Extensiones para usar TLS directo con menos overhead.


El recomendado es vless


En el apartado "settings": definimos las configuraciones adicionales, en este caso el UUID del cliente.

"clients": [{ "id": }], "decryption": "none"


En el apartado "streamSettings" definimos como va a viajar el tráfico a través del túnel Xray.

"network": "ws" Le decimos que el tráfico del protocolo viajará encapsulado en WebSocket.

"security": "tls" Activamos TLS (HTTPS) para el transporte. Sin esto, los websockets irían en claro.

"tlsSettings": { "certificates": [{ "certificateFile": "", "keyFile": ""}]}, Aquí indicamos los certificados que se van a utilizar.


En el apartado "outbounds": le decimos cuál es la puerta de salida del tráfico recibido.

"protocol": "freedom" Usamos freedom para indicar que no manipule los paquetes recibidos y los redirija.

"settings": { "address": "127.0.0.1", "port": "<puerto>", "network": "<tcp/udp>"}}] Indicamos a donde queremos redirigir el tráfico que recibe Xray.


Como vemos, nosotros hemos escogido puerto de escucha el 443, protocolo VLESS, hemos seleccionado los certificados y hemos redirigido el tráfico que llegue a ese puerto a la interfaz loopback, puerto 51820/UDP, es decir Wireguard.


Ahora debemos configurar el cliente:


{
  "inbounds": [{
    "listen": "127.0.0.1",
    "port": 51821,
    "protocol": "dokodemo-door",
    "settings": {
      "network": "udp",
      "address": "127.0.0.1",
      "port": 51820
    }
  }],
  "outbounds": [{
    "protocol": "vless",
    "settings": {
      "vnext": [{
        "address": "11.11.11.11",
        "port": 443,
        "users": [{ "id": "550e8400-e29b-41d4-a716-446655440000", 
"encryption": "none" }]
      }]
    },
    "streamSettings": {
      "network": "ws",
      "security": "tls",
      "tlsSettings": { "serverName": "<dominio definido en el certificado>" },
      "wsSettings": { "path": "/wg" }
    }
  }]
}

Esta configuración es muy similar a lo que nos encontramos en el servidor, salvo que cambiamos el protocolo de entrada por dokodemo-door, con el que capturamos todo el tráfico que llegue desde la dirección:puerto que indicamos y lo redirigimos a la dirección:puerto que indicamos en settings.


En outbounds definimos que usaremos el protocolo especificado en el servidor, que en este caso es VLESS, indicamos cual es la IP pública, el puerto y el UUID del usuario con el que se va a conectar. No se trata de un usuario real, sino de un UUID ficticio.


En streamSettings le indicamos que funcionaremos mediante websockets con cifrado TLS y añadimos el dominio para que esté en la cabecera como SNI.

Además, le añadimos un path para que simule la conexión a una API.


Configuración de wireguard

Esto es sencillo. Xray, al hacer de proxy, deberemos apuntar a los puertos que estamos redireccionando.


Server1:

[Interface]
Address = 192.168.50.1/24
PrivateKey = YEUN4/LUTROPVU1z2VnJyU64PGNzL8CYvzI4vSSOv3I=
ListenPort = 51820

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -
o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens4 -j 
MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD 
-o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens4 -j 
MASQUERADE
MTU =1400
[Peer]
AllowedIPs = 192.168.50.2/32
PublicKey = TEi4TlakU0mmqd514k8vNFeCKF+yz4WYmSNbcHdWLls=

Server2:

[Interface]
PrivateKey = ICuxNmV7Bo8wVqHA9H/Xes3xzxeIgcrWMHNOj9dRXlg=
Address = 192.168.50.2/32
MTU = 1400
[Peer]
PublicKey = Ta5OLS1yNyLmpiE0eDghO9JnacrXZE7JNR2bw7YMe2M=
AllowedIPs = 11.11.11.0/24
Endpoint = 127.0.0.1:51821
PersistentKeepalive = 15

Prueba final: encapsulando el tráfico en TLS

Levantamos el túnel Wireguard con las configuraciones que hemos puesto arriba, y si capturamos tráfico en, por ejemplo, R1, al hacer un ping desde server2 recibiremos los siguientes paquetes:


ree

ree

Y como podemos comprobar, el tráfico que va a través de la VPN nos aparece en R1 como TLS1.2, siendo indescifrable.



Espero que os haya gustado este post y que os sirva a modo educativo, para ver que en este mundo no hay límites que la mente humana no pueda superar.


¡Hasta la próxima!

 
 
 

Comentarios


bottom of page