Introducción
SSH, o Secure Shell, es un protocolo seguro y la forma más común de administrar servidores remotos de manera segura. Utilizando diversas tecnologías de cifrado, SSH proporciona un mecanismo para establecer una conexión criptográficamente segura entre dos partes, autenticando cada lado ante el otro y enviando comandos y resultados de manera segura de ida y vuelta.
En esta guía, examinaremos las técnicas de cifrado subyacentes que SSH emplea y los métodos que utiliza para establecer conexiones seguras. Esta información puede ser útil para comprender las diferentes capas de cifrado y los pasos necesarios para formar una conexión y autenticar ambas partes.
Comprendiendo el Cifrado Simétrico, Cifrado Asimétrico y Hashes
Para asegurar la transmisión de información, SSH emplea diversos tipos de técnicas de manipulación de datos en varios puntos de la transacción. Estas incluyen formas de cifrado simétrico, cifrado asimétrico y hash.
Encriptación Simétrica
La relación de los componentes que encriptan y desencriptan datos determina si un esquema de encriptación es simétrico o asimétrico.
La encriptación simétrica es un tipo de encriptación donde una clave puede ser utilizada para encriptar mensajes hacia la otra parte, y también para desencriptar los mensajes recibidos de la otra parte. Esto significa que cualquiera que posea la clave puede encriptar y desencriptar mensajes para cualquier otra persona que tenga la clave.
Este tipo de esquema de encriptación a menudo se llama encriptación de “secreto compartido” o encriptación de “clave secreta”. Normalmente hay una sola clave que se utiliza para todas las operaciones o un par de claves donde la relación es descubrible y es trivial derivar la clave opuesta.
Las claves simétricas son utilizadas por SSH para encriptar toda la conexión. Contrariamente a lo que algunos usuarios asumen, los pares de claves asimétricas público/privado que se pueden crear solo se utilizan para autenticación, no para encriptar la conexión. La encriptación simétrica permite que incluso la autenticación de contraseña esté protegida contra el espionaje.
El cliente y el servidor contribuyen ambos a establecer esta clave, y el secreto resultante nunca es conocido por partes externas. La clave secreta se crea a través de un proceso conocido como un algoritmo de intercambio de claves. Este intercambio hace que tanto el servidor como el cliente lleguen a la misma clave de manera independiente al compartir ciertas piezas de datos públicos y manipularlos con ciertos datos secretos. Este proceso se explica con más detalle más adelante.
La clave de cifrado simétrico creada por este procedimiento es basada en la sesión y constituye el cifrado real para los datos enviados entre el servidor y el cliente. Una vez establecido esto, el resto de los datos deben ser cifrados con este secreto compartido. Esto se hace antes de autenticar a un cliente.
SSH se puede configurar para usar una variedad de sistemas de cifrado simétrico diferentes, incluidos Advanced Encryption Standard (AES), Blowfish, 3DES, CAST128 y Arcfour. Tanto el servidor como el cliente pueden decidir una lista de sus cifrados admitidos, ordenados por preferencia. La primera opción de la lista del cliente que esté disponible en el servidor se utiliza como el algoritmo de cifrado en ambas direcciones.
En Ubuntu 20.04, tanto el cliente como el servidor tienen por defecto la siguiente configuración:
[email protected]
aes128-ctr
aes192-ctr
aes256-ctr
[email protected]
[email protected]
Esto significa que si dos máquinas Ubuntu 20.04 se están conectando entre sí (sin anular los cifrados predeterminados a través de opciones de configuración), siempre utilizarán por defecto el cifrado [email protected]
para encriptar su conexión.
Encriptación Asimétrica
La encriptación asimétrica es diferente de la encriptación simétrica porque para enviar datos en una sola dirección se necesitan dos claves asociadas. Una de estas claves es conocida como la clave privada, mientras que la otra se llama clave pública.
La clave pública puede ser compartida libremente con cualquier parte. Está asociada con su clave emparejada, pero la clave privada no puede ser derivada de la clave pública. La relación matemática entre la clave pública y la clave privada permite que la clave pública encripte mensajes que solo pueden ser desencriptados por la clave privada. Esta es una habilidad unidireccional, lo que significa que la clave pública no tiene la capacidad de desencriptar los mensajes que escribe, ni puede desencriptar nada que la clave privada le pueda enviar.
La clave privada debe mantenerse completamente secreta y nunca debe ser compartida con otra parte. Este es un requisito clave para que funcione el paradigma de la clave pública. La clave privada es el único componente capaz de desencriptar mensajes que fueron encriptados usando la clave pública asociada. Por virtud de este hecho, cualquier entidad capaz de desencriptar estos mensajes ha demostrado que está en control de la clave privada.
SSH utiliza cifrado asimétrico en varios lugares diferentes. Durante el proceso inicial de intercambio de claves utilizado para configurar el cifrado simétrico (utilizado para cifrar la sesión), se utiliza cifrado asimétrico. En esta etapa, ambas partes producen pares de claves temporales e intercambian la clave pública para producir el secreto compartido que se utilizará para el cifrado simétrico.
El uso más conocido del cifrado asimétrico con SSH proviene de la autenticación basada en claves SSH. Los pares de claves SSH se pueden utilizar para autenticar a un cliente ante un servidor. El cliente crea un par de claves y luego carga la clave pública en cualquier servidor remoto al que desee acceder. Esto se coloca en un archivo llamado authorized_keys
dentro del directorio ~/.ssh
en el directorio de inicio de la cuenta de usuario en el servidor remoto.
Después de que se establece el cifrado simétrico para asegurar las comunicaciones entre el servidor y el cliente, el cliente debe autenticarse para obtener acceso. El servidor puede utilizar la clave pública en este archivo para cifrar un mensaje de desafío al cliente. Si el cliente puede demostrar que pudo descifrar este mensaje, ha demostrado que es dueño de la clave privada asociada. Entonces, el servidor puede configurar el entorno para el cliente.
Hashing
Otro tipo de manipulación de datos que SSH aprovecha es el hash criptográfico. Las funciones de hash criptográfico son métodos para crear una “firma” sucinta o un resumen de un conjunto de información. Sus principales atributos distintivos son que nunca están destinados a ser reversibles, son virtualmente imposibles de influir de manera predecible y son prácticamente únicos.
Usar la misma función de hash y el mismo mensaje debería producir el mismo hash; modificar cualquier parte de los datos debería producir un hash completamente diferente. Un usuario no debería poder producir el mensaje original a partir de un hash dado, pero debería poder determinar si un mensaje dado produjo un hash dado.
Dadas estas propiedades, los hashes se utilizan principalmente para fines de integridad de datos y para verificar la autenticidad de la comunicación. El uso principal en SSH es con HMAC, o códigos de autenticación de mensajes basados en hash. Estos se utilizan para asegurar que el texto del mensaje recibido esté íntegro y sin modificar.
Como parte de la negociación de cifrado simétrico descrita anteriormente, se selecciona un algoritmo de código de autenticación de mensajes (MAC). El algoritmo se elige trabajando a través de la lista de opciones de MAC aceptables del cliente. El primero en esta lista que el servidor admita será utilizado.
Cada mensaje enviado después de que se negocie el cifrado debe contener un MAC para que la otra parte pueda verificar la integridad del paquete. El MAC se calcula a partir del secreto compartido simétrico, el número de secuencia del paquete del mensaje y el contenido real del mensaje.
El propio MAC se envía fuera del área encriptada simétricamente como la parte final del paquete. Los investigadores generalmente recomiendan este método de cifrar los datos primero y luego calcular el MAC.
Comprendiendo cómo funciona SSH
Probablemente ya tienes una comprensión básica de cómo funciona SSH. El protocolo SSH emplea un modelo cliente-servidor para autenticar dos partes y encriptar los datos entre ellas.
El componente del servidor escucha en un puerto designado para conexiones. Es responsable de negociar la conexión segura, autenticar a la parte que se conecta y generar el entorno correcto si las credenciales son aceptadas.
El cliente es responsable de comenzar el apretón de manos inicial del protocolo de control de transmisión (TCP) con el servidor, negociar la conexión segura, verificar que la identidad del servidor coincida con la información previamente registrada y proporcionar credenciales para autenticarse.
Una sesión de SSH se establece en dos etapas separadas. La primera es acordar y establecer la encriptación para proteger la comunicación futura. La segunda etapa es autenticar al usuario y descubrir si se debe conceder acceso al servidor.
Negociación de cifrado para la sesión
Cuando un cliente establece una conexión TCP, el servidor responde con las versiones de protocolo que admite. Si el cliente puede coincidir con una de las versiones de protocolo aceptables, la conexión continúa. El servidor también proporciona su clave de host pública, que el cliente puede usar para verificar si este era el host previsto.
En este punto, ambas partes negocian una clave de sesión utilizando una versión de algo llamado el algoritmo de Diffie-Hellman. Este algoritmo (y sus variantes) hacen posible que cada parte combine sus propios datos privados con datos públicos del otro sistema para llegar a una clave de sesión secreta idéntica.
La clave de sesión se utilizará para cifrar toda la sesión. Los pares de claves pública y privada utilizados para esta parte del procedimiento son completamente diferentes de las claves SSH utilizadas para autenticar a un cliente en el servidor.
La base de este procedimiento para el clásico Diffie-Hellman es:
- Ambas partes acuerdan un número primo grande, que servirá como valor de semilla.
- Ambas partes acuerdan un generador de cifrado (típicamente AES), que se utilizará para manipular los valores de una manera predefinida.
- Independientemente, cada parte crea otro número primo que se mantiene secreto del otro lado. Este número se utiliza como la clave privada para esta interacción (diferente de la clave SSH privada utilizada para la autenticación).
- La clave privada generada, el generador de cifrado y el número primo compartido se utilizan para generar una clave pública que se deriva de la clave privada, pero que puede ser compartida con la otra parte.
- Ambos participantes luego intercambian sus claves públicas generadas.
- La entidad receptora utiliza su propia clave privada, la clave pública de la otra parte y el número primo compartido original para calcular una clave secreta compartida. Aunque esto se calcula de forma independiente por cada parte, utilizando claves privadas y públicas opuestas, resultará en la misma clave secreta compartida.
- El secreto compartido se utiliza entonces para cifrar toda la comunicación que sigue.
Este proceso permite que cada parte participe por igual en la generación del secreto compartido, lo que no permite que un extremo controle el secreto. También logra la tarea de generar un secreto compartido idéntico sin necesidad de enviar esa información a través de canales inseguros. El cifrado del secreto compartido que se utiliza para el resto de la conexión se llama protocolo de paquete binario.
El secreto generado es una clave simétrica, lo que significa que la misma clave utilizada para cifrar un mensaje puede ser utilizada para descifrarlo en el otro lado. El propósito de esto es envolver toda la comunicación posterior en un túnel cifrado que no puede ser descifrado por terceros.
Después de establecerse el cifrado de la sesión, comienza la etapa de autenticación de usuario.
Autenticación del acceso del usuario al servidor
El siguiente paso implica autenticar al usuario y decidir sobre el acceso. Hay algunos métodos que pueden utilizarse para la autenticación, según lo que acepte el servidor.
El método general es la autenticación por contraseña, que es cuando el servidor solicita al cliente la contraseña de la cuenta con la que intentan iniciar sesión. La contraseña se envía a través de la encriptación negociada, por lo que está segura frente a partes externas.
Aunque la contraseña estará encriptada, este método generalmente no se recomienda debido a las limitaciones en la complejidad de la contraseña. Los scripts automatizados pueden romper contraseñas de longitudes normales con facilidad en comparación con otros métodos de autenticación.
La alternativa más popular y recomendada es el uso de pares de claves SSH. Los pares de claves SSH son claves asimétricas, lo que significa que las dos claves asociadas tienen funciones diferentes.
La clave pública se utiliza para encriptar datos que solo pueden ser descifrados con la clave privada. La clave pública puede compartirse libremente, porque, aunque puede encriptar para la clave privada, no hay método para derivar la clave privada a partir de la clave pública.
La autenticación utilizando pares de claves SSH comienza después de que se haya establecido la encriptación simétrica como se describe en la sección anterior. El procedimiento ocurre de la siguiente manera:
- El cliente comienza enviando un ID para el par de claves con el que desea autenticarse al servidor.
- El servidor verifica el archivo
authorized_keys
de la cuenta a la que el cliente intenta iniciar sesión para encontrar el ID de la clave. - Si se encuentra una clave pública con un ID coincidente en el archivo, el servidor genera un número aleatorio y utiliza la clave pública para cifrar el número.
- El servidor envía este mensaje cifrado al cliente.
- Si el cliente realmente tiene la clave privada asociada, podrá descifrar el mensaje usando esa clave, revelando el número original.
- El cliente combina el número descifrado con la clave de sesión compartida que se está utilizando para cifrar la comunicación, y calcula el valor hash MD5 de este valor. MD5 es un algoritmo de resumen de mensajes que utiliza la función hash para generar un valor de hash de 128 bits.
- El cliente luego envía este hash MD5 de vuelta al servidor como respuesta al mensaje de número cifrado.
- El servidor utiliza la misma clave de sesión compartida y el número original que envió al cliente para calcular el valor MD5 por sí mismo. Compara su propio cálculo con el que el cliente envió de vuelta. Si estos dos valores coinciden, demuestra que el cliente estaba en posesión de la clave privada y el cliente está autenticado.
En resumen, la asimetría de las claves permite al servidor cifrar mensajes al cliente usando la clave pública. Luego, el cliente puede demostrar que posee la clave privada al descifrar correctamente el mensaje. Los dos tipos de cifrado que se utilizan (secreto compartido simétrico y claves públicas/privadas asimétricas) pueden aprovechar sus fortalezas específicas en este modelo.
Conclusión
Aprender sobre los pasos de negociación de conexión y las capas de cifrado en funcionamiento en SSH puede ayudarte a comprender mejor qué sucede cuando inicias sesión en un servidor remoto. Ahora puedes reconocer la relación entre varios componentes y algoritmos, y entender cómo todas estas piezas encajan. Para aprender más sobre SSH, consulta las siguientes guías:
- Cómo configurar la autenticación basada en claves SSH en un servidor Linux
- Cómo usar SSH para conectarse a un servidor remoto
- Cómo configurar claves SSH para varios sistemas operativos
- Conceptos básicos de SSH: Trabajar con servidores, clientes y claves SSH