SSH, ¿navaja suiza o agujero de seguridad? II/II

En la anterior publicación sobre ssh mostramos algunas de las funcionalidades y configuraciones que podemos hacer relativas a ssh, principalmente orientadas al cliente. En esta entrada vamos a ver otras opciones más avanzadas que nos permitirán simplificar el uso de ssh a la vez que expondrán problemas de seguridad.

Acceso “automático sin credenciales” 

La forma más común y conocida para conectarnos a un servidor de ssh, es mediante un usuario y una contraseña. Este método utiliza los datos de los usuarios del sistema operativo, así que cada vez que accedemos comprueba si el usuario existe, la contraseña es válida y que esta no haya expirado. 

Si nos conectamos frecuentemente a un servidor, es bastante incómodo tener que meter la contraseña todas las veces, por eso la mayoría de los clientes permiten guardar las contraseñas. Me pone nervioso ver gente que lleva trabajando años con los mismos servidores y cada vez que tienen que conectarse, consultan los datos en un fichero donde lo tienen anotado.

Por ejemplo en Multi-Tabbed PuTTY podemos seleccionar que nos guarde la contraseña con un check. En otros clientes de ssh o de sftp, el proceso es similar e igual de sencillo.

image 1 for 2

Pero si las contraseñas nos las cambian periódicamente, tendremos que ir cambiándolas. ¿Hay algún otro método de autenticación? claro que lo hay, y es independiente de la contraseña, tanto en su valor como en su fecha de expiración, nos podemos autenticar en un servidor mediante clave pública y clave privada. Con este método accederemos sin que se nos solicite introducir la contraseña, y lo que más interesante, podremos acceder aunque la contraseña haya expirado.

Vamos a configurar el acceso mediante clave pública-privada a la máquina rPiZero desde  rPi3 para el usuario pi.

  • Primero comprobamos que hay conectividad y que se está solicitando la contraseña para el usuario

[ksh]pi@rPi3[]: ssh pi@rPiZero

Password:

  • Ahora vamos a generar un par de claves, en la generación podemos añadir una frase de paso (contraseña) que sea distinta a la que tiene configurada el usuario a nivel de sistema operativo, pero por simplificar lo dejamos vacío. 

[ksh]pi@rPi3[]: ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/home/pi/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /home/pi/.ssh/id_rsa.

Your public key has been saved in /home/pi/.ssh/id_rsa.pub.

The key fingerprint is:

f9:b6:9c:c9:28:bb:8c:8b:75:cb:19:5b:10:d2:04:b7 [MD5] pi@rPi3

The key's randomart image is:

+--[ RSA 2048]----+

|    .+o          |

|    ..o.         |

|     .E.         |

|      .  .       |

|       .S        |

|    . o ..       |

|   . o *   o     |

|  .  o*  = +     |

|  .o. ++. *      |

+--[MD5]----------+

 

  • Podemos ver el contenido de los ficheros de clave que hemos creado, uno contendrá la clave pública (id_rsa.pub) y el otro la privada (id_rsa)

[ksh]pi@rPi3[]: cat /home/pi/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCeMDSW61NXAwVOe+Nd3hH01PLTg6eQPoolP6jGuCHcF/wTpb9N6mqGY/uAX4EayYn3HCd/0d2suJteaAeK+5fo5ib+5e3TCgZXd1G/Q417YyVmG6QVhU7DLv+n6S8bi6V2LxhJnZRS+x141Ztda5utctHY66EcKzfRa9fyt7sMhbZ5C/UKsBnhpiqdj7IdF9YV6F/YcTmTxjCixhCMpFdQy6CMcbbukfuNHd0j+HduteHpYmXTP4Ahcads5loHzh7bh2b9tM5e4xmYkuPqBPMWgqg6eLTGmbBRX1z7sTOwqcuSONig0qNYTTqw7df9R99ACpdT8SKBMBcJfLyJo1qn pi@rPi3

[ksh]pi@rPi3[]: cat /home/pi/.ssh/id_rsa

-----BEGIN RSA PRIVATE KEY-----

MIIEowIBAAKCAQEAnjA0lutTVwMFTrvjXd4R9NTy04OnkD6KJT+oxrgh3Bf8E6W/

TepqhmP7gF+BGsmIdxwnf9HdrLibXmgHivuX6OYm/uXt0woGV3dRv0ONe2MlZhuk

FYVOwy7/p+kvG4uldi8YSZ2UUvsdeNWbXWubrXLR2OuhHCs30WvX8re7DIW2eQv1

CrAZ4aYqnY+yHRfWFehf2HE5k8YwosYQjKRXUMugjHG27pH7jR3dI/h3brXh6WJl

0z+AIXGnbOZaB84e24dm/bTOXuMZmJLj6gTzFoKoOmi0xpmwUV9c+7EzsKnLkjjY

oNKjWE06sO3X/UffQAqXU/EigTAXCXy8iaNapwIDAQABAoIBADdIsZhs9dta+ufK

9FNB4RSnt5WkVVNcB/usm9eXUn4RA8/6BTm9yyzclHDw77Xk6QR3mnZZaheLDQGZ

aclw1E5Y4RgEU3GF92FqGe+2NCQDKnbdAiNjS3t7WW3dWNFPpKwBGYPgxo2ZpVst

i/bCPM4Jar1c3Bl0ITxXcsko3P4q0DwHtlySLYVODBWjQ7jGfGlnPgYKJwxhwTZq

2k+k+T+/7dM6Jzg8ZOxnWw3VO5Twtk/l+zWcgAq2IU6cO9aLn+yUiwg0W5oLCTOO

sOPM0z4nO5kjSs5cV+XDaaoIXCMgXA6+uHJpCwWkOgEye+9CnBM0QMUupANHLFbY

QaSpeUECgYEAzuxrUxME9LTXopZqfBUi00ggapSTItNKfc0gnZJNSuxnJy2LFvvW

SUnBbyY/DwRwrdazOSuj/pyg/Fno/asu31oEX7gyj9AmFx4eGIVM6U3lRTemcriM

rqdfw116DpwJ78nXT13lU+T2HSFEeEYZnIsC0YuBwQ51nWYPWriX6eMCgYEAw7TG

so0T6w9ZSmDtT3g9YWhuXnMT3GERDDD8EDvj9YnBZ7hoQGyoPDljUh/g0yeEeV01

tjoTQti1WeuVmCycfkYtuq2B2BqZ7AzsBtPjryvW85f7E87Xu85aofZbjtJRAIsC

la1+uwiVzO+lHSuHMWJ+veXy/Rnm62YJOt2HN20CgYABVedPbvT+O1iU9RGU4XIL

GREUfwcAF4sIitVmDvauwB3eU93s9Q0qBe7Yr8+CYk3z4Ung2ZZCY3Jqjo4BbSRt

TqBumbrB0N8eERSypdGcQ+Nx8e8aGozV58Cneyf5hipOQOhB2+JKC1VHVNqjSBiM

OR14isT4oQZDUNBSjpR0bwKBgAzK+GIbjr3C1xdhlqGnPnvrk6tg4l95iN/PEuwM

vi4Cvz3EdCwh7i1hovhvVQb4glRcn3I2AaRQ/inOmI0I7YHjnIGjbeVud7lSbutT

VoLQ3tA1kxgMYVXJe2sy63E+lkTu0VBvcuVO/lvTHnv1qHS194r6SRP6aXnhxaCv

cnNRAoGBAKzbHximx5j2i9WfosEJafPu/4ZlAgV2A5xMYqb42a+DrGFumC3FYcb3

o9RIotLJCCqMngv5t8I+K1uAACS/V9iZtuj175Ey0dJnlW3UoW+9W6WCDi3+fTxe

SCiUYoWHwyVfm1+8wF+J1LM7t3MCc6lDg0ip5h5UNIRjGxKC+QE6

-----END RSA PRIVATE KEY-----

  • El siguiente paso es copiar la clave pública al servidor donde nos queremos conectar, para ello primero crearemos un directorio, si es que no existe:

[ksh]pi@rPi3[]: ssh pi@rPiZero mkdir -p .ssh

Password:

[ksh]pi@rPiZero[]:

  • ahora añadiremos nuestra clave pública en la lista de claves autorizadas en el servidor destino

[ksh]pi@rPi3[]: cat .ssh/id_rsa.pub | ssh pi@rPiZero 'cat >> .ssh/authorized_keys'

Password:

[ksh]pi@rPi3[]:

  • A partir de este momento no se volverá a pedir la contraseña para conectarnos desde rPi3 a rPiZero. Lo podemos comprobar conectándonos por ssh

[ksh]pi@rPi3[]: ssh rPiZero

[ksh]pi@rPiZero[]:

  • O por sftp

[ksh]pi@rPi3[]: sftp rPiZero

sftp>

Esto nos simplifica mucho la gestión de las conexiones a nuestros servidores, pero por contra, se pierde en parte el control de acceso. Un ejemplo de pérdida de control podría ser un servidor de producción al que nos dan acceso para una instalación, consultar alguna configuración o alguna tarea similar de manera puntual para un día en concreto, sí mientras tenemos acceso metemos nuestra clave pública en el servidor de producción, podremos seguir accediendo después de la expiración de la contraseña, lo cual puede ser un gran problema de seguridad, y además podremos conectarnos por sftp, sacar ficheros de logs, ficheros de configuración… en general mucha información sensible de nuestras aplicaciones.

Túneles

Esta es una opción que nos permite redirigir el tráfico de un servidor a otro e incluso cambiar los puertos. Hace que podamos acceder “directamente” a servicios a los que, a priori, no tenemos acceso. 

Podemos crear varios tipo de túneles:

Port Forwarding

El funcionamiento es sencillo, sirve para hacer una redirección de puertos, lo que recibas en el puerto X lo mandas la IP Y al puerto Z. Es similar a lo que hacíamos en nuestra casa al abrir puertos, cuando tenías el eMule/BitTorrent y tenías que permitir conexiones a nuestro PC, desde internet nadie se podía conectar a nuestro PC, pero si llegaban a nuestro router, por eso le decíamos que lo que llegase al puerto 4662 lo redireccionará a mi PC al mismo puerto 4662 o en el que tuviésemos escuchando el servidor.

Laboralmente muchas veces tenemos acceso a servidores, pero no de manera directa, por lo que tenemos que utilizar máquinas intermedias para llegar. Por ejemplo, podemos tener acceso directo al servidor de desarrollo (rPiZero) pero al servidor de producción (rPi3) no tenemos conectividad. Sin embargo desde desarrollo sí que nos podemos conectar a producción. Ante este escenario, nos conectamos por ssh a la máquina de desarrollo (rPiZero) y desde la máquina de desarrollo nos conectaremos también por ssh al servidor de producción (rPi3). Este tipo de conexión con máquinas intermedias nos puede servir para ciertas tareas, pero desde luego que nos limita mucho respecto a lo que sería una conexión “directa”. Vamos a suponer que no podemos tener una conexión directa por el motivo que sea (distintos segmentos de red, reglas de firewall que no se van a abrir...), así que lo que vamos a hacer es simularlo mediante un túnel.

image 2 for 2

Llegado este punto ¿Cómo creo un túnel ssh para hacer port forwarding? las opciones que tiene el comando son abrumadoras, y podemos utilizarlas en función de nuestras necesidades. Lo más fácil es verlo con un ejemplo, tenemos conectividad a la máquina rPiZero, pero no tenemos conectividad a rPi3, vamos a hacer que las peticiones que lleguen a rPiZero al puerto 8022 las mande a la máquina rPi3 al puerto 22 (puerto estándar de ssh). El comando lo tenemos que ejecutar en la máquina en la que se va a hacer el port forwarding, es decir, en rPiZero. Las opciones que utilizaremos son:

-g para permitir que se acepten conexiones desde otras máquinas

-f para que se ejecute el comando en segundo plano, permitiendo que el terminal desde donde lo hemos lanzado se pueda cerrar pero nuestro comando se siga ejecutando.

-N para indicar que no vamos a ejecutar ningún comando remoto.

[ksh]pi@rPiZero[]: ssh -g -f -N -L8022:rPi3:22 pi@rPiZero

Ahora cuando nos conectemos a la máquina rPiZero al puerto 8022, el tráfico será redirigido a la máquina rPi3 al puerto 22. En otras palabras, con ssh rPiZero -p 8022, nos estaremos conectando por SSH a la máquina rPi3. Esto es algo que no podíamos hacer inicialmente. Una vez que está establecido el túnel podemos hacer uso de todas sus funcionalidades, como puede ser conexión por SFTP… o incluso encadenar varios túneles para llegar a otras máquinas.

SOCKS4/5

Es un protocolo de comunicaciones que se encuentra en la capa de red del modelo OSI. Aunque no es estrictamente necesario utilizar ssh para crear un servidor de SOCKS4/5, ssh nos permite que lo hagamos. ¿Qué es lo que vamos a conseguir con un servidor de SOCKS4/5? salvando muchas diferencias, es lo más parecido a conectarnos a una VPN, y aunque seguro que un experto en redes pondrá el grito en el cielo con esta comparación.

Conectándonos a un servidor de SOCKS4/5, las comunicaciones que hagamos a través de esa conexión irán cifradas y se realizarán como si nuestro cliente se encontrase físicamente en la ubicación/red del servidor al que nos hemos conectado. Esto lo veremos más claro con un caso de uso, en el trabajo tenemos un ordenador con salida a internet, pero tenemos ciertos dominios que están capados, por ejemplo www.futbolfantastico.com, cuando intentamos acceder al dominio, se nos muestra un mensaje del tipo “El administrador ha bloqueado este dominio por motivos de seguridad”. Si tenemos un servidor de ssh en nuestra casa, vamos a hacer que el tráfico web que genere nuestro navegador se envíe por un túnel ssh hasta nuestra casa, y desde nuestra casa salga a internet, ya que en nuestra casas no tendremos ninguna limitación en el contenido que podemos visualizar. Al encriptada la información de nuestro navegador, en la red de nuestro trabajo lo único que podrán ver es que se ha establecido una conexión ssh hasta nuestra casa, pero no sabrán que dentro de esa conexión va tráfico web http/https.

¿Cómo creo un servidor SOCKS4/5? Muy fácil, desde la configuración de nuestra conexión seleccionaremos un túnel dinámico, y le indicaremos el puerto local de nuestro ordenador a través del cual se va a mandar la información al servidor. Un ejemplo de configuración en putty sería el que se muestra en la imagen, en el que se ha seleccionado el puerto 1234. Connections > SSH > Tunnels

image 3 for 2

A partir de este momento, cuando se establezca una conexión al servidor de ssh, en nuestro ordenador se empezará a escuchar en el puerto indicado, en nuestro caso 1234.

Ahora que está configurado, ¿cómo lo uso? tenemos que ir a la configuración de nuestra aplicación, en nuestro caso Firefox y en la pestaña de proxy indicar los datos del servidor, en este ejemplo el servidor lo tenemos en localhost  en el puerto 1234. Podemos observar cómo quedaría la configuración en la siguiente imagen. 

image 4 for 2

Con esta configuración, todos las peticiones que se hagan desde el navegador viajarán encriptadas hasta el servidor ssh al que nos hemos conectado, y desde allí saldrán a la red. De esta manera monitorizando la red no se podrá saber por donde estamos navegando.

SSHFS (SSH File System)

Todas las opciones que hemos visto nos pueden resultar muy complicadas, la línea de comandos, claves… Ojalá se pudiese de alguna manera poder acceder a los ficheros de las máquinas sin tener que hacer conexiones. Una vez más con SSH tenemos la solución, ya que podemos montar como una unidad local el sistema de ficheros remoto de una máquina que nos de acceso con este protocolo.

Por variar, vamos hacerlo en un MacBook, pero hay soluciones para Windows, Linux…

Lo primero que haremos será instalar un cliente que nos permita hacer esto por ejemplo FUSE. La instalación no tiene ninguna complicación y los pasos son básicamente ir aceptando todo lo que nos pregunta. 

Una vez instalado, vamos a crear un directorio donde montar el sistema remoto:

sudo mkdir remoteSSHFolder

image 5 for 2

Ahora que ya tenemos el directorio y el software necesario instalado, únicamente tenemos que ejecutar el siguiente comando. Al ejecutar este comando se nos pedirá primero la contraseña del administrador de la máquina, y luego la contraseña del usuario del servidor remoto. En este ejemplo vamos a conectar a la máquina 10.0.0.103 con el usuario pi,  y va a montar el directorio remoto raíz (/) en el directorio local /Users/miguelserranoraspeno/remoteSSHFolder

sudo sshfs -o allow_other,default_permissions pi@10.0.0.103:/ /Users/miguelserranoraspeno/remoteSSHFolder

image 6 for 2

Una vez montado el sistema de ficheros, será como un directorio más en la máquina, como se puede ver en las capturas de Finder.

image 7 for 2

image 8 for 2

Conclusiones

Creo que después de haber visto parte del potencial que tiene SSH, no nos quedarán dudas de que tienen grandes bondades y grandes defectos, aunque más que defectos es desconocimiento de su funcionamiento. 

Por lo menos deberemos tener en cuenta que una mala configuración del servidor, lejos de ayudarnos a securizar nuestros sistemas, puede convertirse en un gran agujero de seguridad.

Todos los puntos que se han ido viendo de manera individual, se pueden usar de manera conjunta, por ejemplo haciendo un túnel de la máquina A a la máquina B, poniendo en B nuestras claves para acceder sin meter contraseña y recibir en nuestro PC las xWindows del servidor B, y además tener montado como una unidad todo el sistema de fichero remoto.

Respondiendo a la pregunta del título, la respuesta sería ambas, ssh es una herramienta muy versátil y muy potente, y es por eso que si no la usamos correctamente se nos puede volver en nuestra contra.