Conexión SSH a través de HTTPS
(trofi.github.io)- Incluso si el puerto de
SSHestá bloqueado en una red restrictiva, se puede crear una ruta de acceso remoto usando el puerto 443 de HTTPS y el métodoCONNECT - En el servidor,
apache2abreCONNECTconmod_proxy_connect, pero limita el alcance del proxy permitiendo solo el destino ssh-server:22 - En el cliente, se enlazan ProxyCommand de OpenSSH y
socat, y para HTTPS un script envía directamente los encabezadosCONNECT - Algunos firewalls o
httpdpueden cerrar conexiones inactivas, por lo queServerAliveInterval 30ayuda a mantener la sesión - Este método encapsula
SSHdentro deTLS, por lo que es más fácil evitar bloqueos, aunque sigue existiendo la doble encriptación y la carga de configuración del cliente
Crear una ruta de acceso SSH en una red restringida
- En el entorno de Wi‑Fi de un hospital, la mayoría de los tipos de conexión estaban bloqueados, y por lo general solo se permitían TCP 80 de
HTTPy TCP 443 deHTTPS - UDP 53 de
DNSy TCP 853 deDoTparecían funcionar con proveedores de DNS bien conocidos SSHestaba completamente bloqueado en TCP 22 y en la mayoría de los puertos personalizados- Había una conexión alternativa por
GSMque permitía reconfigurar el servidor remoto, así que fue posible probar varios métodos de evasión
Compartir un puerto y encapsular protocolos
- Hay una forma de recibir
SSHyHTTPSen un mismo puerto y bifurcarlos de manera transparente- sslh project estima el protocolo con heurísticas y lo redirige al backend real de
SSH,HTTPSo algún protocolo compatible - La ventaja es que el cliente
sshno necesita configuración especial, y basta con indicar un puerto no predeterminado - La desventaja es que hay que configurar un servicio adicional,
HTTPStambién debe pasar porsslh, y la dirección de origen de la conexión puede quedar oculta en el backend, lo que dificulta el registro
- sslh project estima el protocolo con heurísticas y lo redirige al backend real de
- Otra opción es encapsular por completo un protocolo dentro de otro
ProxyCommandde OpenSSH permite al usuario definir el medio de transporte que usará el protocolossh- Como envuelve
SSHdentro de otro flujo sin heurísticas, puede ser más difícil de bloquear para software de DPI HTTPSen sí no se redirige ni se ve afectado- A cambio, la doble encriptación puede reducir el rendimiento y requiere configuración en el cliente
Configuración de SSH sobre HTTP
- Primero se probó un método para hacer pasar
SSHporHTTP - En el servidor, la configuración de
apache2cargamod_proxy_connecty permite CONNECT al puerto 22 conAllowCONNECT 22 <Proxy *>niega todo por defecto, y solo<Proxy ssh-server>queda permitido para limitar el destino assh-server:22- En el cliente,
.ssh/configusaProxyCommandconsocatyPROXY:http-server:%h:%p,proxyport=80 - Con esta configuración, al ejecutar
$ ssh ssh-via-httpes posible conectarse aSSHa través del puerto 80 ServerAliveInterval 30envía sondeos periódicos para evitar que una conexiónHTTPinactiva se cierre silenciosamente en algún punto intermedio- El
httpdpredeterminado usaTimeOut 60, que cierra el túnel si no hay entrada ni salida durante 60 segundos
Configuración de SSH sobre HTTPS
- Al parecer,
socatno soporta proxyHTTPSmediante el métodoCONNECTy solo soportaHTTP - En su lugar, se usa la función de encapsulación TLS de
socat, y la solicitud basada enCONNECTse implementa directamente en un script ~/.ssh/https-tunnel.bashfunciona con el siguiente flujo- Primero imprime el encabezado
CONNECT ssh-server:22 HTTP/1.1yHost: ssh-server - Después concatena la entrada estándar tal como llega
- Envía todo el flujo a
socat - "SSL:$3:$4"para crear una conexión TLS
- Primero imprime el encabezado
- En
.ssh/config, se especificaProxyCommand ~/.ssh/https-tunnel.bashparaHost ssh-via-https - Al ejecutar
$ ssh ssh-via-https, la conexión assh-serverfunciona como se esperaba a través del túnelHTTPS
Puntos a tener en cuenta en operación
- En entornos donde
HTTPSestá ampliamente permitido, se pueden transmitir datos a través de equipos intermedios muy restrictivos - El método
CONNECTpuede parecer un vestigio antiguo, pero es útil para envolver un flujo de carga útil TCP arbitrario dentro de un flujo de hostTLS ServerAliveIntervalayuda a mantener la conexión OpenSSH cuando la capa de transporte subyacente no trata bien las conexiones inactivas- Hay una variante de configuración para
nginxen CONNECT passthrough on nginx
1 comentarios
Opiniones en Hacker News
La parte del artículo que dice que “HTTPS está en todas partes, por lo que incluso equipos intermedios muy restrictivos pueden dejar pasar los datos” es precisamente la razón por la que casi todos los protocolos VPN propietarios, las llamadas “SSL VPN”, implementan un modo que abre túneles por HTTPS.
Aunque no sea el comportamiento predeterminado, al menos lo tienen como ruta alternativa, con el objetivo de contar con un modo que funcione en casi cualquier conexión de Internet del mundo.
Soy uno de los desarrolladores principales de https://gitlab.com/openconnect/openconnect, que implementa varios protocolos VPN basados en TLS, y también creé https://github.com/dlenski/what-vpn, que detecta e identifica más tipos de servidores VPN basados en TLS.
Hace tiempo, el proveedor de Internet neerlandés XS4ALL ofrecía exactamente esta función.
Permitía conexiones SSH por el puerto 80, y me ayudó varias veces cuando, durante viajes, el WiFi de un hotel bloqueaba todo salvo el puerto 80.
Aunque, desde el punto de vista de KPN, supongo que la cultura hacker de XS4ALL nunca le resultó cómoda.
Se sentía como una recreación de la cultura de la radio pirata de los años 60.
https://en.wikipedia.org/wiki/Pirate_radio_in_Europe
https://www.shodan.io/search/facet?query=ssh&facet=port
https://www.shodan.io/search/facet.png?query=ssh&facet=port
En cambio, el puerto 80 es mucho menos común.
Recuerdo haberlo usado antes solo como proveedor de grupos de noticias.
También suele haber una tercera opción: levantar SSH en el puerto 80 o 443 de otro host y desde ahí usar ProxyJump hacia el destino.
O también puedes abrir SOCKS hacia ese host para obtener una conexión a Internet menos filtrada en general.
Yo uso SOCKS, y también paso DNS basado en TLS mediante port forwarding de la conexión SSH.
Hace algunos años, cuando configuré por primera vez un proxy SOCKS y usé bastante WiFi, no encontré lugares que hicieran algo más que revisar puertos, pero esos equipos existen y quizá ahora sean más comunes.
Así que simplemente me conectaba por SSH a mi servidor y lo usaba como siempre.
Más tarde, cuando armé un archivo de imágenes
.isode Windows, las descargué en la laptop y las subí al servidor conscp; al parecer, usar decenas de GB entre subida y descarga por un puerto que no era 80/443 fue suficiente para disparar una inspección de tráfico, porque alrededor del almuerzo TI bloqueó el puerto 22.Pero como no bloquearon otros puertos, moví SSH al 443 con port forwarding y seguí usándolo.
Después el equipo de TI de la escuela se dio cuenta de que estaba usando SSH en el 443 y agregó un análisis de tráfico básico para bloquear SSH en 80/443, pero todos los demás puertos seguían abiertos.
Al final bloquearon mi servidor por IP, pero todas las demás IP seguían abiertas.
Con un VPS y ProxyJump podría saltármelo, pero como era un programa de preparatoria con inicio temprano de universidad, después del segundo año casi no iba a la escuela, así que no valía mucho la pena el esfuerzo.
La próxima vez que vaya pienso intentarlo solo para demostrar que se puede, y si bloquean SSH en todos los puertos, bastaría con levantar SSH sobre HTTPS en el VPS.
Después de graduarme pienso revisar de nuevo hasta dónde se puede llegar desde el WiFi de invitados.
Es un poco de promoción descarada, pero en Adaptive [1] estamos construyendo infraestructura de seguridad de datos.
En uno de los productos, transportamos SSH y varios otros protocolos sobre HTTP/3 para que los usuarios puedan conectarse a bases de datos, servidores y otros recursos usando un único puerto saliente.
Es parecido a Ngrok y similares, pero se puede autoalojar, permite acceso sin contraseña o agregar credenciales temporales y protección maker-checker.
[1] https://adaptive.live/
En la práctica, con solo hacer que
opensshescuche en el puerto 443 ya se podía eludir la mayoría de los firewalls.Está bueno. Curiosamente, nunca había pensado en el método
CONNECTcomo si fuera un proxy inverso, en vez de un proxy directo.Pero en mi caso
CONNECTno era suficiente, así que usé SSH sobre WebSocket para atravesar el proxy corporativo.Ese proxy inspeccionaba conexiones HTTPS con una CA personalizada.
Modifiqué
socatpara ofrecer mi servidor SSH vía WebSocket a través de Apache, y del lado del cliente lo usé conProxyCommandde OpenSSH.Sigo pensando que debería publicar ese parche, pero también hay otras opciones como
websocat.Hace casi 20 años usé una herramienta llamada corkscrew[0], que hacía exactamente esto, para intentar abrir un agujero en el firewall de la empresa
La implementación independiente y el artículo están prolijos
0: https://github.com/bryanpkc/corkscrew
corkscrewsolo funciona bajo ciertas condiciones: estar detrás de un proxy HTTP, y que ese proxy HTTP admita el métodoCONNECTCuando hice un contrato corto hace unos 20 años, se cumplía la primera condición, pero no la segunda
Por suerte, hay herramientas que sirven incluso en ese caso, aunque por supuesto requieren configuración del lado del servidor
https://github.com/larsbrinkhoff/httptunnel
En general, el tunneling a través de HTTP/2 resultó ser una buena opción
gRPC[1] es un protocolo de llamadas a procedimientos remotos construido sobre HTTP/2
Esto se debe a que HTTP/2 es fuerte en multiplexación, usando una sola conexión TCP para enviar y recibir simultáneamente varias estructuras de datos
Sin embargo, como QUIC ya ofrece multiplexación por sí mismo, quizá no haya razón para usar HTTP/3
En adelante, parece que la mayor parte de las comunicaciones pasará por HTTP/2 cifrado y QUIC, porque los fabricantes de equipos intermedios no pueden dejar de discriminar el tráfico
Para mitigar el sondeo activo[2], quizá haya que servir contenido HTTP/2 y HTTP/3 aleatorio, tal vez generado por IA
[1] <https://grpc.io>
[2] <https://blog.torproject.org/learning-more-about-gfws-active-...>
HTTP en sí ya es un protocolo de solicitud/respuesta y, básicamente, puede usarse para llamadas a procedimientos remotos
No parece haber gran diferencia entre HTTP 1, 2 o 3
La propia evolución de ese protocolo también me resulta algo sospechosa, y en parte está diseñada para aprovechar cosas que no hacen falta en un entorno de llamadas a procedimientos remotos
En esencia, parece más algo diseñado para la Internet pública que para servicios locales
HTTP/3 funciona sobre QUIC
Yo prefiero lo contrario: HTTP sobre SSH
Lo digo medio en broma, pero estaría bueno que los navegadores tuvieran integrada una gestión de identidad equivalente a la de SSH
Me entusiasmé cuando leí por primera vez hobo, una propuesta de autenticación HTTP con clave pública, pero luego descubrí que no había implementación de servidor ni implementación de cliente en navegadores
Hay una implementación en JavaScript, pero no era lo que quería
ssh -D “*:8080” hostEste comando levanta un proxy SOCKS en el puerto 8080
Lo uso siempre en Firefox, y funciona como una especie de VPN de la vieja escuela
También es cómodo para usos sospechosos, pero lo uso además para acceder al panel de rmq en una red privada de AWS
https://techcommunity.microsoft.com/t5/iis-support-blog/clie...
No conozco el tema con suficiente detalle como para saber si encaja con los requisitos, pero los usé para autenticación de servidor en la universidad
ssh://google.comhttps://news.ycombinator.com/item?id=38664729
¿Por qué
sslhno recibe más cariño?Detecta HTTP, TLS/SSL (incluidos SNI y ALPN), SSH, OpenVPN, tinc, XMPP, SOCKS5, y también puede reconocer otros protocolos que se puedan inspeccionar con expresiones regulares
El uso típico es ofrecer varios servicios juntos en el puerto 443
Por ejemplo, podés conectarte por SSH desde detrás de un firewall corporativo y, al mismo tiempo, seguir ofreciendo HTTPS en el mismo puerto
https://www.rutschle.net/tech/sslh/README.html
sslhy la encapsulación completaParece que eligió la encapsulación completa porque hay un servicio menos que configurar, porque el servidor HTTP maneja la conexión y por eso la dirección remota en los logs es correcta, y quizá porque, por espíritu hacker, prefiere una solución nueva antes que una ya existente