Acceder a un terminal mediante SSH inverso

Una de las cosas mas útiles que he deseado tener disponible, es el acceso SSH a mi computadora persona, desde cualquier parte del mundo. He conocido herramientas como ngrok y localtunnel que sirven, mas o menos, para lo que necesito, pero quería intentar con una herramienta que no dependa de servidores externos y ajenos a mi poder, sea porque no quiero compartir mis datos con terceros, o porque simplemente quería aprender a hacerlo por mi mismo.

Luego de mucho investigar, he encontrado algo que existe desde hace mucho tiempo y que probablemente es conocido por todo el mundo, pero recién aprendí a hacerlo por mi cuenta; SSH permite hacer túneles inversos.

Esquemas de control remoto

Desde el periodo de confinación por el COVID-19, todo tipo de servicios se hicieron sumamente populares, como zoom para las conferencias, y AnyDesk para trabajo remoto.

Aunque es de conocimiento común, se puede controlar un equipo utilizando el modelo Cliente-Servidor, donde el cliente se conecta al servidor y el servidor responde a sus peticiones.

Modelo Cliente-Servidor
Modelo Cliente-Servidor

En este modelo, el equipo a controlar debe ser el servidor, es decir, debe mantenerse escuchando para poder responder las peticiones del cliente, es decir, el controlador.

Este modelo es sencillo si hay conexión directa entre el cliente y el servidor, por lo que se puede utilizar la siguiente combinación de programas para el acceso remoto:

  • SSH – SSHd Acceso mediante consola (y montones de trucos mas).
  • RDP/XRDP – Escritorio remoto de Windows/Remina(Linux) Acceso mediante escritorio remoto usando el protocolo RDP de Windows.
  • Vino-Vinagre Acceso mediante VNC que admite múltiples sistemas operativos.

El problema entonces es que todo esto funciona en una red local, pero no a través de internet.

La gran nube

La red de redes
La red de redes

Podríamos definir a internet como la red que une a muchas redes pequeñas mediante un mapa de rutas complejas trazado por algoritmos aun mas complejos de entender.

Inicialmente, los proveedores de internet buscan conectar un solo dispositivo a internet, pero en una casa, esto no es lo ideal. Hay muchos dispositivos y cada día parecen haber mas, por lo que una sola conexión no abastecería.

Para solucionar esto, se crea una pequeña red local mediante routers que guiaran todas las conexiones hacia el exterior.

Es probable que por seguridad el proveedor de internet haya limitado las conexiones del router a solo salientes, por lo que no hay forma de conectarse desde afuera.

También es probable que el mismo proveedor haya creado una infraestructura compleja de subredes anidadas que dificultan aun mas encontrar el camino hacia un equipo en especifico desde el exterior. Casi cualquier dispositivo que no esté en la red local, estará en la misma situación, por lo que la comunicación entre ambos es virtualmente imposible.

La Solución

Internet es una maraña de dispositivos conectados, pero si alejamos lo suficiente nuestra perspectiva, nos daremos cuenta de que en realidad, parece una gigantesca red local.

Esto significa que es posible conectarse a algún nodo que tenga conexión directa y publica a internet, utilizando lo que es llamado IP Pública

Algunos proveedores de internet ofrecen el servicio de IP publica a sus clientes, por lo que ajustando algunas configuraciones en el router, ya se puede acceder desde cualquier parte del mundo a nuestro equipo, pero esto es innecesariamente peligroso, por cuanto internet es un lugar plagado de atacantes buscando vulnerabilidades en cada IP que puedan encontrar.

Para resolver esto y evitarle a los clientes todo tipo de pesadillas, las empresas proveedoras de servicios de control remoto, crearon servidores de conexión inversa, que sigue un modelo de Cliente – Servidor – Cliente.

Modelo Cliente Servidor Cliente
Modelo Cliente Servidor Cliente

Para este ejercicio, vamos a imitar el modelo que utilizan las grandes empresas y crearemos un puente para alcanzar algún equipo de nuestra red local, desde cualquier parte de internet.

Desarrollo de la Solución

Aunque técnicamente se puede realizar con solo dos dispositivos, lo mas común es que se necesiten tres, así que enumeraremos los requisitos a continuación:

  • Dispositivo de destino: Se encuentra aislado en una red local. y es incapaz de recibir conexiones entrantes debido a la configuración de su red y su proveedor de internet, pero puede ejecutar conexiones salientes a cualquier parte de internet.
    • Servidor SSH Puede ser cualquiera, como OpenSSH o Dropbear. Nota importante: el dispositivo debe tener instalado algún servidor SSHd. He hecho pruebas con termux en Android y, aunque tiene uno, su problema esta relacionado con que no permite el login de usuario y contraseña, para lo cual se deben usar otros métodos de autenticación.
    • Cliente SSH Puede ser cualquiera.
  • Servidor: Se encuentra en un lugar accesible de internet y permite conexiones entrantes o salientes libremente. Generalmente es un servidor, pero puede ser cualquier dispositivo mientras tenga una IP pública.
  • Dispositivo de salida: Generalmente está en la misma situación que el dispositivo de destino, pero en otra red. lo importante es que tenga conexión saliente hacia el servidor.

Seguramente ya dispones de los dispositivos de destino y de salida, pero el servidor es algo menos probable, así que, por que no arriesgarse con un droplet de Digital Ocean?

DigitalOcean Referral Badge

Utilizando este enlace puedes crear una cuenta con un crédito inicial de 100 dólares, totalmente sin costo durante 60 días. Úsalo para aprender y practicar con servidores Linux y cuando se acabe el periodo de prueba, puedes comprar Droplets desde 5 dólares mensuales. Recuerda administrar responsablemente tus VPS para evitar sorpresas al final del mes.

Ahora vamos a empezar a aplicar la configuración de los distintos dispositivos implicados:

Dispositivo de Destino

Este dispositivo, que se encuentra atrapado en una red que no permite conexiones entrantes, va a permanecer conectado todo el tiempo al servidor para que el túnel se mantenga vivo. Eso significa que la ventana del terminal tendrá que mantenerse abierta en todo momento o de lo contrario el túnel morirá.

En las aplicaciones de control remoto esto también sucede, pero es mas transparente al usuario debido a que utilizan servicios para mantener vivo el cliente y revivir el túnel cada que sea necesario. En nuestro caso se puede realizar algo similar, enviando la conexión al fondo mediante screen u otras herramientas.

En el dispositivo de destino, hay que escribir lo siguiente

ssh -R 16789:localhost:22 usuario@servidor

donde:

  • ssh Inicia la aplicación de shell segura.
  • -R 16789:localhost:22 vincula un puerto arbitrario(de nuestra elección) en el dispositivo de destino, al puerto 22 del servidor SSHd.
    • 16789 es un puerto arbitrario, es decir, podemos poner cualquiera, siempre que sea un puerto libre en nuestro equipo.
    • localhost o 127.0.0.1 es la dirección local de nuestro dispositivo.
    • 22 es el numero del puerto al que vamos a redirigir la conexión entrante. En este caso, es el puerto de SSHd.
  • usuario@servidor
    • usuario Es el nombre del usuario existente en el servidor al que nos vamos a conectar y utilizar de puente.
    • servidor Es el nombre de dominio o dirección IP del servidor al que nos estamos conectando.

Al ejecutar este comando, se abrirá una conexión con el servidor, que deberás mantener viva tanto como quieras acceder por el túnel inverso. Por supuesto, mientras estas en ese túnel, puedes usar libremente al servidor como si fuera una conexión normal.

Dispositivo de salida

Puede parecer raro comenzar por el dispositivo de salida, pero asumiremos que en el servidor ya está SSHd bien configurado.

En el dispositivo de salida deberás acceder al servidor con una conexión normal de SSH

ssh usuario@servidor

Donde:

  • ssh Es el comando de la consola segura
  • usuario@servidor
    • usuario Es el usuario del servidor
    • servidor Es el nombre de dominio o la dirección IP del servidor

Una vez que haya una sesión iniciada en el servidor, debemos ejecutar este comando y tendremos acceso a la consola del dispositivo de destino.

ssh usuario@localhost -p 16789

Donde:

  • ssh Es el comando de la consola segura.
  • usuario@localhost Es el usuario del dispositivo de destino.
    • usuario es el usuario del dispositivo de destino.
  • -p 16789 Es el puerto que abrimos en el dispositivo de destino.

Si queremos acceder a nuestro dispositivo de destino, hemos de dejar encendido el túnel, pero una falla de la red podría causar que la conexión se cierre. Al no estar cerca del equipo para restaurar la conexión, no podremos revivir el túnel hasta que volvamos presencialmente a restaurarla, así que lo recomendable es utilizar una herramienta que reviva el túnel cada que sea necesario o utilizar un cliente que pueda mantener conexiones persistentes a pesar de los quiebres de red.

Mientras tanto, se pueden utilizar sin problema los demás protocolos que funcionan sobre SSH, como SFTP o SCP por ejemplo.

Eso si, hay que recordar que para conectarse, hay que usar el puerto arbitrario que hemos definido anteriormente.

SFTP:

 sftp -oPort=16789 usuario@localhost

SCP

scp -p -P 16789 /tmp/ssh.txt usuario@localhost:

Hay muchas dudas que me quedan pendientes pero las iré estudiando conforme vaya necesitando mas cosas, pero tener este túnel es algo interesante para practicar.

Bibliografía/Webgrafía

Conexión a servidor mediante túnel inverso ssh Obtenido de https://openwebinars.net/blog/conexion-servidor-mediante-tunel-inverso-ssh/

Túnel inverso. Obtenido de :https://mundo-hackers.weebly.com/tuacutenel-inverso-ssh.html

Creación de túnel inverso. Obtenido de https://campusvirtual.ull.es/ocw/pluginfile.php/2172/mod_resource/content/0/perlexamples/node48.html

A %d blogueros les gusta esto: