Configurar servidor OpenSSH de manera segura y uso de llaves publica/privada y keychain en Slackware Linux.

Jorge Armando Medina

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover, and with no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License”.

2005-07-31


1. Introduccion
2. Instalacion
3. Inicializacion
4. Configuracion
5. Usando Autenticacion con par de llaves publica/privada con SSH.
6. Entra ssh-agent.
7. Limitantes de ssh-agent.
8. Es aqui donde entra keychain.
9. Keychain en accion.
10. Autenticacion a servidores remotos con ssh usando solamente autenticacion con el par de llaves publica/privada DSA.
11. Limitando acceso por usuario o grupo.
12. Limite de acceso por llaves.
13. Conclusion.
14. Referencias

1. Introduccion

OpenSSH es una versión LIBRE de la suite de protocolos SSH para la conectividad de redes. Muchos usuarios de telnet, rlogin, ftp, y otros programas puede que no se den cuenta que sus contraseñas son trasmitidas a través de la Internet en forma plana (texto plano), pero así es. OpenSSH cifra todo el trafico (incluyendo contraseñas) para así evitar que alguien pueda capturar las contraseñas o la información, o algún otro ataque a la red. Adicionalmente, OpenSSH provee otras capacidades para hacer túneles de otros protocolos y una variedad de métodos de autenticación.

La suite OpenSSH incluye los programas ssh el cual remplaza a rlogin y telnet, scp el cual remplaza a rcp, y sftp el cual remplaza a ftp. También es incluido sshd el cual es el paquete de el lado de servidor, y las otras utilerias básicas como ssh-add, ssh-agent, ssh-keysign, ssh-keyscan, ssh-keygen y sftp-server, OpenSSH soporta las versiones de los protocolos ssh 1.3, 1.5, y 2.0.

OpenSSH es desarrollado principalmente por el proyecto OpenBSD, y su primera inclusión dentro de un sistema operativo fue en OpenBSD 2.6, el software es desarrollado fuera de USA, usando código de cerca de 10 países, y es libremente usable y re-usable para todos bajo la licencia BSD.

Bien en este documento explicaremos como instalar y configurar el servidor OpenSSH en Slackware 10.2, las instrucciones podrían ser las mismas para otras distribuciones Linux u otros Unix.

2. Instalacion

Para la instalación es recomendable siempre usar la ultima versión estable de el paquete OpenSSH, en este momento la ultima versión estable para Slackware 10.2 es: openssh-4.2p1-i486-1, por lo tanto se recomienda instalar esa versión, este lo puedes instalar desde tus CDs de instalación, o bajando el paquete desde algún servidor ftp oficial de Slackware.

Si hiciste una instalación full, seguramente ya tienes el paquete de openssh instalado, puedes comprobarlo así:

$ ls /var/log/packages/openssh*
/var/log/packages/openssh-4.2p1-i486-1

Si muestra algo como lo de arriba significa que ya tienes el paquete instalado.

Si no aparece nada, entonces hay que seguir leyendo.

El paquete se encuentra en el CD1 en el directorio slackware/n/ o bajándolo desde el servidor ftp: ftp://ftp.slackware.com/pub/slackware/slackware-10.2/slackware/n/openssh-4.2p1-i486-1.tgz

Cualquier método que hayas elegido se debe de instalar así:

# installpkg openssh-4.2p1-i486-1.tgz

3. Inicializacion

Una vez instalado se debe de iniciar el servicio así:

# /etc/rc.d/rc.sshd start
Generating public/private rsa1 key pair.
Your identification has been saved in /etc/ssh/ssh_host_key.
Your public key has been saved in /etc/ssh/ssh_host_key.pub.
The key fingerprint is:
7b:53:42:4f:c9:8d:c9:20:9b:f0:25:e2:21:ec:a6:ec root@cliente
Generating public/private dsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_dsa_key.
Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub.
The key fingerprint is:
b5:09:f9:a8:12:85:d8:30:64:f8:50:51:e1:da:c2:04 root@cliente
Generating public/private rsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_rsa_key.
Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub.
The key fingerprint is:
8a:d6:20:68:e9:07:ea:a5:78:f4:70:9b:15:73:17:ae root@cliente

Como vemos la primera vez que se inicia el servicio genera el par de llaves (publica/privada) tanto rsa1, dsa y rsa.

Bien hasta ahorita se supone que ya tenemos el servido SSH arriba, podemos comprobarlo haciendo:

# netstat -plutn | grep ssh
tcp   0   0 :::22   :::*   LISTEN   4124/sshd

Como vemos ahí esta escuchando peticiones en todas las interfaces de red en el puerto tcp/22.

Ahora podemos hacer una prueba conectándonos al servidor SSH (sshd) localmente para ver que funcione, nos conectaremos con el cliente SSH (ssh).

usuario@cliente:~$ ssh localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
RSA key fingerprint is 8a:d6:20:68:e9:07:ea:a5:78:f4:70:9b:15:73:17:ae.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
usuario@localhost's password:
Last login: Tue Jul 19 12:19:30 2005 from localhost
Linux 2.6.12.2.
usuario@cliente:~$

Como vemos ahí, nos dice que la autenticidad de el host 'localhost' no puede ser establecida. y nos muestra la huella digital (fingerprint) de la llave RSA que dice que es: 8a:d6:20:68:e9:07:ea:a5:78:f4:70:9b:15:73:17:ae3, si nos fijamos en la salida anterior cuando iniciamos el servicio sshd, vemos que esa huella digital (fingerprint) es la misma para la llave rsa, la cual salio esto:

Generating public/private rsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_rsa_key.
Your public key has been saved in /etc/ssh/ssh_host_rsa_key.pub.
The key fingerprint is:
8a:d6:20:68:e9:07:ea:a5:78:f4:70:9b:15:73:17:ae root@cliente

Si decimos 'yes' agregara el host 'localhost' (RSA a tu lista de host conocidos o confiables y te pide la contraseña de el usuario, si nos fijamos cuando nos tratamos de conectar por ssh, nunca dimos un nombre de usuario, pero el comando ssh automáticamente usa el nombre de usuario de el usuario quien ejecuta el comando, así si estas trabajando con el usuario benito pasara benito@localhost por ejemplo, en este caso es usuario@localhost, claro que el usuario benito o cualquiera con el que te quieras autenticar debe de existir en el host remoto con su debida contraseña y acceso a el shell. Si ingresaste la contraseña correcta inmediatamente después te mostrara el mensaje de bienvenida el host remoto, que en este caso es el mismo host local.

Listo ya estamos conectado, y como podemos ver estamos en una sesión como si nos conectáramos localmente en la consola, todo lo que se puede hacer en la consola localmente, se puede hacer por medio de una sesión SSH, puedes ejecutar comandos como ls, cp, mv, vim, pico, etc.

Para salirse de la sesión SSH se hace con el comando 'exit' o tecleando la combinación de teclas: Ctrl+d

$ exit
logout
Connection to localhost closed.

Bien, hasta ahora ya aprendimos como instalar e iniciar el servidor sshd, y como conectarnos de manera básica al servidor, por default cuando se instala el paquete openssh, este servicio sera automáticamente iniciado al arranque del equipo, esto lo hace el script: /etc/rc.d/rc.sshd, para confirmar que el servicio vaya a iniciar automáticamente debemos de confirmar que el archivo /etc/rc.d/rc.sshd tenga permisos de ejecución, lo podemos comprobar así:

# ls -l /etc/rc.d/rc.sshd
-rwxr-xr-x  1 root root 1222 2004-09-04 19:49 /etc/rc.d/rc.sshd*

Como vemos ahí si tiene permisos de ejecución, si no se mostrara como se ve arriba entonces deberemos de hacerlo manualmente así:

# chmod 755 /etc/rc.d/rc.sshd

4. Configuracion

Ahora sigue la configuración de el servidor sshd, para que podamos tener el servicio de una manera más segura.

El archivo de configuración para el servidor sshd es: /etc/ssh/sshd_config, antes de hacer algún cambio se recomienda hacer una copia de seguridad de este archivo así:

# cd /etc/ssh
# cp sshd_config sshd_config.orig

Ok, ahora hay que cambiar algunos parámetros básicos a este archivo, abre el archivo con tu editor de textos favorito, claro VIM. :D

# vim sshd_config

vayamos a las primeras lineas que están así:

#Port 22
#Protocol 2,1
#ListenAddress 0.0.0.0
#ListenAddress ::

Como vemos están comentadas, entonces empezaremos des comentando algunas para hacer las cosas más explicitas.

Primero des comentar la linea que dice Port 22, esto es el puerto tcp en el que escucha peticiones el servidor sshd. por lo tanto quedara así:

Port 22

Ahora hay que des comentar la linea de #Protocol 2,1 y dejarla así:

Protocol 2

En este caso solo haremos uso de la versión 2 del protocolo ssh.

La siguiente linea, es para configurar la dirección IP asignada a alguna interfaz de red en la que el servidor ssh escuchara peticiones, si el servidor tiene varias interfaces de red con diferentes direcciones IP asignadas entonces por default el servidor sshd escuchara peticiones en todas ellas, como lo vimos al ejecutar el comando netstat en la parte de arriba, esto es útil por ejemplo cuando tenemos un servidor que tiene dos interfaces de red una para Internet y otra para la red local, y solo quisiéramos que escuchara peticiones en la interfaz de la red local, o en la de Internet, entonces podría ser cambiado a algo así:

ListenAddress 192.168.0.1

NOTA: Si deseas que escuche peticiones en todas las interfaces de red, quizás porque necesites administrar el servidor de manera remota por Internet entonces hay que dejar la linea tal y como esta.

Ahora, las siguientes lineas están así:

# HostKey for protocol version 1
#HostKey /etc/ssh/ssh_host_key
# HostKeys for protocol version 2
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key

Estas son las llaves publicas para el servidor sshd, tanto para el protocolo 1 y 2 de ssh, y como arriba ya pusimos que solo usaremos el protocolo version 2, entonces unas lineas están de más, osea, las que son para el protocolo 1, y aquí aparte solo usaremos las llaves dsa de la version 2, entonces eliminaremos unas lineas y des comentaremos otra, de manera que solo quede así:

# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_dsa_key

Ahora sigue la parte en la que el servidor sshd guarda los registros de eventos (logs):

# Logging
#obsoletes QuietMode and FascistLogging
#SyslogFacility AUTH
#LogLevel INFO

Como vemos están comentadas, las haremos explicitas des comentando algunas para que quede así:

# Logging
#obsoletes QuietMode and FascistLogging
SyslogFacility AUTH
LogLevel INFO

Aquí se especifican los parámetros para el registro de eventos, SyslogFacility especifica el tipo de registros que hará, en este caso es AUTH, osea de las autenticaciones que se hacen contra el servidor, el parámetro AUTH es el predeterminado. En LogLevel INFO es el valor predeterminado, otros parámetros están especificados en la pagina del manual de sshd_config (man sshd_config), los parámetros DEBUG2 y DEBUG3 cada uno especifican el nivel mas alto de logueo, guardar registros con el nivel DEBUG viola la privacidad de los usuarios y por lo tanto no es recomendada.

Ahora sigue la parte de los métodos de autenticación.

Por default esta así:

# Authentication:

#LoginGraceTime 2m
#PermitRootLogin yes
#StrictModes yes
#MaxAuthTries 6

La primera opción es: #LoginGraceTime 2m, esto le dice al servidor sshd el tiempo en el que desconectara a el usuario después de que no ha podido iniciar sesión satisfactoriamente, si el valor es 0, no hay limite de tiempo para que un usuario se autentique, lo cual no es recomendable ya que de esta manera podrían hacer ataques de fuerza bruta, o usando métodos de diccionario y así adivinar la contraseña (estos métodos son muy comunes últimamente, yo a diario recibo desde 300, 500 y el máximo 2000 intentos a diario) por lo tanto no es recomendable dejar este parámetro a 0, el valor predeterminado es: 2m, osea 120 segundos.

Se des comentara y se dejara por default haciendo explicito:

LoginGraceTime 2m

El siguiente parámetro es uno de los más importantes en cuanto a seguridad en el servidor sshd se refiere: #PermitRootLogin yes, este parámetro por default le dice que acepte conexiones con el usuario "root" lo cual no es nada recomendable, porque alguien podría identificarse como tal usuario y podría adivinar la contraseña, y tendría privilegios de "root" y así podría hacer cualquier cosa, por lo tanto se desactivara poniendo:

PermitRootLogin no

Luego sigue: StrictModes yes, esto significa que sshd revisara los modos y permisos de los archivos de los usuarios y el directorio $HOME de el usuario antes de aceptar la sesión. Esto es normalmente deseable porque algunos novatos algunas veces dejan sus directorios accidentalmente con permiso de escritura para cualquiera, el valor predeterminado es 'yes'. Por lo tanto lo dejaremos con su valor predeterminado y solo lo des comentaremos para hacerlo explicito:

StrictModes yes

Y el ultimo de estas opciones es: MaxAuthTries 6, esta opción especifica el máximo numero de intentos de autenticación permitidos por conexión. Una vez que la intentos alcanza la mita de este valor, las conexiones fallidas siguientes serán registradas. El valor predeterminado es 6. En este caso lo dejaremos con su valor predeterminado, pero lo des comentaremos para hacerlo explicito, así:

MaxAuthTries 6

Las siguientes opciones son:

#RSAAuthentication yes
#PubkeyAuthentication yes
#AuthorizedKeysFile     .ssh/authorized_keys

La primera linea especifica que se use autenticación RSA, y como arriba desactivamos las llaves RSA para solo usar las DSA, entonces cambiaremos esta opción por:

RSAAuthentication no

Después esta: #PubkeyAuthentication yes: la cual especifica el uso de autenticación por medio de la llave publica, lo cual se vera después, por lo pronto lo activaremos así:

PubkeyAuthentication yes

Y esta otra se usa en conjunto cuando se usa autenticación por llave publica, que especifica donde se guardaran las llaves en el host remoto, el valor por default es: ~/.ssh/authorized_keys esta ruta es por default para el protocolo 2 de ssh, entonces la des comentaremos para hacerla explicita, así:

AuthorizedKeysFile     .ssh/authorized_keys

Las siguientes opciones son:

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#RhostsRSAAuthentication no
# similar for protocol version 2
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

Todas están comentadas de manera predeterminada, la mayoría se refieren a autenticación por RSA y rhosts, una que es importante aclarar es la de: #IgnoreUserKnownHosts no, la cual especifica si se ignorara o no el uso de el archivo ~/.ssh/known_hosts el cual al principio vimos que ahí se agregan las llaves de los servidores ssh a los cuales nos conectamos y confiamos. por lo tanto debe de estar en 'no' para no ignorar este archivo, entonces deberá de quedar todo el bloque así:

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# RhostsRSAAuthentication and HostbasedAuthentication
IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes

El siguiente bloque es:

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no

La primera opción es para especificar si se permite la autenticación por medio de usuario/contraseña, por default esta en 'yes' entonces lo dejaremos así, cuando sigamos en la segunda parte de el documento donde se usan par de llaves publica/privada, se cambiara este parámetro para solo conectarnos usando nuestro par de llaves. La segunda opción especifica si se permitirá el uso de contraseñas vacías, es decir autenticarse sin contraseña (no recomendable) , esto solo es valido cuando se usa PaswordAuthenticacion yes. Por ahora dejaremos los valores predeterminados y solo las des comentaremos para hacerlas explicitas, así:

# To disable tunneled clear text passwords, change to no here!
PasswordAuthentication yes
PermitEmptyPasswords no

Ahora nos brincaremos a la sección que esta así:

#AllowTcpForwarding yes
#GatewayPorts no
#X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression yes
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10

Aquí solo comentare a grandes rasgos algunas opciones.

AllowTcpForwarding yes:

Especifica si se permite hacer re direccionamiento de protocolos TCP, esto para hacer túneles de la conexión de un protocolo no seguro, que envía la información en texto plano, y mandarla por un túnel cifrado, muy usual con conexiones POP3 o IMAP, se recomienda dejarlo por default.

X11Forwarding no, X11DisplayOffset 10 y X11UseLocalhost yes:

Se refieren para especificar si se permite hacer uso de el X11 Forwarding, esto para ejecutar aplicaciones gráficas de el server, en el host local, podría ser útil para conectarse a hosts y ejecutar alguna aplicación gráfica, aunque en algunos servidores es raro tener el sistema gráfico, por ahora se dejaran tal y como están.

PrintMotd yes:

Especifica si cuando se establezca una conexión, se imprima el Mensaje de el Día (MOTD) se deja por default.

PrintLastLog yes:

Aquí se especifica si se mostrara el mensaje mostrando la dirección IP de donde se conecto el usuario la ultima vez, muy útil para saber si alguien más se esta conectando con un usuario en especifico.

TCPKeepAlive yes:

Significa que el servidor sshd enviara mensajes de keepalive a el cliente después de que detecta alguna inactividad (idle), este método puede ser spoofable.

UsePrivilegeSeparation yes:

Significa que después de que la sesión ssh se ha establecida se pasaran los privilegios de ese proceso a el usuario de quien inicie la conexión, sin esto el proceso estará a nombre de root, muy bueno esto para evitar elevación de privilegios.

ClientAliveInterval 0:

Esta opción especifica el intervalo de tiempo en segundos en el cual después de que no se ha recibido ningún dato de el cliente, sshd enviara un mensaje a través de el canal cifrado para requerir una respuesta de el cliente, el valor predeterminado es 0, el cual significa que no se envía tal mensaje, esta opción aplica solamente al protocolo ssh 2 esta opción útil cuando se tienen una conexión intermitente, y se requiere la sesión abierta sin que se cierre la sesión, yo lo uso :).

ClientAliveCountMax 3:

Este valor indica las veces que el servidor sshd enviara mensajes keepalive cuando el cliente esta inactivo, si el cliente no envia ninguna respuesta entonces el servidor terminara la conexion y por lo tanto la sesion, si tienes una conexiones intermitentes es recomendable subir el numero a este valor, hay que notar que esta opcion es diferente la opcion TCPKeepAlive, estos mensajes son enviados a través de el canal cifrado, por lo tanto no sera spoofable, como el TCPKeepAlive.

PidFile /var/run/sshd.pid

Esta opcion indica identificador de proceso (pid) de sshd.

Bien ahora que hable de las opciones de este bloque, usando los valores predeterminados, deberá quedar asi:

AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding no
X11DisplayOffset 10
X11UseLocalhost yes
PrintMotd yes
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression yes
ClientAliveInterval 0
ClientAliveCountMax 3
UseDNS yes
PidFile /var/run/sshd.pid
MaxStartups 10

Y por ultimo esta la opcion:

# override default of no subsystems
Subsystem       sftp    /usr/libexec/sftp-server

Esta opcion lo que hace es iniciar el servidor sftp-server el cual es un sustituto para un servidor ftp, pero la comunicacion es segura, ya que se hace por un canal cifrado.

Ahora a reiniciar el seasídor sshd, asi:

# /etc/rc.d/rc.sshd restart
WARNING: killing listener process only.  To kill every sshd process, you must
         use 'rc.sshd stop'.  'rc.sshd restart' kills only the parent sshd to
         allow an admin logged in through sshd to use 'rc.sshd restart' without
         being cut off.  If sshd has been upgraded, new connections will now
         use the new version, which should be a safe enough approach.

Antes de intentar conectarnos a el servidor borraremos el archivo ~/.ssh/known_hosts el cual mantiene el fingerprint de el servidor, pero como ahora nos conectaremos con DSA, no sera necesario almacenar la RSA, entonces ejecutamos:

usuario@cliente:~$ rm -rf .ssh/known_hosts

Bien, ahora intentaremos conectarnos nuevamente a el servidor ssh, asi:

usuario@cliente:~$ ssh usuario@localhost
The authenticity of host 'localhost (127.0.0.1)' can't be established.
DSA key fingerprint is b5:09:f9:a8:12:85:d8:30:64:f8:50:51:e1:da:c2:04.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (DSA) to the list of known hosts.
usuario@localhost's password:
Last login: Tue Jul 19 12:20:30 2005 from localhost
Linux 2.6.12.2.
usuario@cliente:~$

Como podemos ver, ahora no dice que la autenticidad de el host no puede ser establecida, y nos muestra el fingerprint de la llave DSA, hay que asegurarnos que sea igual a la que se genero cuando se inicio el servicio sshd.

En easí caso fue asi:

Generating public/private dsa key pair.
Your identification has been saved in /etc/ssh/ssh_host_dsa_key.
Your public key has been saved in /etc/ssh/ssh_host_dsa_key.pub.
The key fingerprint is:
b5:09:f9:a8:12:85:d8:30:64:f8:50:51:e1:da:c2:04 root@cliente

por lo que podemos dar 'yes' y confiar en ella.

Y ahora si todo esta listo y seguro, para empezar a trabajar remotamente con conexiones ssh, y asi poder administrar tu servidor o tu estacion de trabajo remotamente.

En la siguiente parte se hablara de como generar tu par de llaves DSA para autenticarse al servidor sshd por medio de las llaves publica/privada.

5. Usando Autenticacion con par de llaves publica/privada con SSH.

En la primera parte de este documento se configuro el servidor ssh básico, se hizo un login basico, en el cual nos autenticamos con un usuario y nos pide una contraseña, aveces cuando necesitas trabajar en un equipo remoto, es algo tedioso estar tecleando la contraseña a cada rato, y más cuando manejas más de 5 servidores,

El siguiente metodo se usara para tener un login seguro sin usar la contraseña de el usuario, se conectara de el equipo "cliente" a el servidor remoto "servidor" entonces en este metodo se logueara de "cliente" a "servidor" sin usar contraseña. Se asume que se tiene cuenta en ambas maquinas, y que es posible hacer login por ssh en las dos maquinas usando contraseña.

Se asume que actualmente estas logueado en "cliente".

El directorio $HOME de el usuario no debe de ser escribible y leible por alguien mas de el grupo al que pertenece el usuario u otros, solo ejecucion.

# chmod 711 /home/usuario

El directorio .ssh no debe de ser escribible y leible por alguien más de el grupo al que pertenece el usuario u otros, solo ejecutable.

$ chmod 700 /home/usuario/.ssh

Los archivos dentro de el directorio .ssh de el usuario deben de ser solamente con permisos de lectura y escritura para el usaurio (rw).

$ cd .ssh
$ chmod 600 *

Bien, cumpliendo los requerimientos anteriores podemos seguir.

Lo primero es crear un par de llaves (publica/privada) DSA.

Como usuario ejecutar:

$ cd .ssh
usuario@cliente:~/.ssh$ ssh-keygen -t dsa
Generating public/private dsa key pair.
Enter file in which to save the key (/home/usuario/.ssh/id_dsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/usuario/.ssh/id_dsa.
Your public key has been saved in /home/usuario/.ssh/id_dsa.pub.
The key fingerprint is:
1f:a7:05:ad:43:23:7c:95:d5:a8:ee:b6:ac:e3:2f:3e usuario@cliente
usuario@cliente:~/.ssh$

La primer pregunta que se hace es que elijamos el archivo donde se guardara la llave privada, por default es /home/usuario/.ssh/id_dsa, puedes dar enter para usar ese archivo. Despues se nos solicita una frase de entrada, esta no debe de ser una simple contraseña, se recomienda usar una frase larga y que sea alfanumerica, es decir, convinando Letras mayusculas, minusculas, numeros, y hasta otros simbolos, se recomienda que sea mas de 10 caracteres.

Esta passphrase se debe de teclear dos veces para confirmarla.

Y entonces nos dira:

Your identification has been saved in /home/usuario/.ssh/id_dsa.
Your public key has been saved in /home/usuario/.ssh/id_dsa.pub.
The key fingerprint is:
1f:a7:05:ad:43:23:7c:95:d5:a8:ee:b6:ac:e3:2f:3e usuario@cliente

Ahi dice que la llave privada se guardo en el archivo /home/usuario/.ssh/id_dsa y la llave publica se guardo en el archivo /home/usuario/.ssh/id_dsa.pub, y al final se muestra tu huella digital para esa llave.

Ahora hay que copiar nuestra llave publica a el servidor remoto, para asi poder autenticarnos con ella, esta autenticacion trabaja mas o menos asi, copiamos la llave publica al servidor, la comunicacion solo se puede establecer por quien pueda descifrar la llave publica, y claro solo podra ser por quien tenga la llave privada y aparte solo se podra usar la llave privada si se conoce el passphrase con la que se creo, es por eso recomendable siempre usar un passphrase largo y dificil no dejarlo vacio, dicha llave debe de tener permisos de "rw" solo para el dueño de dicha llave.

Entonces copiamos la llave publica al servidor remoto asi:

usuario@cliente:~/.ssh$ ssh-copy-id -i id_dsa.pub usuario@servidor
0
The authenticity of host 'servidor (192.168.0.1)' can't be established.
DSA key fingerprint is 7b:44:c4:ea:7a:f5:e2:5e:b8:36:06:ef:ff:cb:9e:f5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'servidor,192.168.0.1' (DSA) to the list of known
hosts.
usuario@servidor's password:
Now try logging into the machine, with "ssh 'usuario@servidor'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

usuario@cliente:~/.ssh$

En este paso se copio la llave publica con el comando ssh-copy-id, que le pasamos el parametro -i y el nombre de el archivo de la llave publica, y aparte el usario y nombre de host a donde la ibamos a copiar. Como vemos nos advirtio sobre la autenticidad de el host, y nos dice igual que siempre si deseamos agregar la llave DSA, por lo que decimos que "yes".Despues nos dice que ahora probemos logearnos a la maquina usando el comando: "ssh usuario@servidor" y revisar que el archvo ~/.ssh.authorized_keys exista, en ese archivo es donde se copio la llave publica, aunque el mismo ssh-copy-id configura los permisos de ~/.ssh y los archivos que contiene de el servidor remoto se recomienda comprobar que dicho directorio y archivo tenga los permisos adecuados, como se hizo en el host local (cliente).

Entonces lo comprobaremos:

$ ssh usuario@servidor
Enter passphrase for key '/home/usuario/.ssh/id_dsa':
Linux 2.4.31.
usuario@servidor:~$

Como vemos nos pide el passphrase de la llave privada, lo ingresamos y ya nos loguea :), si nos fijamos solo nos pidio el passphrase y no la contraseña esto porque ahora nos autenticamos con la llave publica.

Y vemos que los permisos de el directorio y el archivo este correctamente configurado.

Si cerramos la sesion ssh, y volvemos a intentar logearnos, nos volvera a pedir el passphrase, ahora veremos como evitar eso.

6. Entra ssh-agent.

ssh-agent, es un programa especialmente diseñado para hacer el trato con las llaves RSA y DSA más placentero y seguro, ssh-gent, a diferencia de ssh, es un daemon designado con el solo proposito de cachear la llave privada decifrada.

ssh incluye soporte incorporado que permite comunicarse con ssh-agent, permitiendo a ssh adquirir la llave privada decifrada sin perguntar por el passphrase para cada conexion. Con ssh-agent simplemente usas ssh-add para agregar tu llave privada al cache de ssh-agent. Este es un proceso llamado one-time process; osea que despues de usar ssh-add, ssh grabara la llave privada decifrada que tiene ssh-agent, en lugar de que pregunte cada vez el passphrase para las conexiones.

Usando ssh-agent

Ahora veamos como funciona el sistema de cacheo de ssh-agent. Cuando ssh-agent inicia, lanza algunas variables de entorno antes de salirse del shell y continuar corriendo en el background. este es un ejemplo generado por ssh-agent:

usuario@cliente:~/.ssh$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-gNVjIc6289/agent.6289; export SSH_AUTH_SOCK;
SSH_AGENT_PID=6290; export SSH_AGENT_PID;
echo Agent pid 6290;

Como puedes ver, la salida de ssh-agent en realidad son un par de comandos bash; si son ejecutados, estos comandos configuraran unas variables de entorno, SSH_AUTH_SOCK y SSH_AGENT_PID. Debido a que incluye el comando export, estas variables de entorno deberian de ser disponibles para cualquier programa que corra despues. Bueno, todo eso deberia de pasar, pero solo si esas lineas fueran evaluadas por el shell, pero solo son impresas en la salida estandar. Para solucionar esto, podemos invocar ssh-agent de la siguiente manera:

$ eval `ssh-agent`

Este comando le dira a bash que ejecute ssh-agent y evaluar su salida. Invocado de esta manera ( con las comillas ``, no comillas simples), las variables SSH_AGENT_PID y SSH_AUTH_SOCK seran definidas y exportadas por tu shell, haciendo estas variables disponibles para cada proceso que puedas iniciar en tu sesion.

La mejor manera de iniciar ssh-agent es agregar la linea de arriba a tu ~/.bash_profile; de esa manera, todos los programas que son iniciados en tu login veran esas variables de entorno, tambien seran capaces de localizar ssh-agent y consultarle por las llaves como sea necesario. La variable de entorno de particular importancia es SSH_AUTH_SOCK; esta contiene la ruta a un socket UNIX que ssh y scp pueden usar para establecer dialogos con ssh-agent.

ssh-agent inicia con una cache vacia de llaves privadas decifradas. Antes de que podamos usar ssh-agent, primero necesitamos agregar nuestra llave privada a el cache de ssh-agent usando el comando ssh-add. En el siguiente ejemplo, Uso ssh-add para agregar mi llave privada DSA ~/.ssh/id_dsa a el cache de ssh-agent:

usuario@cliente:~$ ssh-add ~/.ssh/id_dsa
Enter passphrase for /home/usuario/.ssh/id_dsa:
Identity added: /home/usuario/.ssh/id_dsa (/home/usuario/.ssh/id_dsa)
usuario@cliente:~$ 

Como puedes ver, ssh-add pregunto por el passphrase para que pueda ser decifrada la llave privada y almacenada en el cache de ssh-agent, lista para usarse. Una vez que haz usado ssh-add para agregar tu llave privada ( o llaves) a el cache de ssh-agent, y SSH_AUTH_SOCK es definido en tu shell actual ( lo cual deberia de ser, si es que iniciaste ssh-agent desde tu ~/.bash_profile), entonces puedes usar scp y ssh para establecer conecciones a sistemas remotos sin proveer el passphrase.

7. Limitantes de ssh-agent.

ssh-agent es realmente bueno, pero su configuracion por defecto todavia nos deja con unos inconvenientes menores. Veamoslos.

Para uno, con eval `ssh-agent` en su ~/.bash_profile, una nueva copia de ssh-agent es lanzada para cada login sesion; lo cual significa que necesitas usar ssh-add para agregar la llave privada a cada nueva copia de ssh-agent. Si solo abres una sola terminal o consola en tu sistema, esto no es una mala idea, pero la mayoria de nosotros abrimos varias terminales y necesitariamos teclear el passphrase cada vez que abrimos una consola. Tecnicamente, no hay razon de porque necesitariamos hacer esto puesto que un solo proceso de ssh-agent deberia de ser suficiente.

Otro problema con la configuracion de ssh-agent, es que no es compatible con los trabajos de cron. Puesto que los trabajos de cron son iniciados por el proceso cron, ellos no podran usar la variable de entorno SSH_AUTH_SOCK. y por lo tanto no sabra que un proceso de ssh-agnet esta corriendo, o como contactarlo.

8. Es aqui donde entra keychain.

keychain es un script en bash escrito por Daniel Robbins el cual permite el uso de un solo proceso de ssh-agent por sistema, no solo por sesion. Esto significa que solo necesitas hacer un solo ssh-add por llave privada. keychain tabien ayuda al optimizar el proceso ssh-add solo tratando de agregar las llaves privadas que no estan en el cache de el proceso ssh-agent.

Instalacion de keychain en Slackware 10.x:

# wget \
http://tuxjm.net/downloads/packages/Slackware-10.1/keychain/keychain-2.5.4.1-noa
rch-1.tgz

-- NOTA: Todo en una sola linea :D --

y ahora:

# installpkg keychain-2.5.3.1-noarch-1.tgz

Esta es la manera en que keychian trabaja cuando es iniciado desde ~/.bash_profile, primero revisara si algun ssh-agent esta actualmente corriendo. Si no, entonces iniciara ssh-agent y grabra las variables de entorno importantes SSH_AUTH_SOCK y SSH_AGENT_PID a el archivo ~/.keychain/$HOSTNAME-sh para uso posterior. Esta es la mejor manera de iniciar keychain:

Agregar las siguientes lineas a tu archivo ~/.bash_profile

# Load keychain
keychain --quiet ~/.ssh/id_dsa
[[ -f $HOME/.keychain/$HOSTNAME-sh ]] && \
  source $HOME/.keychain/$HOSTNAME-sh

9. Keychain en accion.

Una vez que haz configurado tu ~/.bash_profile para llamar a keychain en cada login, termina tu sesion y logueate de nuevo. Cuando lo hagas, keychain iniciara ssh-agent, grabara las variables de entorno de el agente y las definira en ~/.keychain/$HOSTNAME-sh y entonces te preguntara por tu passphrase por cada llave privada que especificaste como argumento en el comando keychain que usaste en ~/.bash_profile (en este caso fue: ~/.ssh/id_dsa).

PRIMERA VEZ EJECUTANDO keychain:

Enter passphrase for /home/usuario/.ssh/id_dsa:
Identity added: /home/usuario/.ssh/id_dsa (/home/usuario/.ssh/id_dsa)

Una vez que metas el passphrase, la llave privada sera cacheada, y keychain terminara. Entonces, ~/.keychain/$HOSTNAME-sh sera sourced :S, inicializando tu sesion para que sea usada con ssh-agent. Ahora si terminas la sesion y la vuelves a iniciar, te encontraras con que keychain encontrara el proceso existente de ssh-agent el cual no termino cuando cerraste la session. Ademas, keychain verificara que la llave privada que tu especificaste este en el cache de ssh-agent. Si no, entonces te preguntara por el passphrase apropiado para esa llave. si todo va bien, el proceso existente de ssh-agent todavia contendra la llave privada que previamente agregaste, esto significa que no se te sera perguntada nuevamente el passphrase:

$ ssh servidor
Last login: Tue Jul 19 13:39:10 2005 from usuario.dominio.tld
Linux 2.4.31.
usuario@servidor:~$ 

Felicitaciones; te acabas de logear y sears capaz de hacer ssh y scp a sistemas remotos, no necesitaste de hacer ssh-add despues de el login, y ssh y scp no te preguntara por el passphrase. De hecho, mientras que tu proceso inicial de ssh-agent siga corriendo, seras capaz de logearte y establecer conexiones ssh sin proveer una contraseña, es muy comun que tu proceso de ssh-agent continue corriendo hasta que la maquina sea reiniciada; y como esto lo estas haciendo en un sistema Linux, es posible que no tengas que teclear el passphrase por varios meses. jeje. Bienvenido a el mundo de conexiones seguras y sin contraseña con autenticacion RSA y DSA.

Ahora ve y crea varias sesiones abre varias terminales y veras que keychian siemper se amarrara a el proceso correcto de ssh-agent, no olvides que tambien puedes usar trabajos de cron y scripts que usen este proceso de ssh-agent, si usas los comandos ssh o scp desde algun script o trabajo de cron, no olvides que ellos hagan source el archivo ~/.keychain/$HOSTNAME-sh:

source ~/.keychain/$HOSTNAME-sh

Por ejemplo en cliente, puedes hacer esto:

$ crontab -e

Para editar la tabla de trabajos cron para tu usuario, y agregar al final una linea por ejemplo:

# Sync notes file.
20 4 * * *     source ~/.keychain/usuario-sh; \
/usr/bin/scp /home/usuario/notes usuario@servidor:./dir-backup

Esto para que puedan hacer uso de el proceso ssh-agent. y puedan hacer conexiones sin contraseña tal y como lo haces en tu shell.

10. Autenticacion a servidores remotos con ssh usando solamente autenticacion con el par de llaves publica/privada DSA.

Si seguiste el documento completo haz llegado hasta aqui y ya podras autenticarte a el equipo remoto por medio de tu par de llaves y quizas estes usando keychain. si no te recomiendo que te regreses y revises los pasos que se explicaron anteriormente.

En la seccion donde se habla de la configuracion de el servidor vimos varias opciones que hablan sobre la autenticacion por usuario/contraseña y otras para la autenticacion con el par de llaves, en esta parte de el documento se explicara como configurar el sistema para que solo se use la autenticacion por medio de tu par de llaves, para asi evitar que alguien se autentique con un usuario y pueda ingresar una contraseña, esto es util para equipos que estan dando la cara a Internet no queremos que tengan posibilidad de logearse con algun usuario y contraseña que puedan adivinar.

Primero desactivaremos la opcion que se refieren a el uso de autenticacion por medio de usuario/contraseña, dicha opcion son:

PasswordAuthentication yes

Y la cambiaremos a:

PasswordAuthentication no

Esto se hace en el sistema remoto en donde queramos desactivarlo.

Una vez que hayas cambiado esa opcion se debera de reiniciar el servidor sshd.

# /etc/rc.d/rc.sshd restart

Ahora en la maquina cliente debere

Para probar esta configuracion moveremos nuestro directorio ~/.ssh a ~/ssh-backup

Esto para que no usar nuestra llave privada y asi simular que nos trataramos de autenticar con usuario/contraseña, entonces en la maquina cliente hacemos:

$ mv .ssh ssh-backup

Y ahora limpiaremos la informacion que hizo keychain, para asi limpiar el cache de ssh-agent.

$ keychain --clear

KeyChain 2.5.4.1; http://www.gentoo.org/proj/en/keychain/
Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL

 * Found existing ssh-agent (7512)
 * Found existing gpg-agent (7532)
 * ssh-agent: All identities removed.
 * gpg-agent: All identities removed.
$ keychain -k all

KeyChain 2.5.4.1; http://www.gentoo.org/proj/en/keychain/
Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL

 * All usuario's ssh-agent(s) (7512) are now stopped
 * All usuario's gpg-agent(s) (7532) are now stopped

Ahora nos trataremos de autenticar a "servidor":

$ ssh usuario@servidor
The authenticity of host 'servidor (192.168.0.1)' can't be established.
DSA key fingerprint is 7b:44:c4:ea:7a:f5:e2:5e:b8:36:06:ef:ff:cb:9e:f5.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'servidor,192.168.0.1' (DSA) to the list of known
hosts.
Permission denied (publickey,keyboard-interactive).

Como vemos nos dice que nos denego el acceso, esto es porque no encontro ninuna llave para autenticarse y no permite la autenticacion por usuario/contraseña. :D

Ahora removeremos el directorio .ssh que se acaba de crear al agregar nuevamente el archivo ~/.ssh/known_hosts

$ rm -rf .ssh

Y restauraremos nuestro directorio donde respaldamos el directorio bueno de .ssh:

$ mv ssh-backup .ssh

Ahora se recomienda hacer source a el archivo ~/.bash_profile para que vuelva a ejecutar keychain y pueda almacenar la llave privada descifrada en el cache de ssh-agent:

$ source ~/.bash_profile
Enter passphrase for /home/usuario/.ssh/id_dsa:
Identity added: /home/usuario/.ssh/id_dsa (/home/usuario/.ssh/id_dsa)

Ahora prueba autenticarte a "servidor"

$ ssh servidor
Last login: Tue Aug 9 13:39:10 2005 from usuario.dominio.tld
Linux 2.4.31.
usuario@servidor:~$

Listo ahora la autenticacion solo se hace por medio de tu par de llaves.

11. Limitando acceso por usuario o grupo.

Como ultimo si en el servidor remoto se manejan varios usaurios locales con shell, pero no a todos se les quiere dar acceso a shell remoto por ssh, se pueden usar unas opciones para que solo a algunos usuarios o grupos puedan conectarse al equipo de manera remota por medio de ssh, dichas opciones son:

AllowUsers

Esta opcion puede ser usada poniendo una lista de nombres de usuario separada por espacio, si se usa solo se permiten nombres de usuarios, los numeros de ID de el usuario no son reconocidos.

Para más detalles de esta opcion lo puedes ver en la pagina del manual de sshd_config ( man sshd_config).

La opcion que se usa para permitr un grupo es:

AllowGroups

Esa opcion puede ser usada poniendo una lista de nombres de grupos separada por espacio, si se usa solo se permiten nombres de grupos, los numeros de ID de los grupos no son reconocidos.

Para más detalles de esta opcion lo puedes ver en la pagina del manual de sshd_config ( man sshd_config).

Por ejemplo puedes usar:

AllowUsers usuarioadmin usuarioamigo

12. Limite de acceso por llaves.

Como un paso opcional para limitar el uso de la llave publica para accesar a cualquier servidor, la directiva "from" puede ser usada antes de la entrada de la llave publica en el archivo ~/.ssh/authorized_keys en el servidor para limitar de donde el sistema cliente es permitod accesar el servidor. Sin el limite de "from" cualquier sistema cliente con la llave privada apropiada sera capaz de conectarse al servidor desde cualquier lado. Si el par de llaves solo sera usado desde el cliente que se conecta por ejemplo de el host hostadmin.dominio.tld o el que tiene la direccion IP 192.168.1.2 configura from="hostadmin.dominio.tld" antes de los datos de la llave publica.

servidor$ cat ~/.ssh/authorized_keys
from="hostadmin.dominio.tld" ssh-dss AAAAB3Nz...

Puedes usar tambien comodines por ejemplo para usar algo asi:

from="*.dominio.tld" ssh-dss AAAAB3Nz...

Si se usa un editor de texto para agregar la opcion "from", asegurate que los datos son guardados en una sola linea; algunos editores de texto pondran linea de la llave publica en dos lineas, (wrap) y corromperan los datos. Cada llave publica en el archivo ~/.ssh/authorized_keys debe ser una linea.

Multiples hosts o direcciones IP pueden ser especificadas como valores separados por coma. por ejemplo:

from="*.dominio.tld, 192.168.1.2" ssh-dss AAAAB3Nz...

Para mas informacion sobre la sintaxis de la opcion "from" ver la documetacion de sshd(8).

13. Conclusion.

Bien, creo que despues de no se cuantas lineas de tanta palabreria sobre la configuracion de el servidor sshd y el uso de autenticacion por medio de llaves ha quedado claro y ahora podras autenticarte de manera segura a equipos remotos y usando las ventajas de keychain para cachear la llave privada descifrada.

Para más informacion sobre ssh se recomienda leer la pagina del manual de sshd_config:

$ man sshd_config

Tambien puedes leer la pagina del manual de keychain para que veas las demas opciones que podrias utilizar:

$ man keychain

Espero que este documento haya sido de utilidad para quien lo lea.

Ahora si el tan esperado

FIN

14. Referencias

OpenSSH key management

Keychain