lunes, 5 de diciembre de 2011

X Forwarding y túneles ssh


Puff, ya hacía tiempo que no posteaba. Mucho lío , poco tiempo , muchas cosas... o una combinación de todas.
Bueno pues voy a hablar del forwarding de X en sesiones ssh, cosa que más de una vez me ha "salvado la vida".

Tunelizando conexiones a servidor X


Cuando necesitemos acceso a otra máquina y hacer uso de herramientas gráficas, pero sólo podemos acceder vía ssh, podemos usar un túnel ssh y a través de la conexión  hacer  forwarding, de modo que las aplicaciones ejecutadas en la máquina remota tengan acceso al servidor X local.

El mecanismo es el siguiente:

Para establecer la sesión ssh con túnel para las x, ejecutaremos

ssh -X <host_remoto>  (*)
login: userx
Password:
Have a lot of fun...
/usr/bin/xauth:  creating new authority file /home/userx/.Xauthority
userx@server>$

(*) Si no inidcamos la opción -X, debemos tener habilitado el forwading  del servidor local de X (ForwardX11 yes) en el fichero de configuración del cliente ssh (/etc/ssh/ssh_config)

Con esto, el  cliente ssh local genera una cookie de autenticación y la envía al servidor ssh remoto que añadirá al fichero $HOME/.Xauthority de la máquina remota en la conexión.

El servidor remoto, abre el socket TCP 6010 en modo escucha. Además, inserta en el entorno del usuario que se logea la variable de entorno DISPLAY=localhost:10.0. En el caso de que el socket estuviese ya ocupado, asignará el siguiente (TCP 6011) y la correspondiente variable de entorno DISPLAY=11.0 y así sucesivamente.

Observemos la siguiente salida de netstat que nos muestra el estado de los sockets LISTEN en la máquina remota:

Sockets Listen en la máquina remota




Conexiones establecidas
Tenemos que:

Se crea una conexión ssh entre la máquina local 10.70.4.11 y la remota 10.70.4.4.  En la máquina remota se lanza una aplicacion gráfica (iceweasel). Esta  leerá la cookie del fichero $HOME/.Xauthority e iniciará una conexión TCP al socket local que corresponda, en este caso el 6010. El cliente recibirá la cookie y comprueba que, efectivamente, es la que él generó inicialmente. A continuación establece una conexión con el servidor X local. A partir de este momento el túnel está establecido.

En este ejemplo la sesión que abrió el socket 6010 y se  ejecutó iceweasel:

userx@server>$ pstree 15094
sshd----bash----iceweasel-----22*[{iceweasel}]

Conexión al servidor X. Tipos

La conexión de una aplicación al servidor X puede realizarse por varios métodos. En GNU/Linux los métodos son socket local (socket Unix)  y TCP. Es la aplicación cliente la que escoje el protocolo y la localización del servidor con la variable DISPLAY o bien con la opción --display.
En el caso de usar socket unix local , la variable DISPLAY será un signo de dos puntos seguido del número de display, generalmente 0 (aunque puede ser distinto si se ejecutan varios servidores de X). Opcionalmente puede añadirse un punto y número de pantalla (también suele ser cero salvo que el servidor X controle varias pantalllas) .Entonces DISPLAY tomará generalmente el valor :0 (o :0.0). El socket local se creará en /tmp/.X11-unix/Xn siendo n el número de display:

linux:/etc/ssh # ls -l /tmp/.X11-unix/
total 0
srwxrwxrwx 1 root root 0 Dec  5 10:53 X0

Cuando la conexión es por socket TCP, DISPLAY será el hostname o IP del servidor X seguido de dos puntos y el número de display. Al igual que antes puede añadirse punto y el numero de pantalla. Por ejemplo en una conexión local pero por TCP el valor será DISPLAY=localhost:0. El puerto TCP mas usado es el 6000 mas el número de display.
Téngase en cuenta que las comunicaciones con el servidor X no están cifradas por lo que si se usa TCP las comunicaciones pueden monitorizadas. Es por ello que GNU/Linux no permite la conexión al servidor X por TCP. Esto puede comprobarse observando el parámetro -nolisten tcp en el proceso X:

linux:/etc/ssh # ps -ef | grep X

root      4177  4163  0 10:53 tty7     00:00:07 /usr/bin/X :0 -br -verbose -auth /var/run/gdm/auth-for-gdm-APoml7/database -nolisten tcp vt7 

Nota: En el ejemplo, la conexión de la aplicación cliente (en la máquina remota) se conecta al servidor X a través de un túnel ssh, con lo cual realmente el puerto TCP 6010 (6000 + 10 display) remoto está redirigido al túnel ssh y  la conexión al servidor X local a través de él

No hay comentarios:

Publicar un comentario