Claves SSH distintas para distintos servidores

Publicado por Diego Córdoba en

openssh_logo claves ssh

Si somos adictos al ssh, y lo usamos para conectarnos a varios servidores remotos, una buena técnica es usar claves públicas y privadas para no tener que typear las contraseñas. Si esos servidores usan distintos pares de claves publica-privada, deberíamos especificar, en cada llamada a ssh, qué clave usar. Hoy veremos cómo automatizar la selección de las claves privadas cuando accedemos a distintos servidores.

¿SSH es un protocolo para conexión de terminal remota? Sí, es eso, y mucho más. SSH es un protocolo de establecimiento de túnel seguro (cifrado) a nivel de capa de aplicación de TCP/IP.

En un artículo anterior estuvimos comentando cómo autenticar un usuario contra un servidor usando claves SSH asimétricas. Imaginemos que estamos administrando 10 servidores de la misma manera. Generamos el par de claves en nuestro cliente ssh, y enviamos la clave pública al archivo authorized_keys de los 10 servidores… hasta ahí muy bonito.

Ahora imaginemos que por alguna cuestión de seguridad (alguna vez comentamos de heartbleed por ejemplo), o torpeza nuestra, se compromete el archivo de clave privada de nuestro equipo. Eso significa que alguien podría hacerse con la clave y conectarse a los 10 servidores haciéndose pasar por nosotros, con todos los accesos que tenemos nosotros.

Conclusión hasta aquí, administrar varios equipos utilizando una sola clave privada puede llegar a ser un riesgo.

En esta entrega comentaré brevemente cómo podemos conectarnos a varios servidores remotos utilizando claves asimétricas SSH diferentes, una para cada servidor.

Generando las claves ssh

Este paso es exactamente igual al que comentamos acá. Supongamos un caso de prueba en el que con nuestro cliente vamos a conectarnos a dos servidores cuyas direcciones IP son 10.0.0.20 y 10.0.0.60.

Generemos las claves ssh para ambos, con sus respectivos nombres:

diego@cryptos:~$ ssh-keygen -f ~/.ssh/id_rsa_vm20
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/diego/.ssh/id_rsa_vm20.
Your public key has been saved in /home/diego/.ssh/id_rsa_vm20.pub.
The key fingerprint is:
SHA256:uO7P+yZJ7/JGiE1oWR6R6WlKxUt/bk9q5v9Kvd4h8Jg diego@cryptos
The key's randomart image is:
+---[RSA 2048]----+
|       ..+       |
|        O        |
|       O =       |
|      =.B . .    |
|     o.*S. +     |
|      o.+ . B .. |
|      .. + E *...|
|     . .+ + +.o +|
|     .o.+X++..+=o|
+----[SHA256]-----+
diego@cryptos:~$ ssh-keygen -f ~/.ssh/id_rsa_vm60
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/diego/.ssh/id_rsa_vm60.
Your public key has been saved in /home/diego/.ssh/id_rsa_vm60.pub.
The key fingerprint is:
SHA256:9bIFz1AEDNK6kVsdhrRv7nbNu+M6DqilbU6C3qWAL1k diego@cryptos
The key's randomart image is:
+---[RSA 2048]----+
|      .oo+.oo    |
|       .o.+.     |
|       o.o+.     |
|      + .o.*     |
|       =S + =    |
|   .E.o  + +     |
|  .oo . = +  o   |
|  oo o X....o +  |
|   .o =oo..oo+++ |
+----[SHA256]-----+

Copiando las claves ssh a sus respectivos sitios

Ahora copiamos las claves ssh a los equipos correspondientes, dentro de los authorized_keys de los usuarios. En los ejemplos se supone que el servicio SSH está atendiendo en el puerto predeterminado, si está corriendo en un puerto distinto, se puede añadir la opción -p XXXX al comando ssh-copy-id, donde XXXX es el puerto en el que corre el servicio.

Copiando la clave del usuario «usuario» del server 10.0.0.20:

diego@cryptos:~$ ssh-copy-id -i .ssh/id_rsa_vm20.pub usuario@10.0.0.20
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa_vm20.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
usuario@10.0.0.20's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'usuario@10.0.0.20'"
and check to make sure that only the key(s) you wanted were added.

Para el usuario «alumno» del server 10.0.0.60:

diego@cryptos:~$ ssh-copy-id -i .ssh/id_rsa_vm60.pub alumno@10.0.0.60
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa_vm60.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
alumno@10.0.0.60's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'alumno@10.0.0.60'"
and check to make sure that only the key(s) you wanted were added.

Listo, ya tenemos las claves para poder entrar a cada uno de los servidores. Como son distintas, para conectar, en primera instancia, deberíamos invocar a cada clave de esta forma:

#Conectando al server 10.0.0.20:
ssh -i ~/.ssh/id_rsa_vm20 usuario@10.0.0.20

#Conectando al server 10.0.0.60:
ssh -i ~/.ssh/id_rsa_vm60 alumno@10.0.0.20

Configurando nuestro cliente SSH

Ahora llegó la hora de editar las configuraciones de nuestro cliente ssh personal, es decir, cómo le decimos al cliente que use X clave para conectarse a tal server, o Y clave para hacerlo con cual server.

Para ello, editamos el archivo de configuración personal de nuestro cliente. Es el archivo ~/.ssh/config, puede estar vacío, o puede no estar, para lo cual deberá crearse un archivo de texto en blanco y añadir la configuración.

diego@cryptos:~$ cat ~/.ssh/config
Host 10.0.0.20
 HostName 10.0.0.20
 User usuario
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/id_rsa_vm20

Host 10.0.0.60
 HostName 10.0.0.60
 User alumno
 PreferredAuthentications publickey
 IdentityFile ~/.ssh/id_rsa_vm60

Donde:

  • Host: es un alias para el nombre de host, que nos permita recordarlo. Yo he puesto la dirección IP en este ejemplo para evitar confusiones.
  • Hostname: es la dirección IP o nombre del servidor al que vamos a conectarnos.
  • User: es el usuario remoto con el cual vamos a autenticarnos (debe ser el que posee nuestra clave pública en su authorized_keys).
  • PreferredAuthentications: indica el método o métodos de autenticación utilizados para conectarnos a este host. He seleccionado publickey para la autenticación con clave asimétrica, pero hay varios, password para contraseña por ejemplo, etc.
  • IdentityFile: indica el archivo de clave privada utilizado para conectarnos. Debe ser el par de la clave publica que «subimos» al authorized_keys del servidor.

NOTA: otros parámetros de configuración del cliente pueden leerse en el man 5 ssh_config (o acá). El listado también figura en el man ssh bajo la opción -o (también acá).

Testeando la conexión

Ahora la prueba de fuego, vamos a conectarnos! Al igual que con el comando ssh-copy-id, si el servidor SSH está atendiendo en un puerto diferente del predeterminado, deberá agregarse la opción -p XXXX a los comandos ssh, donde XXXX es el puerto en el que está corriendo el servidor.

Conectando al host 10.0.0.20:

diego@cryptos:~$ ssh usuario@10.0.0.20
Linux debian2 2.6.32-5-686 #1 SMP Tue Mar 8 21:36:00 UTC 2011 i686
mantenimiento a las 14
You have new mail.
Last login: Thu Sep  6 19:35:04 2012 from 10.0.0.10
usuario@debian2:~$ exit
logout
Connection to 10.0.0.20 closed.

Conectando al host 10.0.0.60:

diego@cryptos:~$ ssh alumno@10.0.0.60
Linux curso 3.2.0-4-486 #1 Debian 3.2.41-2+deb7u2 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
You have new mail.
Last login: Tue Jun 30 21:37:50 2015
alumno@curso:~$ exit
logout
Connection to 10.0.0.20 closed.

La prueba ha sido un éxito 🙂

Notas adicionales

Por un lado, aclarar que en el caso de que un cliente no conecte y siempre nos pida contraseña, podremos optar por agregar las claves privadas de conexión a nuestro agente de autenticación local utilizando ssh-add de la siguiente forma:

diego@cryptos:~$ ssh-add .ssh/id_rsa_vm20
Identity added: .ssh/id_rsa_vm20 (.ssh/id_rsa_vm20)
diego@cryptos:~$ ssh-add .ssh/id_rsa_vm60
Identity added: .ssh/id_rsa_vm60 (.ssh/id_rsa_vm60)

Si ahora listamos las claves ssh agregadas:

diego@cryptos:~$ ssh-add -l
2048 SHA256:uO7P+yZJ7/JGiE1oWR6R6WlKxUt/bk9q5v9Kvd4h8Jg .ssh/id_rsa_vm20 (RSA)
2048 SHA256:9bIFz1AEDNK6kVsdhrRv7nbNu+M6DqilbU6C3qWAL1k .ssh/id_rsa_vm60 (RSA)

Por otro lado, cabe añadir que si disponemos de varias claves privadas y no sabemos con cual debemos autenticarnos, podemos especificar varias líneas «IdentityFile» para que vaya probando una clave por vez. Esto no debería ser una generalidad, nosotros creamos las claves (o algún proveedor de cloud/hosting nos las dio), así que deberíamos saber qué clave usar en cada caso.

Dejo pendiente un artículo sobre ssh-agentcoming soon.

Espero les sirva! Cualquier duda o comentario están invitados a escribir, y por supuesto, a compartir si les resulta útil!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador

2 comentarios

Samuel Martinez Gonzalez · 14 enero, 2018 a las 05:59

Hola compañero, excelente tutorial, yo lo que quiero es que al establecer conexion en un servidor pueda conectar a la misma vez en otros servidores, me dijeron que es mediante claves ssh, he generado las claves en mi servidor con conexion ssh mediante el comando:

ssh-keygen

Puse los archivos a una carpeta temporal del servidor,
y pase la clave pública al listado de claves autorizadas mediante este comando:

cat /tmp/id_rsa.pub >> authorized-keys

rm /tmp/id_rsa.pub

Ahora no tengo nidea que mas hacer, nose si copiar esos archivos a mis otros servidores y ya estaria, o no lo se
el hecho es que quiero registrar a alguien en mi web y quiero realizar una conexion mysql en los 3 servidores para poder mandar datos a la base de datos de los 3, incluso recibir datos de esos 3 servidores al servidor principal de la web.

No se si me entiendes, por lo menos aprendi a conectarme mediante ssh por putty desde windows, que no sabia xD, si hay alguna forma de que me ayudes con esto te lo agradeceria 1000 veces.

Un Saludo Compy.

    Diego Cordoba - @d1cor · 31 enero, 2018 a las 02:15

    Hola Samuel! Sinceramente no llego a entender qué es lo que necesitás puntualmente… si se trata de que vos desde tu computadora te conectes mediante ssh a un servidor, y desde esa consola de servidor te conectes, también mediante ssh, a otros servidores, el tratamiento es el mismo:

    Primero generás mediante ssh-keygen las claves en tu computadora. Luego podés copiarlas a tu servidor mediante el comando:

    ssh-copy-id -i ~/.ssh/id_rsa.pub usuario@ip_servidor

    Este comando evita la comprometer las claves, y utilizar el directorio temporal /tmp. Ese comando te va a pedir la contraseña para el usuario en ese servidor, y por única vez.

    Una vez que hiciste eso, vas a poder conectarte utilizando el comando:

    ssh usuario@ip_servidor

    Y no debería pedirte clave.

    Una vez adentro del servidor, simplemente generás las claves del servidor con el mismo ssh-keygen, y las copiás a otro servidor con algo similar a:

    ssh-copy-id -i ~/.ssh/id_rsa.pub usuario@ip_otro_servidor

    Te va a pedir la contraseña para el usuario en el otro servidor, y por única vez.

    Luego, mediante:

    ssh usuario@ip_otro_servidor

    Vas a poder conectarde, desde adentro del primer servidor, al segundo.

    Nuevamente, esto es segun lo que entiendo de tu mensaje, pero necesitaría más información para poder ayudarte con mas detalle.

    Espero te aclara un poco!

    Saludos!

Los comentarios están cerrados.