Túneles inversos en ssh
Un túnel inverso es una técnica que permite a un cliente SSH establecer una conexión segura desde un servidor remoto a tu máquina local. Se suele utilizar cuando la máquina local está detrás de un firewall, o un NAT, o cualquier motivo por el cual esta no es accesible directamente desde el exterior.
Funciona estableciendo una conexión inversa desde el cliente (máquina local) con el servidor SSH (remoto). Para ello se asigna un puerto en el servidor remoto que redirige las peticiones a un puerto específico en la máquina local. Cualquier conexión entrante al puerto en el servidor remoto se envía a través del túnel al puerto en la máquina local.
Es imprescindible para esto contar con una máquina de la red local o algún servidor externo con ssh que tenga expuestos los puertos a internet.
Configuración ssh
Para que ssh permita crear túneles inversos hay que modificar una opción en la configuración del servicio que por defecto suele estar comentada. En el caso de debian o derivados, la configuración ssh se encuentra en el archivo:
/etc/ssh/sshd_config
La opción a modificar es
#GatewayPorts no
La cual debemos descomentar y modificar, quedando de la siguiente forma:
GatewayPorts yes
Comando para la creación de un túnel inverso:
ssh -R PuertoRemoto:IpLocal:PuertoLocal usuario@ip
- -R: Esta opción indica que se está configurando un túnel inverso. Permite que un puerto en el servidor remoto redirija el tráfico hacia un puerto en la máquina local.
- PuertoRemoto: Es el número de puerto en el servidor remoto donde se escucharán las conexiones. Cualquiera que se conecte a este puerto en el servidor podrá acceder al servicio de la máquina local.
- IpLocal: Es la dirección IP de la máquina local que tiene el servicio que deseas exponer. Usualmente, puedes usar localhost si el servicio está en la misma máquina donde inicias el túnel.
- PuertoLocal: Es el número de puerto en la máquina local donde el servicio está escuchando. Esto es lo que se redirigirá a PuertoRemoto en el servidor.
Primer ejemplo
Supongamos que necesito compartir una carpeta con archivos desde mi Windows, el cual no tiene puertos abiertos a internet. Para ello voy a conectarme por ssh a mi raspberry que sí los tiene, y crear un túnel inverso.
En primer lugar configuro en mi router una regla de reenvío de puertos para que el 5555/tcp se reenvíe a la ip de mi raspi (192.168.1.85
En mi caso particular utilizo un firewall en la raspberry, por lo que debo activar en ella el puerto con el comando:
sudo ufw allow 5555/tcp
Si la carpeta de Windows llamada canciones con los archivos que quiero compartir se ubica en la raíz de la unidad C, debería crear un server local con python ejecutando el siguiente comando en CMD:
python -m http.server 88 --directory "C:\canciones"
Este comando Python inicia un servidor HTTP en el puerto 88, sirviendo los archivos desde el directorio C:\canciones, y permitiendo que se acceda a ellos a través de un navegador web. Por lo que si desde algún navegador accedo a la url:
http://localhost:88
Debería tener acesso a los archivos. Sigamos con el siguiente paso.
Voy a utilizar otra ventana de CMD y crear el túnel remoto con el siguiente comando:
ssh -R 5555:localhost:88 gera@192.168.1.85
Y eso es todo. Ahora desde el dominio o la ip pública de mi red especificando el puerto 5555, Cualquier persona tendrá acceso a los archivos alojados en una carpeta de Windows que no tiene salida directa a internet.
Conexión con otro dispositivo de la red:
Audiomemos es una grabadora de audio que utilizo en IPhone que permite descargar los archivos, entre otras formas, creando un servidor local. En el apartado información muestra la ip y el puerto, por ejemplo:
192.168.1.44:8080
Por lo que utilizaremos el siguiente comando para establecer el túnel inverso y permitir una conexión externa:
ssh -R 5555:192.168.1.44:8080 gera@192.168.1.85
Aquel que acceda al dominio o IP pública de mi red, especificando el puerto 5555, tendrá acceso a los archivos del IPhone.
Como aconsejo en el post sobre montar un servidor apache... es conveniente tomar precauciones de seguridad con el uso de conexiones remotas por ssh. Utilizar claves en lugar de contraseñas, cambiar los puertos por defecto, y otras acciones recomendadas para evitar intrusiones no deseadas que puedan comprometer los datos.