Reverse SSH Tunneling

Posted on Posted in linux, seguridad

Que es el Reverse SSH Tunneling?, básicamente se trata de realizar una conexión del equipo A –> B y poder usar esta conexión de forma inversa, es decir conectarte del equipo B –> A, saltándose así el Firewall que bloquea la conexiones ssh entrantes. Puede ser muy util como VPN casero, ya que la transmisión se realiza de forma cifrada.

Imaginemos que por ejemplo queremos conectarnos al puesto de trabajo, pero lógicamente la conexión ssh a tu equipo esta bloqueada, pero la conexión ssh hacia el exterior está abierta, pues bien,  podrías dejar una conexión abierta desde tu puesto de trabajo a un equipo personal y después desde la comodidad de tu casa conectarte a tu puesto de trabajo usando está conexión.

Para llevar a cabo esta tarea:

Conexión OFICINA–>CASA

Para crear el tunel usaremos la siguiente sentencia:

nohup ssh -f -N -R 10000:localhost:22 <server_username>@<pc-casa>

Siendo -R la opción Reverse y 10000:localhost:22 el puerto que crearemos en el servidor de casa para realizar la conexión de forma inversa.

Conexión CASA –> OFICINA

Ahora usaremos la conexión establecida para conectarnos a la oficina:

ssh -p 10000 <client_username>@localhost

Como vemos usamos la conexión que hemos creado previamente 😉

Script SSH-REVERSE-TUNNELING

Tenemos una herramienta bastante útil que nos puede facilitar la tarea a la hora de mantener un Tunel SSH durante tiempo indefinido.

ssh_reverse_tunnel script –> http://danielwebb.us/software/ssh-reverse-tunnel/

ssh_reverse_tunnel.sh

Este script nos permite establecer una conexión ssh a nuestro servidor de casa de forma automática, manteniendo la conexión en caso de des-conexión, cada X tiempo chequea si la conexión está establecida y si no es así la restablece. Pudiendo así conectarnos a nuestro cliente desde nuestra casa.

Instalación

Lo único que tenemos que hacer es descargarnos el script de la dirección anterior e instalarlo:

tar xvfz ssh-reverse-tunnel_0.5.3.tar.gz
cd ssh-reverse-tunnel_0.5.3
make install
configuración

Lo siguiente será configurar el fichero de configuración que usará este script para realizar la conexión a nuestro servidor de casa, para ello copiamos el archivo que trae el instalador:

cd ssh-reverse-tunnel_0.5.3/examples
cp -pr ssh-reverse-tunnel.conf /etc/

vim /etc/ssh-reverse-tunnel.conf:

  • REVERSE_PORT_LIST: Puerto inverso que se creará en el servidor y que nosotros usaremos para conectarnos al cliente.
  • SERVER_USER: Usuario con el que realizaremos la conexión, el cual tendrá la clave publica del cliente para que así no haga falta introducir la contraseña-
  • SERVER_HOST: Servidor al que nos vamos a conectar.
  • CLIENT_USER: Usuario Cliente con el que lanzamos el script, tiene que ser el mismo que el de inicio de sesión
  • CLIENT_HOST: Client HOSTNAME, es decir nombre de la máquina cliente.
#
#verbose output
VERBOSE=true
# Allow remote commands (commands place on the server but executed on the client)
REMOTE_COMMANDS=false

# Ports to reverse forward
REVERSE_PORTS_LIST=2222:localhost:22
# Example of multiple ports (first forwarded port must go back to ssh server on client):
# REVERSE_PORTS_LIST="2222:localhost:22 2223:localhost:23"

# User on server machine
# Usuario con el que el cliente se intentara conectar
SERVER_USER=ssh_server_user

# Server hostname (from the client's point of view)
SERVER_HOST=ssh_server_machine

# The alias for client using the reverse forwarded server port
# (if you just use "localhost" RSA host keys will clash)
SERVER_HOST_CLIENT_ALIAS=localhost

# Server SSH port
SERVER_SSH_PORT=22

# Client user
# Tiene que ser el mismo que el de iniciod e sesion
CLIENT_USER=ssh_client_user

# Client host (from the server's point of view)
# Nombre de la maquina cliente
CLIENT_HOST=ssh_client_machine

# Extra options to pass to ssh in server mode
SSH_EXTRA_SERVER_OPTIONS="-x"

SSH_EXTRA_CLIENT_OPTIONS="-x -o TCPKeepAlive=yes"

# Time to wait when trying to create a connection to server in client mode
CLIENT_MODE_TIMEOUT=20

# Time to wait when trying to create a connection to client in server mode
SERVER_MODE_TIMEOUT=20

# -------------------------------------------------------------------------
# PPP VPN options (set VPN=true to use the PPP VPN instead of SSH port forwarding
# -------------------------------------------------------------------------
VPN=false

# The pppd IP address on the client side of the VPN tunnel
CLIENT_VPN_ADDRESS=192.168.88.10

# The pppd IP address on the server side of the VPN tunnel
SERVER_VPN_ADDRESS=192.168.88.1

# The command to run pppd on client and server
CLIENT_PPPD_COMMAND="pppd"
SERVER_PPPD_COMMAND="sudo pppd"
intercambio de claves:

Si la tenemos creada:

cat .ssh/id_rsa.pub

Y sino la creamos, no introduciremos password

ssh-keygen

Ahora la copiamos al “.ssh/authorized_keys” del usuario “SERVER_USER”, es decir establecemos una conexión ssh al servidor e introducimos el contenido del fichero “id_rsa.pub” del cliente que va a realizar la conexión.

Ahora probamos si la conexión se realiza de forma automática, volvemos a realizar un ssh al servidor con el usuario “SERVER_HOST” y si todo es correcto NO nos tiene que pedir password, si nos lo pidiera algo no hemos realizado bien.

Si todo es correcto probamos el script:

ssh-reverse-tunnel client

Lo que tiene que hacer es establecer una conexión con el servidor de casa (SERVER_HOST) y creará una conexión inversa en el puerto configurado

tcp        0      0 127.0.0.1:2222          0.0.0.0:*               LISTEN      22380/sshd: sshfals
tcp6       0      0 ::1:2222                :::*                    LISTEN      22380/sshd: sshfals

Así desde el equipo de casa podremos conectarnos al cliente:

ssh CLIENT_USER@localhost -p 2222
automatización

En el Cliente

Por último nos queda programar la ejecución de este script, cada 2 minutos, por ejemplo, este chequeará si la conexión esta establecida, si lo estuviera no llevaría a cabo ninguna tarea, sino lo estuviera volvería a crear la conexión.

crontab -l
#################################
# m h  dom mon dow   command
*/2 * * * * /usr/local/bin/ssh-reverse-tunnel client

En el Servidor

Probando esta herramienta me he dado cuenta que en muchas ocasiones el tunel se queda “congelado”, es decir, la conexión está establecida así como el puerto inverso escuchando, pero a la hora de conectarte no obtienes respuesta del cliente.

Para solucionar esto me he creado un script que revisa el estado del tunel y si no es correcto lo restablece. Básicamente los pasos que realiza son:

  1. Comprueba que el cliente responde
  2. Si no responde en 10 seg, crea un fichero llamado .ssh-reverse-tunnel.restart.$CLIENT_HOST, el cual el cliente comprueba, y si existe realiza un restart de la comunicación. Desbloqueando así la comunicación.
#!/bin/sh

### Script que comprueba si el tunel está vivo, si no es así lo revive

PUERTO="2222"
USUARIO="snaider"
SSH="/usr/bin/ssh"
TOUCH="/usr/bin/touch"
USER_TUNEL="sshfalse"
BASE="/home/$USER_TUNEL"
CLIENT_HOST="snaiderclient"
RESTART=".ssh-reverse-tunnel.restart.$CLIENT_HOST"
CONDICION="$SSH -o ConnectTimeout=10 $USUARIO@localhost -p $PUERTO exit"
PROCESO=`ps aux | grep -c "live_tunneling.sh"`
LOG="/var/log/tunneling"

# COMPROBAMOS SI YA ESTA EN EJECUCION

if [ $PROCESO -gt '4' ]; then
	{
	exit
	}
fi

while true
do
{
	DATE=`/bin/date`
	if $CONDICION; then
		echo "$DATE ---- IT'S LIVED" >> $LOG
  		sleep 15
	else
		echo "************************************************" >> $LOG
		echo "WARNING TUNEL DOWN" >> $LOG
		echo "$DATE" >> $LOG
		echo "************************************************" >> $LOG
		$TOUCH $BASE/$RESTART
		echo "RESTART FILE CREATED" >> $LOG
		echo "WAITING 15sec" >> $LOG
		echo "+++++++++++++++++++++++++++++++++++++++++++++++" >> $LOG
		sleep 15
	fi
}
done

Leave a Reply

Your email address will not be published. Required fields are marked *