Olvídate de ngrok: expongo servicios locales con el OpenSSH que ya tengo corriendo

Olvídate de ngrok: expongo servicios locales con el OpenSSH que ya tengo corriendo

Olvídate de ngrok: expongo servicios locales con el OpenSSH que ya tengo corriendo

Vive conmigo una escena que ya me aburrió: un servicio corriendo en un puerto local de algún server de mi flota — un dashboard, un webhook de pruebas, una app a medio armar — y la necesidad de mostrárselo a alguien que no está en la misma red. La respuesta automática de siempre es instalar ngrok, o un tunnel de Cloudflare, o frp, o localtunnel. Y yo llevo un tiempo pensando que es puro autoboicot: todo lo necesario ya está instalado en el servidor.

El truco: un reverse forward y un nginx con regex

La pieza clave es ssh -R 0:localhost:PUERTO. El 0 le dice al servidor remoto que asigne él mismo un puerto libre, así ningún forward choca con otro servicio. A partir de ahí, el resto es config pura: en nginx una directiva server_name con regex que capture el número de puerto del subdominio (p41535.tudominio.cl, por ejemplo), un proxy_pass a 127.0.0.1:puerto, y listo.

Dos detalles hacen que esto funcione de verdad. El primero: DNS wildcard (*.tunel.tudominio.cl apuntando al mismo server). El segundo: certificado wildcard de Let’s Encrypt, que se saca con validación DNS-01, no HTTP, precisamente porque el subdominio cambia con cada túnel. Si usas Caddy — como yo en varios de mis servers — es todavía más simple: el on_demand_tls emite el certificado cuando llega la primera conexión y se olvida solo.

En OpenSSH además puedes fijar GatewayPorts y restringir qué usuarios pueden hacer forwards, que es algo que casi nadie revisa y que deja tu authorized_keys como única llave de la puerta.

Ahora la parte incómoda: la seguridad

Aquí es donde la mayoría del rango me incomoda un poco. Un túnel expuesto a internet donde el único secreto es el número de puerto es un escaneo de nada. Existe ngx_http_secure_link_module, que genera un hash sobre puerto + expiración + un secreto, y se manda como usuario de HTTP Basic en la URL. No es bonito, pero funciona con cualquier cliente: curl, un navegador, lo que sea. Puedes ponerle expiración al link — un día de vida, por ejemplo — y que el túnel muera solo. Sin panel, sin app extra, sin cuenta en ningún lado.

La pregunta que quiero plantear no es ngrok contra nginx. Es otra: ¿cuántas herramientas nuevas estás dispuesto a cargar por algo que tu stack actual ya resuelve?

La regla de oro de mi self-hosting

Todo lo que instalo hoy es algo que voy a tener que parchar el resto de mi vida. Cada herramienta extra con su propia config, sus credenciales propias, su propio daemon escuchando. Y cada daemon es un problema esperando CVE. Aprender a explotar lo que ya corre es, honestamente, más difícil que curl -fsSL https://get.ngrok.io | sh. Ese fue el argumento real por el que me demoré en cambiar de hábito: no era capacidad, era flojera.

Ahora uso esto para todo: previews de blogs antes de publicar, webhooks que no quiero exponer permanente, sesiones de debug de apps internas. El mismo túnel, el mismo patrón, cero software nuevo. Si el post es para un partner de trabajo, genero hash con expiración de unas horas y lo mando por privado. Nadie puede forzar la URL si esa persona borra el mensaje y se termina la expiración.

Y una advertencia final que no escatimaré: lo que va por estos túneles viaja cifrado por SSH hasta el server, pero esos servers ahora son la superficie atacable. Si tu cae una llave SSH comprometida, te acaba de abrir la puerta a todo lo que esté detrás. Igual que toda la idea self-hosting, el control lo ganas tú, pero también la responsabilidad es tuya.

Cierre

La próxima vez que sientas la tentación de instalar una herramienta más para hacer passthrough de HTTP, pregunta primero qué hay en ssh -R. La respuesta siempre es la misma que te da tu abuelo: usa lo que ya tienes, y hazlo bien. Tu server — y tu factura de servicios cloud que nunca usas — te van a agradecer.

Fuente que me inspiró este post: Self-hosted HTTP tunnels with SSH and nginx, del blog de Vincent Bernat.

Fuente de inspiración: Self-hosted HTTP tunnels with SSH and nginx

Comentarios

Aún no hay comentarios. ¿Por qué no comienzas el debate?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *