Home Linux Conexión segura SSH Con clave pública y privada

Conexión segura SSH Con clave pública y privada

by José Luis Sánchez Borque
200415-ssh-con-clave

En este Post os voy a mostrar como conectarnos a un servidor SSH sin la necesidad de introducir la contraseña cada vez. Podemos conseguirlo utilizando un par de claves asimétricas.

Podemos preguntarnos que ventajas tenemos al utilizar este método, en vez de utilizar una contraseña. Os añado algunas de las ventajas:

  1. No tenemos que recordar la contraseña, y de paso evitamos que al introducirla al conectarnos contra el servidor alguien pueda “robarla” mediante alguna técnica Man In The Middle. Si bien es cierto, que para aumentar la seguridad de este tipo de conexión recomiendan añadir una “Key PassPhrase” (lo vemos más adelante en este Post). Con esto estamos en las mismas… Tenemos que acordarnos de la PassPhrase.., aunque la seguridad de la encriptación es mucho mayor.
  2. Mejoramos el cifrado de la conexión, con lo que aumentamos considerablemente la seguridad.
  3. Podemos automatizar muchos procesos, como copias de seguridad entre diferentes dispositivos de forma segura, al estar la información encriptada. Por ejemplo con Rsync.
  4. Podemos montar un sistema de archivos remoto con SSHFS. Al poder acceder sin contraseña, podemos hacer que el servidor SSHFS se monte de forma automática al arrancar el servidor.
  5. Para automatizar cualquier tipo de tarea entre un servidor y un cliente.
  6. Existen además múltiples servidores y servicios que utilizan autenticación mediante clave pública SSH. Por ejemplo servidores GIT

Un gran inconveniente es la clave privada que permitirá conectarse al servidor….. Si la perdemos estamos “muertos”… Debemos tenerla a buen recaudo. Esto es el principal argumento de todos los que critican el uso de este tipo de autenticación. Aunque bien es cierto, que también existen otras basadas en JSON, etc.. que implica el mismo riesgo. Igualmente existe la posibilidad de revocar los certificados y generar nuevos si pensamos que la seguridad está comprometida.

Existen varios escenarios posibles. En este Post vemos dos de ellos

  • Generar claves pública y privada en el servidor SSH, para conexión segura con un cliente. Por ejemplo con PUTTY desde un Windows. Esto lo utilizan muchos proveedores de alojamiento como SiteGround.
  • Generar clave pública y privada con PUTTY para subir la clave al servidor ssh y conectarnos de forma segura.
  • Generar claves pública y privada en un cliente Linux, y subir la clave al servidor Linux para conectarnos de forma segura.

En este Post voy a explicar el 1er y 3er caso. Si alguno le interesa como se puede generar el par de claves desde el mismo PuTTY y subirlas al servidor.. solo tiene que ponerse en contacto conmigo a través de la sección contacto de mi BLOG

Generar claves en Servidor SSH Ubuntu para conectarnos desde un cliente PUTTY


En primer lugar deciros que estoy trabajando con un Ubuntu Server 18.04

demo@nft-fw:~$ lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic

En primer lugar debemos asegurarnos que tenemos el paquete openssh-server instalado. Está claro que si nos podemos conectar vía Putty o cualquier otra aplicación es que está ?

Pero para ver instrucciones del mundo Linux y aprender un poco más…. Podemos utilizar algunas órdenes que nos darán información al respecto:

Ver si el paquete openssh-server está instalado:

demo@nft-fw:~$ apt-cache search openssh-server

openssh-server - servidor de terminal seguro (SSH) para acceder de forma segura desde máquinas remotas

Ver si el servidor está en marcha y activo:

demo@nft-fw:~$ service sshd status

● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enab
Active: active (running) since Wed 2020-04-15 16:41:40 CEST; 1h 2min ago
Process: 1434 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
Main PID: 1445 (sshd)
Tasks: 1 (limit: 2290)
CGroup: /system.slice/ssh.service
└─1445 /usr/sbin/sshd -D
abr 15 16:41:40 nft-fw systemd[1]: Starting OpenBSD Secure Shell server...
abr 15 16:41:40 nft-fw sshd[1445]: Server listening on 0.0.0.0 port 22.
abr 15 16:41:40 nft-fw sshd[1445]: Server listening on :: port 22.
abr 15 16:41:40 nft-fw systemd[1]: Started OpenBSD Secure Shell server.
abr 15 16:42:07 nft-fw sshd[1458]: Accepted publickey for demo from…

Empezaremos generando el par de claves:

  • Clave Pública que debe estar en el servidor SSH
  • Clave Privada que la tendremos que pasar al Cliente para que se conecte

Recordar que me he validado con el cliente que luego utilizará para conectarme, en mi caso se llama: demo

demo@nft-fw:~$

Para generar las claves

demo@nft-fw:~$ ssh-keygen -b 2048 -t rsa
-b 2048  La clave asimétrica se genera con un tamaño de 2048 bits. Podríamos poner 1024 o 4096 por ejemplo. Recordar que a mayor tamaño mayor impacto en CPU
-t rsa El algoritmo usado para generar el par de claves. Otros que podemos usar con dsa, ecdsa, rsa1 y ed25519

Veamos la secuencia de acciones:

demo@nft-fw:~$ ssh-keygen -b 2028 -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/home/demo/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/demo/.ssh/id_rsa.
Your public key has been saved in /home/demo/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:ShoQsMsPazHJS/Xco/vIs4aEBZzJF3Hx5UaVc09opfk demo@nft-fw
The key's randomart image is:
+---[RSA 2028]----+
|+.+ooo. o... o. |
| B o. . + o +o. |
|. +. . o +oo |
|o.ooo . . .. |
|.Oo .o.oS E |
|..B. +... |
| +..o.. |
|. ..oo |
| .=+. |
+----[SHA256]-----+

Os he puesto en rojo dos temas a comentar…

(/home/demo/.ssh/id_rsa) La ruta donde almacenamos el par de claves. La podemos cambiar, pero en nuestro caso la dejamos en la ruta por defecto.
Enter passphrase El caballo de batalla de mucha gente.. Si esto está para ahorrarnos la memorización de contraseñas, para que tenemos que poner uns PassPhase?????

Recordaros que mejora la seguridad, puesto que podemos poner toda una frase entera.. Pero si la ponemos requerirá que la introduzcamos.. luego no servirá para automatizar procesos.

Recordar también que la Passphrase sin la clave privada, o viceversa no sirvan para nada.

En mi ejemplo la he dejado sin poner, para que veáis que nos conectaremos de forma directa.

Quien quiera saber algo más al respecto en la Web de Use a PassPhase os da más información a nivel de seguridad de lo que implica ponerla o no… La imagen adjunta os resume muy bien lo que implica ?

200415-descarga-clave-privada-con-winscppassphrase-time-to-crack

“Para los de la Logse”… Centuria son 100 años..

Ya tenemos las dos claves generadas, ficheros is_rsa (clave privada) y is_rsa.pub (clave pública):

demo@nft-fw:~$ ls /home/demo/.ssh/ -la

drwx------ 2 demo demo 4096 abr 15 17:51 .
drwxr-xr-x 7 demo demo 4096 abr 15 17:47 ..
-rw------- 1 demo demo 1651 abr 15 17:51 id_rsa
-rw-r--r-- 1 demo demo 389 abr 15 17:51 id_rsa.pub

Podéis echar un vistazo con #cat id_rsa y #cat id_rsa.pub para ver su contenido.

Bien, para configurar nuestro servidor, y permitir que el usuario demo se conecte con la clave privada id_rsa, debemos generar el fichero authorized_keys y copiar dentro la clave pública, es decir id_rsa.pub:

demo@nft-fw:~$ cat /home/demo/.ssh/id_rsa.pub >> /home/demo/.ssh/authorized_keys

demo@nft-fw:~$ ls /home/demo/.ssh/ -la

drwx------ 2 demo demo 4096 abr 15 18:03 .
drwxr-xr-x 7 demo demo 4096 abr 15 17:47 ..
-rw-rw-r-- 1 demo demo 1651 abr 15 18:03 authorized_keys
-rw------- 1 demo demo 1651 abr 15 17:51 id_rsa
-rw-r--r-- 1 demo demo 389 abr 15 17:51 id_rsa.pub

De hecho el contenido de id_rsa.pub y authorized_keys es el mismo.

Importante. He utilizado la dobre pipe «>>» para el fichero authorized_keys. Eso es porque el fichero puede contener más de una clave, y por lo tanto lo que hago es añadir la clave pública (id_rsa.pub) al final del fichero. Si este no existiera se crea igualmente.

Hay que ajustar los permisos adecuadamente, de tal forma que solo el usuario en cuestión tenga permisos de r y w. Ni el Grupo ni Others.. Fijamos también la pertenencia de propietario y grupo: demo:demo

demo@nft-fw:~/.ssh$ ls -la

drwx------ 2 demo demo 4096 abr 15 18:03 .
drwxr-xr-x 7 demo demo 4096 abr 15 17:47 ..
-rw------- 1 demo demo 389 abr 15 18:04 authorized_keys
-rw------- 1 demo demo 1651 abr 15 17:51 id_rsa
-rw------- 1 demo demo 389 abr 15 17:51 id_rsa.pub

De no estar como os indico, debéis utilizar chmod para ajustar los permisos.

Pues ya casi estamos.. Nos bajamos la clave privada a nuestro Windows. Yo he utilizado WinSCP para conectarme al servidor y descargarla dentro de la carpeta C:\Users\usuario\Documents\PUTTY-CLAVE PRIVADA :

200415-descarga-clave-privada-con-winscp

Nos queda un pequeño paso.. Debemos convertir la clave privada id_rsa a formato ppk entendible para el PUTTY.

Para ello, y si hemos instalado, no solo el putty.exe, sino el fichero msi encontraremos varias utilidades en la carpeta de instalación.

200415-descarga-putty

En concreto debemos ejecutar el programa PuTTYgen que se encuentra en la misma carpeta que PUTTY.

200415-archivo-puttygen

Una vez lo ejecutemos es muy sencillo. Debemos seleccionar el mismo método de encriptación, RSA, y longitud de clave, 2048, que al generar el par de claves. Luego la opción de menú Conversions debemos seleccionar Importe Key:

200415-importar-clave-putty

Seleccionamos el fichero id_rsa que nos hemos descargado anteriormente, en mi caso con la aplicación WinSCP

200415-almacenarla

Nos aparece la clave privada en si, y le daremos a la opción “Save private Key”. Nos dirá si estamos seguros de grabarla PassPhrase.. Antes no la hemos puesto, y aquí tampoco debemos ponerla. En mi caso la grabo en la misma carpeta con el nombre de clave-privada.ppk

200415-clave-almacenada-formato-putty

Pues ya estamos… Ahora abrimos la aplicación PuTTY y ponemos la dirección IP y el puerto del servidor.

200415-abrir-conexion-putty

Antes de darle al Open, debemos indicarle la clave privada que hemos generado en la opción SSH indicada por la fecha en la imagen superior.

200415-abrir-conexion-putty-clave-privada

Y ahora si.. Le damos a Open y una vez introducido el usuario, demo en nuestro caso, no nos pide la contraseña para validarnos:

200415-conexion-con-exito

Todo por el bien de la seguridad y la automatización de procesos… no os olvides. Os mostraré un ejemplo cuando lo hagamos de Linux a Linux..

De Linux a Linux


En este caso el objetivo es conectarnos desde un sistema Linux (cliente) a otro sistema Linux (Server). Las claves las vamos a generar en el cliente.

Veamos mi escenario:

Sistema Cliente: Kali Linux, con IP 192.168.153.133

root@gkali:~# lsb_release -a

No LSB modules are available.
Distributor ID: Kali
Description: Kali GNU/Linux Rolling
Release: 2020.2
Codename: kali-rolling

Usuario: root

Sistema Servidor: Ubuntu Server, con IP 192.168.153.137

demo@nft-fw:~$ lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic

Usuario: demo

El objetivo es conectarnos desde la máquina Cliente Kali Linux al servidor SSH Ubunto con el usuario demo. Los pasos para no olvidar lo que estamos haciendo:

  1. Generar las claves en el cliente Kali.
  2. Pasar la clave Pública al servidor Ubuntu son el comando scp o con el script ssh-copy-id
  3. Conectarnos desde el cliente Kali al servidor Ubuntu con la clave privada y ver que podemos y que no nos pide contraseña.

Generar las claves en el cliente Kali Linux

En mi caso he creado una carpeta para guardar las claves dentro por tema organizativo.

root@gkali:~# pwd

/root

root@gkali:~# mkdir demo
root@gkali:~# ls -la

drwxr-xr-x 26 root root 4096 abr 15 19:13 .
drwxr-xr-x 18 root root 4096 abr 14 18:54 ..
-rw------- 1 root root 30347 abr 15 19:03 .bash_history
-rw-r--r-- 1 root root 3391 nov 25 11:31 .bashrc
drwx------ 9 root root 4096 abr 12 10:33 .cache
drwxr-xr-x 16 root root 4096 abr 12 10:35 .config
drwxr-xr-x 2 root root 4096 abr 15 19:13 demo

Generamos el par de claves como lo hemos hecho anteriormente, salvo que por organización las guardo en la carpeta /root/demo

root@gkali:~# ssh-keygen -b 2048 -t rsa

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): /root/demo/id_rsa
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/demo/id_rsa
Your public key has been saved in /root/demo/id_rsa.pub
The key fingerprint is:
SHA256:xHl978s8ZPXV96aluuMfyVDq/0kwCkxlIuPlDc/6hgc root@gkali
The key's randomart image is:
+---[RSA 2048]----+
| o + o |
| ..=.O. |
| .+o.+. o .|
| .o.. + .=|
| SE oo B|
| =..oo==|
| . =. **.|
| o ..*oo|
| .+=o*o|
+----[SHA256]-----+

Vemos que se han generado correctamente la clave privada y la pública:

root@gkali:~# ls /root/demo/ -la

drwxr-xr-x 2 root root 4096 abr 15 19:15 .
drwxr-xr-x 26 root root 4096 abr 15 19:13 ..
-rw------- 1 root root 1823 abr 15 19:15 id_rsa
-rw-r--r-- 1 root root 392 abr 15 19:15 id_rsa.pub

Copiar clave pública al servidor remoto

En mi caso voy a utilizar el script ssh-copy-id :

root@gkali:~/demo# pwd

/root/demo

root@gkali:~/demo# ssh-copy-id -i id_rsa.pub demo@192.168.153.137

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "id_rsa.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
demo@192.168.153.137's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'demo@192.168.153.137'"
and check to make sure that only the key(s) you wanted were added.

Parámetros:

-i id_rsa.pub Ruta y nombre de la clave pública. Si no se la especifico la buscará en /root/.ssh, y os recuerdo que yo la he puesto en /root/demo
demo@192.168.153.137 Usuario y máquina remota a la que nos conectamos. El servidor Ubuntu

Ahora os añado desde el servidor Ubuntu que ha dejado la orden ssh-copy-id. Os añado las órdenes hostname, whoami, pwd y ls para que veáis: en qué máquina estoy ( Ubuntu Server que se llama nft-fw), quien soy (usuario demo), en que carpeta estoy (/home/demo/.ssh) del servidor Ubuntu y que ha dejado dentro y con que permisos (authorized_keys)

demo@nft-fw:~/.ssh$ hostname

nft-fw

demo@nft-fw:~/.ssh$ whoami

demo

demo@nft-fw:~/.ssh$ pwd

/home/demo/.ssh

demo@nft-fw:~/.ssh$ ls -la

drwx------ 2 demo demo 4096 abr 15 19:18 .
drwxr-xr-x 7 demo demo 4096 abr 15 17:47 ..
-rw------- 1 demo demo 392 abr 15 19:18 authorized_keys

Bien, si el script no funciona…. Siempre podéis recurrir al scp de toda la vida del Señor…

root@gkali:~/demo# scp id_rsa.pub demo@192.168.153.137:/home/demo/.ssh/authorized_keys

Ojo esto solo copiaría de la máquina Kali Linux la clave pública id_rsa.pub en la carpeta /home/demo/.ssh con el nombre de authorized_keys, Luego tendríamos que conectarnos vía ssh normal y corriente y arreglar tema permisos… Esto ya lo dejo por vuestra cuenta….(chmod 600 authorized_keys)

Ahora solo tenemos que conectarnos vía ssh desde la Shell y no se nos pide contraseña como podéis ver. Recordar que estamos en la máquina Kali Linux que actúa como cliente:

root@gkali:~# ssh -i /root/demo/id_rsa demo@192.168.153.137

Welcome to Ubuntu 18.04.4 LTS (GNU/Linux 4.15.0-76-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

System information as of Wed Apr 15 19:29:25 CEST 2020
System load: 0.0 Processes: 167
Usage of /: 13.0% of 29.40GB Users logged in: 1
Memory usage: 19% IP address for ens33: 192.168.153.137
Swap usage: 0%

* Kubernetes 1.18 GA is now available! See https://microk8s.io for docs or
install it with:
sudo snap install microk8s --channel=1.18 --classic
* Multipass 1.1 adds proxy support for developers behind enterprise
firewalls. Rapid prototyping for cloud operations just got easier.
https://multipass.run/
Pueden actualizarse 65 paquetes.
50 actualizaciones son de seguridad.
Last login: Wed Apr 15 18:58:33 2020 from 192.168.153.133

Vemos que estamos como el usuario demo conectados en el servidor destino_

demo@nft-fw:~$ whoami

demo

Como podemos ver estamos conectados desde el cliente al servidor con la órden who:

demo@nft-fw:~$ who

demo tty1 2020-04-15 16:33
demo pts/0 2020-04-15 19:29 (192.168.153.133)

 

EJEMPLO DE SINCRONIZACIÓN


Tal como os he indicado, muchos se quedan con la idea de «vaya lio hemos montado para evitar poner una contraseña». Es más, si me pillan la clave privada estoy igual de ….

Recordar que al inicio he dicho claramente que la idea es emplear dicho mecanismo de clave pública y privada para automatizar procesos.

Un ejemplo.. Quiero sincronizar el contenido de la carpeta de mi cliente Kalin Linux /root/Descargas a la carpeta del servidor Ubuntu /home/demo/tmp.

Pues bien, el comando sería algo de este estilo.

#rsync -avh -e 'ssh -i /root/demo/id_rsa' /root/Descargas/* demo@192.168.153.137:/home/demo/tmp 

file list2 239
1586597355.hccapx
Exploit.exe
TSSpentest-master.zip
rtl8812au-master.zip
TSSpentest-master/
TSSpentest-master/README.md
TSSpentest-master/tsspentestweb
TSSpentest-master/hackthissite.com/
TSSpentest-master/hackthissite.com/infodns
TSSpentest-master/hackthissite.com/www.hackthissite.com/
TSSpentest-master/hackthissite.com/www.hackthissite.com/index.html.tmp
rtl8812au-master/
rtl8812au-master/.8812au.ko.cmd
...

Si nos conectamos vía ssh al servidor Ubuntu veremos que la estructura se ha copiado.. Y sin pedirnos contraseña..

demo@nft-fw:~/tmp$ ls -la

total 1724
drwxrwxr-x 4 demo demo 4096 abr 15 21:53 .
drwxr-xr-x 8 demo demo 4096 abr 15 21:53 ..
-rw-r--r-- 1 demo demo 786 abr 11 11:29 2239_1586597355.hccapx
-rw-r--r-- 1 demo demo 73802 abr 6 17:49 Exploit.exe
drwxr-xr-x 7 demo demo 4096 abr 10 18:56 rtl8812au-master
-rw-r--r-- 1 demo demo 1661747 abr 10 18:55 rtl8812au-master.zip
drwxr-xr-x 3 demo demo 4096 dic 21 08:44 TSSpentest-master
-rw-r--r-- 1 demo demo 3396 dic 21 08:42 TSSpentest-master.zip

En definitiva, que este método nos permite generar scripts donde podemos conectar sistemas sin necesidad de establecer contraseñas, o lo que es peor.. dejarlas dentro del script en texto plano.

Espero que os haya parecido interesante. Cualquier cosa no dudéis en poner un comentario y os responderé.

 

 

You may also like

2 comments

Xavi abril 16, 2020 - 1:53 pm

Gracias JL por todo tu tiempo.
Podrías complementar el Post indicando de cómo prohibir el acceso al servicio SSH con password simple, una vez establecidas las keys pública/privada.
Gracias.

Reply
José Luis Sánchez Borque abril 16, 2020 - 3:21 pm

Molt Bones…

Gracias por el comentario. Espero tomen nota y lo puedan utilizar, ellos y la comunidad.

Sobre lo que comentas habría que añadir en el fichero de configuración /etc/ssh/ssh_config los parámetros adecuados:

ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no
PermitRootLogin no

Saludos y nos vemos en el próximo Post 🙂

Reply

Responder a José Luis Sánchez Borque Cancel Reply