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.
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:
alumno$ ssh host_remoto
Con este comando estamos accediendo al host utilizando el usuario alumno.
Cuando queramos acceder con otro nombre de usuario utilizaremos:
alumno$ ssh otro_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 en la Sección 9.2, 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:
- Generar las claves de autentificación:
# Por curiosidad mostramos el contenido del directorio "~/.ssh".
alumno$ ls -l $HOME/.ssh/
total 4
-rw-r--r-- 1 alumno alumno 1866 2007-02-08 15:12 known_hosts
v
# Generación de la clave usando RSA.
alumno$ 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".
alumno$ ls -l $HOME/.ssh/
total 12
-rw------- 1 alumno alumno 1743 2007-02-08 22:19 id_rsa
-rw-r--r-- 1 alumno alumno 405 2007-02-08 22:19 id_rsa.pub
-rw-r--r-- 1 alumno alumno 1866 2007-02-08 15:12 known_hosts
# Comprobamos que la clave pública se ha generado.
alumno$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA5HgtUR6OfvEIUv6m2xXM6QK3MH0Z6\
74btlJ20XDTAfh0llRgiDxnqrH492ZwH0r6EjVfkH6KhB9R2Duxvpzp4LeBWZ0ouL\
E5MiJBe0aR7CBUcjkq8FzLL3Caf0c7w3Dbtldn4zQdIoHswsD8sFyk2vT4a3QXBV/\
U3Q0DvCXyb5kZp7JOfzNAMJbCD6IVEbDrwqfu4JfTOXAWY8ckofq9zFK+JtkB9XJy\
a7pVJVtI0dKCnVTw3oU4eufj4OxwSGnAyVrf9rEv6jB+4R7tCQZdtuJO7SPAUbJsc\
rD4qjnOz/BDvx2LUQuQXMrbr7GQ+lBNC6gZWcUF33RGc+wIAjvR8Q==\
alumno@debian
- Enviar la clave pública al servidor:
# Añadimos la clave pública a nuestro fichero de claves públicas en el
# host remoto.
alumno$ 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 alumno. 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 cuyo login sea “usuario_ssh”.
________________________________
- Especifique cada uno de los pasos que ha realizado para probar la
autentificación basada en clave pública cuando accede a un host
“remoto”. Indique el objetivo de cada uno de estos pasos.
-
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:
- Acceder al host remoto y comprobar que HostbasedAuthentication
= yes y que IgnoreRhosts = no.
- Reiniciar el servidor SSH en el host remoto si se ha tenido que modificar
su configuración.
- 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.
- En el servidor, añadir el nombre del host cliente al fichero /.shosts.
- En el cliente, asegurarse de que HostbasedAuthentication = yes.
- 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.
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?
alumno$ 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.
alumno$ export
declare -x HISTCONTROL="ignoredups"
declare -x HOME="/home/alumno"
declare -x LANG="es_ES.UTF-8"
:
declare -x TERM="xterm"
declare -x USER="alumno"
# 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.
alumno$ test -z "$SSH_AUTH_SOCK" && eval "ssh-agent -s"
Agent pid 3256
alumno@debian:~$ export
declare -x HISTCONTROL="ignoredups"
declare -x HOME="/home/alumno"
:
declare -x SSH_AGENT_PID="3256"
declare -x SSH_AUTH_SOCK="/tmp/ssh-kVGvUg3255/agent.3256"
:
declare -x TERM="xterm"
declare -x USER="alumno"
alumno$ 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...
alumno$ 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:
alumno$ ssh-add -l
Las frases puede ser eliminadas del demonio usando:
alumno$ 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 la cuenta de usuario “usuario_ssh”.
________________________________________________________________________________________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Explique brevemente lo que aparece en dicho volcado.
Con SSH es posible ejecutar comandos no interactivos en el host remoto. Un
ejemplo:
# Averiguando los usuarios actuales en el host remoto
alumno$ ssh <host_remoto> who
# Viendo el contenido actual del directorio /tmp en el host remoto
alumno$ ssh <host_remoto> ls /tmp
# Copiando un fichero al host remoto
alumno$ cat fichero | ssh <host_remoto> "cat > fichero"
# Copiando un directorio completo al host remoto
alumno$ 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
la cuenta de usuario “usuario_ssh”.
___________________________________________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Explique brevemente su contenido.
Como vimos al comienzo de esta práctica, 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.
alumno$ 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 la cuenta de usuario “usuario_ssh”.
_____________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Comente brevemente su contenido.
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:
alumno$ scp fichero <host_remoto>:~
# Copiando "fichero" al /tmp del host remoto:
alumno$ scp fichero <host_remoto>:/tmp
# Copiando "fichero" al /tmp del host remoto y cambiando el nombre:
alumno$ scp fichero <host_remoto>:/tmp/file
# Copiando un "directorio" con todos sus contenidos al home del host remoto:
alumno$ scp -r directorio <host_remoto>:~
# También podemos utilizar sftp (un intérprete semejante a ftp) para
# mover ficheros entre hosts:
alumno$ sftp <host_remoto>
# Los comandos de sftp son similares a los del programa ftp.
# Por último, podemos hacer copias incrementales con la utilidad rsync:
alumno$ 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 la cuenta de usuario
“usuario_ssh”.
_____________________________________________________________________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Explique brevemente su contenido.
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:
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:
- Configurar nuestro cliente para que redirija el agente:
# También vale el fichero /etc/ssh/ssh_config
alumno$ cat ~/.ssh/config
:
Host nombre_host_remoto
ForwardAgent yes
:
- Invocar al cliente mediante:
# Este comando lanzará ssh-agent en el host remoto y copiará las claves.
alumno@host_local$ ssh -A <host_remoto>
Para verificar que el redireccionamiento ha funcionado, comprobaremos que el agente
en el host remoto contempla nuestras claves:
alumno@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 la cuenta de usuario “usuario_ssh”.
________________________________________________________________________________________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Explique el funcionamiento de ssh-agent en dicho ejemplo.
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:
- Configurar nuestro cliente para que rediriga el X11:
# También vale el fichero /etc/ssh/ssh_config
alumno$ cat ~/.ssh/config
:
Host nombre_host_remoto
ForwardX11 yes
:
- Invocar al cliente mediante:
alumno@host_local$ ssh -X nombre_host_remoto
En este punto podríamos ejecutar una aplicación gráfica, un xterm, por
ejemplo:
alumno@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:
- Instale Cygwin en el host huésped. Los paquetes que se instalan
por defecto instalan un cliente SSH y el sistema gráfico X11. Si
esto no ocurriera así, instale la aplicación xterm.
- Ejecute una consola de texto. Tras la instalación anterior, en su
escritorio debería haber aparecido un icono que ejecuta dicha
consola.
- 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).
- 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.
alumno$ xhost +
# Accedemos al host virtual
alumno$ ssh -X <dir_IP_del_host_virtual>
- Cuando esté dentro del host virtual, ejecute una aplicación
gráfica:
alumno$ xeyes &
_____________________________________________________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Comente brevemente qué es lo que ocurre en dicho volcado de pantalla.
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:
- Que el host que ejecuta el servicio (llamémoslo host X) no tiene un servidor
SSH instalado o no tenemos cuenta de usuario en él. En este caso deberíamos
tener una cuenta en otro host Y situado en la misma red segura que el host
X que ejecuta el servicio, y el redireccionamiento se realizaría desde nuestro
host al host Y usando un canal seguro, y desde el host Y al host X usando un
canal inseguro, pero a través de la red que se considera segura. Usaremos el
término redireccionamiento local indirecto para referirmos a esta posibilidad.
- Que tenemos cuenta de usuario en el host que ejecuta el servicio. En este caso
sólo tenemos que redireccionar el puerto desde nuestro host al host remoto.
LLamaremos a esta forma de redireccionamiento, redireccionamiento local
directo.
- Con SSH es posible utilizar servicios que están tras un cortafuegos que no
permite las conexiones SSH entrantes (desde Internet hacia la red protegida).
Esto puede hacerse con el redireccionamiento remoto. Para ello debemos tener
acceso físico al host que ejecuta el servicio y redirigir el puerto del servicio a
un puerto en el host que está fuera de la red protegida.
Bien, una vez hechas 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:
alumno@home_host$ ssh -L 1234:squid_host:3128 squid_host
# Nota importante: si "alumno" no tiene cuenta como "alumno" en
# "squid_host" y por lo tanto tiene que especificarlo, este
# procedimiento puede no funcionar :-(
# Aunque también funciona:
alumno@home_host$ 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:
-
alumno@home_host$ ssh -L 1234:squid_host:3128 remote_host
# Nota importante: si "alumno" no tiene cuenta como "alumno" 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:
-
alumno@squid_host$ 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/Cygwin o Linux) y como host remoto el PC virtual (Debian).
Si no desea o no puede ejecutar Cygwin, también puede hacerlo desde
el propio PC virtual. Finalmente, existe la posibilidad de duplicar el PC
virtual y acceder desde uno hasta otro.
______________________________________________
- Presente un volcado de pantalla mostrando la ejecución del anterior taller.
Explique su funcionamiento.