SSH Hardening y Auditoría

CiberSeguridad 21 de jul. de 2024

Conexiones SSH Cliente-Servidor

Hoy en día todas las conexiones entre equipos GNU/Linux se realizan mediante el protocolo ssh Secure Shell para conectarse de modo seguro entre un cliente y un servidor.

SSH es un protocolo y mecanismo para autenticar a un usuario remoto, transferir las peticiones desde el equipo cliente al servidor y luego enviar lo solicitado de vuelta al cliente.

Este servicio fue creado como reemplazo seguro para el protocolo telnet, que es un protocolo sin cifrar. SSH utiliza técnicas criptográficas para garantizar que las comunicaciones entre el cliente y el servidor se realicen de forma encriptada.

Funcionamiento esquematizado de SSH

Una conexión SSH se realiza del siguiente modo:

Paso 1: El cliente inicia la conexion SSH
Paso 2: El servidor SSH devuelve su clave pública de servidor
Paso 3: Se establecen los parámetros de conexión y se inicia un canal seguro
Paso 4: Se realiza el Login del usuario en el servidor remoto

SSH utiliza tres tecnologías diferentes de cifrado en el proceso de conexión:

  1. Cifrado simétrico
  2. Cifrado asimétrico
  3. Hashing

Versiones de SSH

A pesar de toda la seguridad, se van detectando fallos en el protocolo que se van solventando en nuevas versiones.

Actualmente hay 2 versiones:

  • SSH-1: Diseñado en 1995, se creó tras una detección de "snifado de contraseñas", fue desarrollado para proporcionar una autenticación y confidencialidad sólidas, al contrario de lo que ofrecían los protocolos ya existentes como rlogin, Telnet, FTP y rsh.
  • SSH-2: Esta versión del protocolo SSH se desarrollo oficialmente por «Secsh», un grupo de trabajo de la IETF (Internet Engineering Task Force).
    La versión 2 de Secure Shell se adoptó como estándar en 2006 y es incompatible con la versión SSH-1. SSH-2 incluye mejoras de seguridad, como la verificación de la integridad mediante códigos de autenticación de mensaje y la capacidad de ejecutar cualquier número de sesiones shell en una única conexión SSH.

La configuración de la conexión tanto de la parte cliente como en la parte del servidor se puede reforzar para aumentar la seguridad y evitar ciertas vulnerabilidades como ataques DDoS.

Securizando la conexión del cliente SSH

No sólo hay que disponer de un servidor ejecutando un servicio SSH totalmente seguro.

Hay que fortificar al cliente que realiza la conexión SSH para usar unicamente protocolos seguros, aceptar firmas CA correctas y aceptar solo algoritmos seguros para las claves públicas que se reciban desde la parte del servidor SSH al que queramos conectarnos.

En Debian 12 podemos fortificar nuestra conexión SSH hacia otro servidor remoto incluyendo (o creandolo si no existe) las siguientes línea en nuestro fichero ~/.ssh/config

Host *
   Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
 KexAlgorithms gss-curve25519-sha256-,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group14-sha256,gss-group16-sha512-,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256
   MACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com
   HostKeyAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256
   CASignatureAlgorithms sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256
   GSSAPIKexAlgorithms gss-curve25519-sha256-,gss-group16-sha512-
   HostbasedAcceptedAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256
   PubkeyAcceptedAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256

Esta configuración nos permite que nadie pueda "auditar" nuestra conexión SSH hacia un servidor remoto.

Securizando la conexión SSH del Servidor

Todos los siguientes pasos los vas a tener que ejecutar como usuario root

Antes de nada nos haremos un backup de toda la configuración actual, por si necesitamos volver atras:

# Backup de /etc/ssh (.tgz)
cd /etc
tar czvfp ssh.tgz ssh

Paso 1: Vamos a regenerar las claves RSA y ED25519 (publicas y privadas) del servidor:

# Regenerar claves propias del Servidor
rm /etc/ssh/ssh_host_*
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""

Paso 2: Eliminaremos del fichero moduli el modulo small Diffie-Hellman de generación de primos que está considerado inseguro:

awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.seguro
mv /etc/ssh/moduli.seguro /etc/ssh/moduli

Paso 3: Restringimos el soporte de exportación de claves, cifrado y algoritmos MAC y lo incluimos como fichero de configuración extra en la ruta:  /etc/ssh/sshd_config.d:

echo -e "# Restringir key exchange, cipher y algoritmos MAC.\nKexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,gss-curve25519-sha256-,diffie-hellman-group14-sha256,diffie-hellman-group16-sha512,gss-group16-sha512-,diffie-hellman-group18-sha512,diffie-hellman-group-exchange-sha256\n\nCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr\n\nMACs hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com,umac-128-etm@openssh.com\n\nHostKeyAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-256-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256\n\nRequiredRSASize 3072\n\nCASignatureAlgorithms sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256\n\nGSSAPIKexAlgorithms gss-curve25519-sha256-,gss-group16-sha512-\n\nHostbasedAcceptedAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256\n\nPubkeyAcceptedAlgorithms sk-ssh-ed25519-cert-v01@openssh.com,ssh-ed25519-cert-v01@openssh.com,sk-ssh-ed25519@openssh.com,ssh-ed25519,rsa-sha2-512-cert-v01@openssh.com,rsa-sha2-512,rsa-sha2-256-cert-v01@openssh.com,rsa-sha2-256\n\n\n" > /etc/ssh/sshd_config.d/ssh-audit_hardening.conf

Paso 4: Reiniciar el servicio SSH

systemctl restart ssh

Paso 5: Comprobamos que funciona la conexion SSH

Desde una nueva terminal, comprueba con tu usuario que puedes acceder sin problema. En la primera conexión del cliente al servidor deberas aceptar su nueva clave pública como válida:

ssh localhost

The authenticity of host 'localhost (::1)' can't be established.
ED25519 key fingerprint is SHA256:AEixxxxxxxxxxxx8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Warning: Permanently added 'localhost' to the list of known hosts.

ssh-audit: Auditoría de la conexion SSH

Puedes comprobar, primero sin aplicar ningún cambio y despues con los cambio aplicado, si la configuración de su cliente y servidor SSH es correcta realizando una prueba de conexión usando el programa ssh-audit

# Instalar ssh-audit en Debian
sudo apt update
sudo apt -y install ssh-audit

Uso de ssh-audit
Con tu propio usuario crea mediante ssh-audit una nueva conexión ssh en un puerto no ocupado (por ejemplo en el puerto 1234):

ssh-audit -c -p 1234

Abre una nueva terminal y simplemente realiza una conexion local al puerto escogido:

ssh localhost -p 1234

Vuelve a la primera terminal y comprueba los resultados:


# general
(gen) client IP: ::1
(gen) banner: SSH-2.0-OpenSSH_9.x Debian
(gen) software: OpenSSH 9.x
(gen) compression: enabled (zlib@openssh.com, zlib)

# key exchange algorithms
(kex) curve25519-sha256                     -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
(kex) curve25519-sha256@libssh.org          -- [info] available since OpenSSH 6.5, Dropbear SSH 2013.62
(kex) diffie-hellman-group14-sha256         -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group16-sha512         -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512         -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group-exchange-sha256  -- [info] available since OpenSSH 4.4
(kex) ext-info-c

# host-key algorithms
(key) sk-ssh-ed25519-cert-v01@openssh.com   -- [info] available since OpenSSH 8.2
(key) ssh-ed25519-cert-v01@openssh.com      -- [info] available since OpenSSH 6.5
(key) rsa-sha2-512-cert-v01@openssh.com     -- [info] available since OpenSSH 7.8
(key) rsa-sha2-256-cert-v01@openssh.com     -- [info] available since OpenSSH 7.8
(key) sk-ssh-ed25519@openssh.com            -- [info] available since OpenSSH 8.2
(key) ssh-ed25519                           -- [info] available since OpenSSH 6.5
(key) rsa-sha2-512                          -- [info] available since OpenSSH 7.2
(key) rsa-sha2-256                          -- [info] available since OpenSSH 7.2

# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com         -- [info] available since OpenSSH 6.5
                                            `- [info] default cipher since OpenSSH 6.9.
(enc) aes256-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes128-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes256-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr                            -- [info] available since OpenSSH 3.7
(enc) aes128-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52

# message authentication code algorithms
(mac) hmac-sha2-256-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) umac-128-etm@openssh.com              -- [info] available since OpenSSH 6.2

Si alguno no es satisfactorio, corrige los algoritmos que te indique la herramienta.

Extra: Implementar limitación de la velocidad de conexión

DHEat: El 24 de abril de 2024 se agregaron instrucciones de limitación de conexión para contrarrestar el ataque de denegación de servicio DHEat.

La solución más completa y flexible es utilizar iptables para permitir hasta 10 conexiones cada 10 segundos desde cualquier dirección de origen.

La solución alternativa es establecer la directiva PerSourceMaxStartups de OpenSSH con un valor 1.
Esto puede causar resultados incompletos si se realizan auditorías de ssh. También puede ocasionar fallos en el cliente si realiza conexiones en ráfaga.

Como root debes de realizar los siguientes pasos:

# Instalar iptables(+persistente) y netfilter(persistente)
apt install -y iptables netfilter-persistent iptables-persistent

# Ajustar las iptables
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP
ip6tables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --set
ip6tables -I INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 10 --hitcount 10 -j DROP

# Dejar las reglas de iptables en modo persiste tras los reinicios
service netfilter-persistent save

Etiquetas

Luis GuLo

🐧 SysAdmin GNU/Linux - 🐳 Docker - 🖥️ Bash Scripting - 🐪 Perl - 🐬 MySQL - 👥 Formador de TI - 👥 Formador de SysAdmin's - 💢 Ansible - ☁️ Cloud Computing - ❤️ Debian GNU/Linux