Skip to main content

SSH (Secure Shell)

SSH (Secure Shell) es un protocolo de red cifrado usado para comunicación segura entre dispositivos. Permite acceder remotamente al terminal de otro ordenador o servidor como si estuvieras físicamente presente. Es ampliamente utilizado por administradores de sistemas, desarrolladores y usuarios que necesitan acceso remoto seguro.

Una característica clave de SSH es su capacidad de cifrar todos los datos transmitidos, garantizando la seguridad de contraseñas y comandos. Soporta autenticación por claves asimétricas, aumentando aún más la seguridad de las conexiones.

El servicio SSH generalmente se ejecuta en el puerto 22 por defecto, y para acceder a un servidor vía SSH, usas el comando ssh seguido del nombre de usuario y de la dirección IP o nombre de dominio del servidor.

Vamos a imaginar que tenemos el usuario david en la máquina a la que queremos acceder y la IP de la máquina es 192.168.0.10. Siempre que puedas alcanzar la máquina destino podemos ejecutar

ssh [email protected]

# Apuntando a un puerto específico en el que el servicio de ssh de la máquina esté ejecutándose.
ssh -p 2222 [email protected]

Los comandos arriba pedirán la contraseña de david al intentar logar como david.

La práctica recomendada es desactivar el acceso SSH vía contraseña y, en vez de eso, usar autenticación por clave pública. Esto significa que, en vez de escribir una contraseña al conectarse, autentificas tu identidad con una clave privada correspondiente a una clave pública almacenada en el servidor.

Esto quiere decir que necesitamos dos claves una pública y una privada. Todo lo que sea cifrado con la clave privada solamente será descifrado con la clave pública. Ni la propia clave privada conseguiría descifrar lo que ella misma cifró. De la misma forma, todo lo que es cifrado con la clave pública solamente será descifrado con la clave privada. Estas claves trabajan en pares. Este método de cifrado es conocido como cifrado asimétrico.

Vale resaltar que incluso utilizando contraseña para autenticación la comunicación será cifrada por el protocolo SSH. En el caso de uso del par de claves pública y privada, estas solamente son utilizadas para autenticación.

Una vez autenticado el protocolo SSH negociará una clave simétrica generada por él y común para el cliente y el servidor para cifrar los datos.

El uso de claves para autenticación ofrece varias ventajas significativas en comparación con la autenticación basada en contraseñas:

  • Seguridad mejorada: Las claves SSH son mucho más seguras que las contraseñas, pues son más difíciles de ser adivinadas por ataques de fuerza bruta.

  • Eliminación de contraseñas: Con el uso de claves SSH, puedes eliminar la necesidad de insertar contraseñas al conectarse a servidores remotos. Esto simplifica el proceso de login y elimina el riesgo de que las contraseñas sean interceptadas o comprometidas.

  • Auditoría y gestión centralizada: Las claves SSH pueden ser gestionadas centralmente y auditadas de forma más eficaz que las contraseñas. Los administradores pueden controlar qué claves tienen acceso a qué servidores y revocar claves comprometidas de forma rápida y fácil.

  • Capacidad de usar autenticación de dos factores (2FA): Las claves SSH pueden ser combinadas con autenticación de dos factores (como contraseñas o autenticación basada en token) para proporcionar una capa adicional de seguridad. Esto requiere que los usuarios proporcionen no solamente la clave SSH, sino también otro factor de autenticación para acceder al servidor.

Creando claves SSH

Para configurar la autenticación por clave pública, necesitas generar un par de claves SSH (una pública y una privada) en tu máquina local y después añadir el contenido de la clave pública al archivo ~/.ssh/authorized_keys en el servidor remoto para el usuario que deseas acceder. Si tenemos el usuario david en el servidor y es con él que queremos autenticar será en /home/david/.ssh/authorized_keys.

Si el servidor contiene la clave pública y ella solo consigue descifrar solamente lo que vino de su par, la clave privada, entonces garantizamos que quien tiene la clave privada es quien dice ser.

Primero vamos a generar un par de claves para uso con SSH. Tenemos varios algoritmos de cifrado que podemos utilizar, pero voy a abordar solamente los dos más considerados seguros.

El par de claves SSH no tiene un tiempo de validez como un certificado. La clave privada no debe ser compartida.

El algoritmo RSA es de 1977 y más utilizado que el Ed25519 que es de 2011, a pesar de que este último es mejor. Vamos a ver las diferencias.

CaracterísticaRSAEd25519
TipoAsimétricoAsimétrico
Tamaño de las ClavesGeneralmente 2048 bits o más256 bits
Eficiencia ComputacionalMás intensivo computacionalmenteMás eficiente computacionalmente
Generación de ClavesMás lentaMás rápida
Tamaño de los Datos FirmadosTiende a ser mayorTiende a ser menor
Resistencia a Ataques de Fuerza BrutaMenos resistenteMás resistente
Soporte y AdopciónAmplia adopción y soporte en muchos sistemas y protocolosGana popularidad, aún en proceso de adopción
Almacenamiento de Claves en el ClienteNecesita almacenar clave privada en el clienteNecesita almacenar clave privada en el cliente
Almacenamiento de Claves en el ServidorNecesita almacenar clave pública en el servidorNecesita almacenar clave pública en el servidor
Uso en Aplicaciones ActualesAún ampliamente utilizado en muchos escenariosGana popularidad, especialmente en entornos donde la eficiencia es una prioridad
SeguridadRSAEd25519
VulnerabilidadesVulnerable a ataques de factorización de enterosMás resistente a varios tipos de ataques
Base MatemáticaBasado en el problema de la factorización de enterosBasado en el problema del logaritmo discreto en curvas elípticas
Resistencia a Ataques de Fuerza BrutaMenos resistenteMás resistente
Ataques ConocidosAtaques conocidos, como ataques de factorización y ataques de compromiso de claves privadasMenos ataques conocidos debido a su naturaleza más reciente

Para crear un par de claves.

# El comando abajo utiliza el algoritmo RSA como predeterminado
# Utiliza 2048 bits y genera los archivos id_rsa para la clave privada e id_rsa.pub en ~/.ssh
ssh-keygen
# Podemos aumentar la cantidad de bits para fortalecer la seguridad del algoritmo.
# -N "" es para no pasar una contraseña para esa clave.
# -f es el nombre que vamos a dar a la clave. Ya podemos pasar el camino hacia donde estará el archivo mi_clave_rsa.
ssh-keygen -t rsa -b 4096 -f ~/Desktop/mi_clave_rsa -N ""

# Utilizando el algoritmo Ed25519 y usando una contraseña (no es obligatorio) para la clave privada.
# El tamaño de ed25519 es siempre 256 entonces si pasamos el comando -b 4096 será ignorado
ssh-keygen -t ed25519 -f ~/Desktop/mi_clave_ed25519 -N "mi!contraseña"

Ahora tenemos el par de claves coloca el contenido de la clave pública dentro de .ssh/authorized_keys del usuario con el que queremos logar. Tengo una máquina en la que el usuario es ubuntu y tengo la clave pública en el lugar correcto.

# En la máquina local
cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDXZQyz0KI35+Cay+p13+9DQs5R2twRojHIj3DHSC1DcRm9HEw0HpTQLunM181mtv6ElZXU5zKCrKRkXJUHTTAN5t7l7YVHTCJ3CoHbaDdZBTncZbXNBYRniRS+NV4uXuYVqzaDOK8mnytgQwKhbrwnA77vyHsDT4DZQM4FA3EiOpzHSKz7/uvgojOASEd6TTRHtLdLwXemqww9C060Gwg2wFTk9HbZI9kzJYVSBhK4Z4Fd5RsBiFsmz1GqSXTunncDLHgz1EtC+ShoRJ/ckEmfqZaGjBE2TiK4YGikXKul1RceSjsk9nROcxWt6uJdRAi0m/XsYat6E5UHP0IRwYcQt6Mcjj/3nPpGqSXjR6oNlondI+Pg7CffrKU+WhtVC5mwfLxg960B1PeSDsbnYJhg+vSGsXmmrgKZb6Xz8Qgl3o72d6gW1+2Lpnwtm6Q7lP5kzGpWCPMHjpzzTb41JHzAqM7vBFvfPw7YIUVgdbkMyjN/ap/BWApe1acbYMVNSTrE02HzdPtmI2FvJU8cy93PayEC9/SntNV1m9WcgxFZCoJQamDwOME4hfRMF/efgZ8haEJGXM2TqnBO3bsZI+m2nPwV85TpYU+uKZeNAEbxq7JoKMV6JInX+6+VBK4GfFXwElhFqG+6gzRXLB3Cvuv+I4BHFiuOXKmUq2k6ik3PLQ== david@david

# -i para pasar la clave privada con la que queremos logar
ssh -i id_rsa [email protected]

# Ya dentro del sistema podemos ver la clave pública equivalente.
ubuntu@master1:~$ cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDXZQyz0KI35+Cay+p13+9DQs5R2twRojHIj3DHSC1DcRm9HEw0HpTQLunM181mtv6ElZXU5zKCrKRkXJUHTTAN5t7l7YVHTCJ3CoHbaDdZBTncZbXNBYRniRS+NV4uXuYVqzaDOK8mnytgQwKhbrwnA77vyHsDT4DZQM4FA3EiOpzHSKz7/uvgojOASEd6TTRHtLdLwXemqww9C060Gwg2wFTk9HbZI9kzJYVSBhK4Z4Fd5RsBiFsmz1GqSXTunncDLHgz1EtC+ShoRJ/ckEmfqZaGjBE2TiK4YGikXKul1RceSjsk9nROcxWt6uJdRAi0m/XsYat6E5UHP0IRwYcQt6Mcjj/3nPpGqSXjR6oNlondI+Pg7CffrKU+WhtVC5mwfLxg960B1PeSDsbnYJhg+vSGsXmmrgKZb6Xz8Qgl3o72d6gW1+2Lpnwtm6Q7lP5kzGpWCPMHjpzzTb41JHzAqM7vBFvfPw7YIUVgdbkMyjN/ap/BWApe1acbYMVNSTrE02HzdPtmI2FvJU8cy93PayEC9/SntNV1m9WcgxFZCoJQamDwOME4hfRMF/efgZ8haEJGXM2TqnBO3bsZI+m2nPwV85TpYU+uKZeNAEbxq7JoKMV6JInX+6+VBK4GfFXwElhFqG+6gzRXLB3Cvuv+I4BHFiuOXKmUq2k6ik3PLQ== david@david
ubuntu@master1:~$

En vez de pasar cuál es la clave que tenemos que utilizar todas las veces usando el -i.

¿Cómo Gestionar Múltiples Claves SSH?

A veces es necesario utilizar diferentes claves privadas ssh para hacer logins en diferentes servidores. El par de claves A se usa en los servidores de la empresa A y el par de claves B usados en el servidor de la empresa B o incluso tendremos nuestra clave personal para interactuar con nuestros propios repositorios y otra clave para interactuar con los repositorios de la empresa.

Podemos usar ssh-agent que es un programa que gestiona las claves privadas SSH usadas para autenticación. Funciona como un intermediario que almacena las claves privadas en memoria y las utiliza conforme sea necesario. Para saber si está funcionando.

eval $(ssh-agent)
# Si el pid es retornado entonces está disponible
Agent pid 35526

Si tienes una clave privada que necesita una contraseña para desbloqueo, cargarla usando ssh-agent es interesante pues guarda en memoria la clave desbloqueada evitando tener que escribir la contraseña todo el tiempo. Al añadir una clave pide la contraseña y después administra solo.

# Para añadir
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/id_rsa2

# Para Listar
ssh-add -l

# Elimina una clave específica de la lista
ssh-add -d ~/.ssh/id_rsa2

# Elimina todo
ssh-add -D

El archivo en ~/.ssh/config es necesario para saber qué clave usar. La configuración más simple para una única clave es.

Host *
ForwardAgent yes

Pero podemos definir claves diferentes para hosts diferentes. Abajo tendremos un ejemplo más concreto con GitLab.

Host github.com
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa_github

Multi GitLab Account con SSH y Git

En GitLab no es posible añadir la misma clave pública en cuentas diferentes. Ciertamente necesitaremos crear más de una clave. El consejo es crear una configuración para que la clave sea seleccionada basada en el host.

En ~/.ssh vamos a imaginar que tenemos 2 claves; una para tu GitLab personal y otra para GitLab del trabajo.

Entonces vamos a crear una configuración en ~/.ssh/config.

Host gitlab.com
HostName gitlab.com
User git
IdentityFile ~/.ssh/personal_key
Host gitlab.com-work
HostName gitlab.com
User git
IdentityFile ~/.ssh/work_key

Cuando sea identificado que el host es gitlab.com va a usar la clave privada personal_key y cuando sea identificado como gitlab.com-work usará la clave work_key.

Al ejecutar el comando git clone [email protected]... cambia gitlab.com por gitlab.com-work cuando sea para un clon del repositorio de la empresa.

Si un repositorio ya está definido solamente cambia el remote de él configurando una url nueva si es necesario.

# Ejemplo para un repositorio de GitLab del trabajo
git remote set-url origin [email protected]:work/repository.git

En este caso un detalle interesante para hacer también es crear una carpeta (work en el ejemplo abajo) que tendrá todos los proyectos de la empresa y alterar la configuración del git para cambiar el usuario y email solamente en aquella carpeta y mantener el global.


[user]
name = David Puziol
email = [email protected]
[includeIf "gitdir:~/Desktop/work/"]
path = ~/.gitconfig-work

Y crear un archivo .gitconfig-work para sobrescribir el user

[user]
name = David Puziol
email = [email protected]