Hace tiempo que empleo túneles para poder acceder a ciertos servicios inaccesibles desde Internet, o para agregar seguridad a un acceso determinado. Esto es posible gracias a los túneles que se pueden crear con la herramienta OpenSSH.
Los túneles son conexiones cifradas (ya sea mediante SSL o TLS) que permiten enviar datos de un punto a otro de Internet (o de una red en general) sin que pueda ser vista dicha comunicación. La encriptación se realiza mediante un certificado con parte pública y parte privada, por lo que se asegura que la recepción del mensaje solo puede ser vista por alguien que disponga la clave privada pareja de la clave pública que se empleó para cifrar el mensaje.
Claves
El sistema de SSH emplea para su comunicación las claves privadas/públicas, enviando la clave pública al cliente para que encripte con ella y desencriptando con la privada cada mensaje recibido.
Cuando realizamos una conexión SSH, si activamos el verbose, podremos ver información como esta:
$ ssh -v rivendel
OpenSSH_5.2p1, OpenSSL 0.9.7l 28 Sep 2006
[...]
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Host 'rivendel' is known and matches the RSA host key.
[...]
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
En este punto se ve que el sistema recibe del servidor la clave pública y la compara con el fichero known_hosts
para saber si es el mismo al que se ha conectado en otras veces. Como es así, el cliente genera una clave al vuelo y la envía para establecer la comunicación.
Con este proceso de negociación de claves, se establece la conexión y se puede continuar para solicitar el certificado de acceso o la clave de acceso.
Certificado de acceso
Lo más fácil es trabajar con una clave, ya que no habría que hacer nada, pero usar certificados es lo más simple de cara a seguridad, ya que echar o restringir el acceso a un usuario es simplemente eliminar su certificado de acceso. Con OpenSSH es tan simple generar un certificado de acceso como hacer esto:
$ ssh-keygen -t rsa
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Si tan solo presionamos el retorno de carro en las tres ocasiones, se generará un certificado sin protección de contraseña en dos ficheros, en este caso: id_rsa
, la clave privada; y id_rsa.pub
, la clave pública.
Podemos agregar el fichero de la clave pública al fichero de claves autorizadas de la cuenta a la que queramos acceder en el servidor por el que accedemos, y listo, ya podríamos entrar por certificado en lugar de clave.
Hay que tener en cuenta que, si por algún motivo decidimos poner clave al certificado generado, cada vez que se quiera usar el certificado se pedirá usuario y clave, pero esta no será a nivel de servidor, sino que será el cliente el que requiera la clave para poder desbloquear el certificado y usarlo contra el servidor.
Acceder a un puerto del servidor desde el cliente
Vamos a empezar por algo simple. Imagina que tenemos un puerto de escucha local en el servidor, por lo que, no podemos acceder a menos que estemos en el propio servidor. Si queremos tener ese puerto disponible en nuestro equipo de trabajo, habría que permitir una conexión en remoto. Pongamos que el puerto es el 8080 en el servidor:
$ ssh -f -N -L 8080:localhost:8080 user@server
Si vemos los puertos de escucha en nuestro ordenador, veremos que ssh ha abierto el puerto 8080 y si se trata de un servicio web y abrimos un navegador con http://localhost:8080 podremos ver el contenido que nos muestra el servidor.
Esto es útil cuando en el servidor se activan interfaces de gestión que solo pone a disposición de forma local, por seguridad, pero que se requiere desde el cliente tener acceso a las mismas. Además de proporcionar seguridad de acceso (que bien podría hacer un cortafuegos aunque no de forma tan dinámica) también nos da una capa de seguridad en la transmisión, ya que se transmite a través del canal seguro de OpenSSH.
Acceder a otro servidor desde el servidor
Al igual que se puede acceder a otro puerto, también se puede acceder a otro equipo al que tan solo se tenga acceso desde el servidor donde se ha realizado el SSH. Por ejemplo, imaginemos que tenemos dos servidores, el servidor web, al que tenemos acceso por SSH y otro servidor de base de datos, que está en una red privada de servidores (la DMZ), pero que no tenemos acceso directo a él y queremos hacer una consulta con nuestra interfaz de gestión de MySQL. Esto se haría:
$ ssh -f -N -L 3306:serverdb:3306 user@webserver
Con esto, al igual que el caso anterior, damos visibilidad al puerto 3306 del servidor de base de datos a través del servidor web en el cliente, el ordenador desde el que lo hemos ejecutado.
Acceso al cliente desde el servidor
También podríamos querer, en un momento dado, tener acceso a nuestro equipo. Por ejemplo, el propio servidor de SSH, para, desde otro sitio, poder acceder a nuestro ordenador de casa. Esto sería:
$ ssh -f -N -R 2222:localhost:22 user@server
En este caso hemos tenido que cambiar el puerto de escucha, ya que el puerto 22 se supone ocupado por el servidor SSH, por lo que lo cambiamos al 2222. Si accedemos al servidor y escribimos:
$ ssh -p 2222 user@localhost
El sistema usará el puente para acceder al cliente y conectar con su puerto 22, por lo que preguntará por la clave (o enviará el certificado si está configurado de forma adecuada) y establecerá una conexión segura (y doblemente segura) con el cliente. Útil para accesos remotos a otros equipos, como mantenimiento en remoto y similares.
Conclusiones
Espero que haya resultado de ayuda y sea de utilidad, ya que con lo presente que se ha hecho Internet en los últimos años, son casi generales para la mayoría de los informáticos estos escenarios o similares.