9.6 Uso de SSH

SSH es uno de los programas con los que tendremos que lidiar todos los días que estamos trabajando en una máquina con Unix o Linux. Veámos algunos ejemplos de uso típicos.

9.6.1 Accediendo a un host remoto

Para acceder al host remoto utilizamos el cliente ssh. En ese momento se producirá el proceso de autentificación del servidor y el proceso de identificación y autentificación del usuario. Dependiendo del esquema de autentificación de usuario existen distintas alternativas:

Autentificación basada en password:
Suele ser la forma más corriente de acceder al host remoto:
usuario$ ssh host_remoto

Con este comando estamos accediendo al host utilizando el usuario usuario. Cuando queramos acceder con otro nombre de usuario utilizaremos:

usuario$ ssh nombre_de_usuario@host_remoto

Taller 9.1:
Instale un servidor SSH. Acceda a su cuenta en su host usando SSH. Pruebe también a hacerlo como administrador.
Autentificación basada en clave pública:
Como indicamos, el usuario se autentifica probando que es capaz de firmar (descifrar y cifrar) el desafío que le plantea el servidor. Para poder hacer esto son necesarios los siguientes pasos:
  1. Generar las claves de autentificación:
    # Por curiosidad mostramos el contenido del directorio "~/.ssh".  
    usuario$ ls -l $HOME/.ssh/  
    total 4  
    -rw-r--r-- 1 usuario usuario 1866 2007-02-08 15:12 known_hosts  
    v  
    # Generación de la clave usando RSA.  
    usuario$ ssh-keygen -t rsa  
    # Selecionar el fichero de salida que se especifica por defecto.  
    # La clave debería tener al menos 20 caracteres.  
     
    # Por curiosidad mostramos el contenido del directorio "~/.ssh".  
    usuario$ ls -l $HOME/.ssh/  
    total 12  
    -rw------- 1 usuario usuario 1743 2007-02-08 22:19 id_rsa  
    -rw-r--r-- 1 usuario usuario  405 2007-02-08 22:19 id_rsa.pub  
    -rw-r--r-- 1 usuario usuario 1866 2007-02-08 15:12 known_hosts  
     
    # Comprobamos que la clave pública se ha generado.  
    usuario$ cat ~/.ssh/id_rsa.pub  
    ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5HgtUR6OfvEIUv6m2xXM6QK3MH0Z6\  
    74btlJ20XDTAfh0llRgiDxnqrH492ZwH0r6EjVfkH6KhB9R2Duxvpzp4LeBWZ0ouL\  
    E5MiJBe0aR7CBUcjkq8FzLL3Caf0c7w3Dbtldn4zQdIoHswsD8sFyk2vT4a3QXBV/\  
    U3Q0DvCXyb5kZp7JOfzNAMJbCD6IVEbDrwqfu4JfTOXAWY8ckofq9zFK+JtkB9XJy\  
    a7pVJVtI0dKCnVTw3oU4eufj4OxwSGnAyVrf9rEv6jB+4R7tCQZdtuJO7SPAUbJsc\  
    rD4qjnOz/BDvx2LUQuQXMrbr7GQ+lBNC6gZWcUF33RGc+wIAjvR8Q==\  
     usuario@debian.ace.ual.es

  2. Enviar la clave pública al servidor:
    # Añadimos la clave pública a nuestro fichero de claves públicas en el  
    # host remoto.  
    usuario$ ssh <host_remoto> "mkdir .ssh/; umask 077; cat >> .ssh/authorized_keys" < ~/.ssh/id_rsa.pub

En este punto deberíamos tener ya acceso al host remoto. Para ello se nos preguntará por la frase que usamos cuando generamos las claves de autentificación. Esta forma de autentificación sólo se establecerá cuando accedemos desde el host local usando el usuario usuario. Si accedemos desde otro host o con otro nombre de usuario, se utiliza la autentificación mediante password.

Taller 9.2:
Pruebe la autentificación basada en clave pública accediendo a un host remoto. Si no dispone de cuenta en un host remoto, utilice su propio host. Emplee en este caso una cuenta de usuario distinta.
Autentificación basada en el host del usuario:
Para habilitar esta forma de autentificación debemos tener acceso al host remoto como administrador. Estos son los pasos:
  1. Acceder al host remoto y comprobar que HostbasedAuthentication = yes y que IgnoreRhosts = no.
  2. Reiniciar el servidor SSH en el host remoto si se ha tenido modificar su configuración.
  3. Copiar la host key pública del cliente en el servidor. La clave pública en el cliente se almacena en /etc/ssh/ssh_host_rsa_key.pub. Dicha clave debe ser añadida al fichero /etc/ssh/ssh_known_hosts o al fichero  /.ssh/known_hosts.
  4. En el servidor, añadir el nombre del host cliente al fichero  /.shosts.
  5. En el cliente, asegurarse de que HostbasedAuthentication = yes.
  6. En el cliente, asegurarse de que la host key privada y pública existen. Esta información debería estar en los ficheros /etc/ssh/ssh_host_rsa_key y /etc/ssh/ssh_host_rsa_key.pub, respectivamente.

Debido a que necesitamos disponer de la clave de root en el host remoto, esta forma de autentificación es poco corriente. Además, como veremos a continuación, la autentificación basada en clave pública es muy cómoda y segura si utilizamos un agente SSH.

9.6.2 Usando ssh-agent y ssh-add

Para que la identificación basada en clave pública sea realmente segura la frase que usemos para generar la clave de autentificación debe ser suficientemente larga (20 caracteres o más). Esto puede suponer un embrollo cuando accedemos muchas veces al host remoto.

Para solucionar este problema, el SSH incorpora un demonio llamado ssh-agent que se encarga de escribir por nosotros las frases. Este demonio puede ser invocado por el usuario de la siguiente manera:

# ¿Qué procesos se están ejecutando?  
usuario$ ps x  
 PID TTY      STAT   TIME COMMAND  
   : :        :      :    :  
3096 pts/1    R+     0:00 ps x  
 
# Comprobamos que entre las variables de entorno declaradas  
# no aparecen SSH_AGENT_PID y SSH_AUTH_SOCK.  
usuario$ export  
declare -x HISTCONTROL="ignoredups"  
declare -x HOME="/home/usuario"  
declare -x LANG="es_ES.UTF-8"  
:  
declare -x TERM="xterm"  
declare -x USER="usuario"  
 
# Lanzamos el demonio. Este comando comprueba primero que no existe  
# ya un agente ejecutándose. La directiva del shell "eval" permite  
# ejecutar ssh-agent con su parámetro.  
usuario$ test -z "$SSH_AUTH_SOCK" && eval ‘ssh-agent -s‘  
Agent pid 3256  
usuario@debian:~$ export  
declare -x HISTCONTROL="ignoredups"  
declare -x HOME="/home/usuario"  
:  
declare -x SSH_AGENT_PID="3256"  
declare -x SSH_AUTH_SOCK="/tmp/ssh-kVGvUg3255/agent.3256"  
:  
declare -x TERM="xterm"  
declare -x USER="usuario"  
 
usuario$ ps x  
  PID TTY      STAT   TIME COMMAND  
    : :        :      :    :  
 3056 ?        Ss     0:00 ssh-agent -s  
 3099 pts/1    R+     0:00 ps x

Una vez que el demonio está ejecutándose, informarle de nuestra clave de autentificación pública es sencillo:

# Deberemos introducir la clave pública introducida en  
# la fase de autentificación basada en clave pública...  
usuario$ ssh-add

En este punto, accederemos al host remoto sin necesidad de escribir la frase de acceso porque ssh-agent lo ha hecho por nosotros.

Evidéntemente, como podemos tener acceso a distintas máquinas con distintas frases de acceso, podemos usar tantas veces ssh-add como deseemos. Para saber qué frases son admistradas en un momento dado por ssh-agent:

usuario$ ssh-add -l

Las frases puede ser eliminadas del demonio usando:

usuario$ ssh-add -d [fichero_con_la_clave]

Usar man ssh-add para ver el resto de opciones.

Taller 9.3:
Haga uso ssh-agent para acceder a un host remoto sin necesidad de introducir la clave pública. Si no dispone de cuenta en un host remoto, utilice su propio host y una cuenta de usuario distinta.

9.6.3 Ejecución de comandos no interactivos en el host remoto

Con SSH es posible ejecutar comandos no interactivos en el host remoto. Un ejemplo:

# Averiguando los usuarios actuales en el host remoto  
usuario$ ssh <host_remoto> who  
 
# Viendo el contenido actual del directorio /tmp en el host remoto  
usuario$ ssh <host_remoto> ls /tmp  
 
# Copiando un fichero al host remoto  
usuario$ cat fichero | ssh <host_remoto> "cat > fichero"  
 
# Copiando un directorio completo al host remoto  
usuario$ tar cvf - directorio/ | gzip -9c | ssh <host_remoto> "tar xz"

Taller 9.4:
Pruebe a ajecutar un comando en un host remoto. Si no dispone de cuenta en un host remoto, hágalo en su propio host usando una cuenta de usuario distinta.

9.6.4 Verificación de la host key

Como vimos al comienzo de este módulo, SSH incorpora un mecanismo para autentificar al servidor basado en la comparación de la host key que envía el servidor con la que hay almacenada en el fichero  /.ssh/known_hosts. Si es la primera vez que nos conectamos o por algún motivo, la host key ha cambiado, es una buena costumbre que comprobemos que dicha clave coindice con la que el servidor generaría utilizando las herramientas del SSH. Para mostrar la host key en el servidor podemos utilizar el siguiente comando:

# Mostrando la host key del servidor.  
usuario$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub

En el fichero /etc/ssh/ssh_host_rsa_key.pub se almacena la host key pública de forma cifrada usando el algoritmo RSA. En el fichero /etc/ssh/ssh_host_rsa_key se almacenan la host key privada de forma cifrada usando el algoritmo RSA.

Taller 9.5:
Fuerce a que SSH le muestre la host key de un host remoto. Para ello debe borrar la entrada correspondiente a dicho host en el fichero ~/.ssh/known_hosts (puede borrar directamente el fichero). Acceda al host remoto y anote la host key que le muestra el cliente. En el host remoto ejecute el comando que muestra la host key y compruebe que ambas claves coinciden. Si no dispone de cuenta en un host remoto, utilice su propio host y una cuenta de usuario distinta.

9.6.5 Copiando ficheros

SSH incorpora una utilidad semejante a cp para copiar ficheros entre hosts de una forma muy sencilla. Algunos ejemplos:

# Copiando "fichero" al home del host remoto:  
usuario$ scp fichero <host_remoto>:~  
 
# Copiando "fichero" al /tmp del host remoto:  
usuario$ scp fichero <host_remoto>:/tmp  
 
# Copiando "fichero" al /tmp del host remoto y cambiando el nombre:  
usuario$ scp fichero <host_remoto>:/tmp/file  
 
# Copiando un "directorio" con todos sus contenidos al home del host remoto:  
usuario$ scp -r directorio <host_remoto>:~  
 
# También podemos utilizar sftp (un intérprete semejante a ftp) para  
# mover ficheros entre hosts:  
usuario$ sftp <host_remoto>  
# Los comandos de sftp son similares a los del programa ftp.  
 
# Por último, podemos hacer copias incrementales con la utilidad rsync:  
usuario$ rsync * <host_remoto>

Taller 9.6:
Efectúe una copia remota entre hosts. Si no dispone de cuenta en un host remoto, utilice su propio host y una cuenta de usuario distinta.

9.6.6 SSH forwarding

El SSH tiene la habilidad de multiplexar varias conexiones sobre un mismo tunnel cifrado. A esta propiedad se le conoce como forwarding (encaminamiento). Veámos algunos ejemplos interesantes:

Forwarding del agente de autentificación

Como vimos anteriormente, el agente de autentificación es muy útil para lidiar con las frases de clave. El problema es que si hemos accedido a un host remoto A y desde él queremos acceder a otro B usando de nuevo el agente, deberíamos ejecutarlo en A y añadirle las frases. Para conseguir esto podemos hacer dos cosas:

  1. Configurar nuestro cliente para que rediriga el agente:
    # También vale el fichero /etc/ssh/ssh_config  
    usuario$ cat ~/.ssh/config  
    :  
    Host nombre_host_remoto  
    ForwardAgent yes  
    :

  2. Invocar al cliente mediante:
    # Este comando lanzará ssh-agent en el host remoto y copiará las claves.  
    usuario@host_local$ ssh -A <host_remoto>

Para verificar que el redireccionamiento ha funcionado, comprobaremos que el agente en el host remoto contempla nuestras claves:

usuario@host_remoto$ ssh-add -l

Taller 9.7:
Redirija ssh-agent hacia un host remoto y compruebe que las claves se han copiado. Si no dispone de cuenta en un host remoto, hágalo contra su propio host usando una cuenta de usuario distinta.

Redireccionamiento del X11

Cuando usamos SSH desde una consola gráfica, podemos ejecutar aplicaciones gráficas en el host remoto y presentarlas en el host local. Para conseguir esto debemos:

  1. Configurar nuestro cliente para que rediriga el X11:
    # También vale el fichero /etc/ssh/ssh_config  
    usuario$ cat ~/.ssh/config  
    :  
    Host nombre_host_remoto  
    ForwardX111 yes  
    :

  2. Invocar al cliente mediante:
    usuario@host_local$ ssh -X nombre_host_remoto

En este punto podríamos ejecutar una aplicación gráfica, un xterm, por ejemplo:

usuario@host_remoto$ xterm &

Taller 9.8:
Para probar la redirección del X11 lo ideal es tener cuenta en un host remoto con el servidor X11 y el servidor SSH activados. Si este no es el caso, podemos instalar en el host huésped (Windows) el software Cygwin (http://www.cygwin.com/) y acceder desde una consola gráfica al host virtual usando SSH. Una vez que hayamos accedido al host virtual lanzaremos alguna aplicación gráfica y comprobaremos que la redirección ha funcionado. Más concretamente:
  1. Instale Cygwin en el host huésped. Los paquetes que se instalan por defecto instalan un cliente SSH y el sistema gráfico X11.
  2. Ejecute una consola de texto. Tras la instalación anterior, en su escritorio debería haber aparecido un icono que ejecuta dicha consola.
  3. Escriba en ella:
    startx &

    Transcurridos unos segundos debería aparecer una ventana con un terminal gráfico (este terminal se invoca con la aplicación xterm).

  4. En el terminal gráfico realice las siguientes acciones:
    # Habilitamos el sistema gráfico para que cualquier host pueda  
    # enviar su salida gráfica X11 a nuestro sistema.  
    usuario$ xhost +  
     
    # Accedemos al host virtual  
    usuario$ ssh -X <dir_IP_del_host_virtual>

  5. Cuando esté dentro del host virtual, ejecute una aplicación gráfica:
    usuario$ xeyes &

Redireccionamiento de puertos

El redireccionamiento de puertos es una característica utilísima de SSH. Con esto podemos acceder a servicios que están filtrados por un cortafuegos y cifrar transmisiones sobre redes no seguras.

Antes de mostrar cómo se realiza el redireccionamiento, una aclaración importante. El objetivo del redireccionamiento es codificar la comunicación desde nuestro host a otro distinto, situado fuera de nuestra red “segura”. En este sentido podemos encontrarnos los siguientes contextos:

Bien, una vez hecha estas aclaraciones explicaremos cómo redireccionar puertos en cada caso. En los ejemplos que se muestran a continuación supondremos que hemos configurado nuestro navegador Web para que utilize un proxy Web situado en nuestro host (home_host) escuchando en el puerto 1234, aunque dicho servidor esté realmente ejecutándose en un host remoto que llamaremos squid_host y al que tenemos acceso mediante SSH. Supondremos además que en la red local (y por tanto, segura) de squid_host existe otro host remoto remote_host en el que también tenemos cuenta.

Redireccionamiento local directo:
 
# La forma estándar es:  
home_host@usuario$ ssh -L 1234:squid_host:3128 squid_host  
# Nota importante: si "usuario" no tiene cuenta como "usuario" en  
# "squid_host" y por lo tanto tiene que especificarlo, este  
# procedimiento puede no funcionar :-(  
 
# Aunque también funciona:  
home_host@usuario$ ssh -L 1234:localhost:3128 squid_host

Con este ejemplo, hemos redirigido el puerto 1234 del home_host al puerto 3128 de host squid_host.

Redireccionamiento local indirecto:
 
home_host@usuario$ ssh -L 1234:squid_host:3128 remote_host  
# Nota importante: si "usuario" no tiene cuenta como "usuario" en  
# "squid_host" y por lo tanto tiene que especificarlo, este  
# procedimiento puede no funcionar :-(

En este ejemplo el puerto 1234 del host local se ha redirigido al puerto 3128 del host squid_host a través del host remote_host.

Redireccionamiento remoto:
 
squid_host@usuario$ ssh -R 1234:localhost:3128 home_host

Redireccionamos el puerto 3128 del host squid_host al puerto 1234 del host home_host.

Taller 9.9:
Redirija el puerto 1234 hacia un host remoto que ejecuta Squid en el puerto 3128. Configure su navegador Web para que utilice un proxy escuchando en el host local en el puerto 1234. Compruebe que puede navegar. Utilice como host local el PC huésped (Windows) y como host remoto el PC virtual (Debian).
Cuestión 9.1:
Imagine que está utilizando un sistema de cifrado de clave asimétrica para comunicarse con otra persona. ¿Con qué clave descifraré un mensaje que ella le ha enviado? ¿Con qué clave cifrará le mensaje que usted quiere transmitirle?
Cuestión 9.2:
Usted dispone de una cuenta de usuario en un host de la universidad de Almería en el que está ejecutándose un servidor POP3. Explique qué pasos realizaría para leer el correo electrónido cuando está usando un host externo a la universidad. Nota, el cortafuegos de la universidad impide cualquier conexión a un host de la universidad desde fuera de la misma, si el servicio usado no es La Web o el SSH.