Una de las cosas que podemos hacer al gestionar un servidor web, por ejemplo con Rocky Linux, es realizar un hardening del servidor SSH, OpenSSH. Por eso te voy a recomendar unos cuantos valores que puedes configurar en el archivo sshd_config de tu servidor.
Cómo aseguramos SSH en Rocky Linux y otros sistemas RHEL
Lo primero que tenemos que hacer es editar el archivo de configuración de OpenSSH:
sudo vi /etc/ssh/sshd_config
Voy a comentar los valores uno por uno un poco más abajo. Al final hay que guardar el archivo con ESC y wq! Luego reiniciamos el servidor OpenSSH:
systemctl restart sshd.service
Antes de editar este archivo, haz una copia de seguridad: sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Cambiar el puerto por defecto
Por defecto, el puerto SSH es el 22. Debes cambiarlo por otro puerto no reservado (entre 1024 y 65535). Por ejemplo, podrías usar puertos como 2222, 2233, etc.
Port 2233
Recuerda, que debes abrir este puerto en el Firewall y cerrar el 22. Si usas FirewallD
sudo firewall-cmd --permanent --add-port=2233/tcp
sudo firewall-cmd --reload
- Si usas CSF, tienes que añadir el puerto a TCP_IN y TCP_OUT.
Si tienes activo SELinux, debes permitir este nuevo puerto también:
sudo semanage port -a -t ssh_port_t -p tcp 2233
Deshabilitar el acceso de root:
PermitRootLogin no
¡Ojo con esto! Sigue los pasos que te he indicado en Cómo quitamos el acceso root en Rocky Linux. Primero tienes que crear una cuenta de usuario con permisos limitados pero dentro del grupo wheel.
Si tienes una dirección IP fija desde la que accedes a tu servidor, puedes configurar en este archivo de configuración de OpenSSH que solo se pueda acceder desde esa dirección IP:
ListenAddress TuIPv4
Establecer un tiempo de gracia para el login
LoginGraceTime 30
Este es un valor seguro, pero de vez en cuando nos sorprenden con noticias como la aparición de una vulnerabilidad crítica en SSH, y todos corremos a nuestros servidores para ver si hay una actualización al paquete sel servidor Open SSH. Es lo que ha pasado con la regreSSHion de la vulnerabilidad CVE-2024-6387 del 1 de julio de 2024. No es la primera vez y no será la última.
En este caso, te recomiendan actualizar el paquete, pero a lo mejor tu distribución no lo ha publicado todavía. La opción que te dan es poner LoginGraceTime en 0 en la configuración SSH en tu servidor, pero también hay que configurar un valor apropiado para MaxStartups. Ponemos lo siguiente o cambiamos los valores:
LoginGraceTime 0
MaxStartups 10:30:60
Con esto conseguimos dos cosas:
- LoginGraceTime 0
- El parámetro LoginGraceTime define el tiempo que el servidor esperará a que un usuario se autentique exitosamente antes de desconectar la sesión. Si se establece en 0, no hay límite de tiempo para la autenticación, pero evitamos la ejecución de código por culpa de CVE-2024-6387. El valor predeterminado es 120 segundos. Lo aconsejable en una situación normal es ponerlo entre 30 y 60 segundos. Esta no es una situación normal. Para compensar un posible ataque DoS, cambiamos el siguiente parámetro a lo siguiente:
- MaxStartups 10:30:60
- Permitir hasta 10 conexiones no autenticadas.
- A partir de 10 y hasta 30 conexiones, la probabilidad de rechazar una conexión adicional es del 60%.
- Después de 30 conexiones, se rechazan todas las conexiones adicionales.
Limitar el número de conexiones no autenticadas
MaxStartups 10:30:60
Ya te he comentado en el punto anterior que hace esto. Es una buena práctica de seguridad recomendada por el CIS. Suele estar en 10:30:100.
Limitar los intentos de autenticación
MaxAuthTries 3
Puedes subirlo a 5 si tienes gente que tiene problemas para acceder a tu servidor por fallos en la password, pero un valor de 3 es un buen comienzo.
Limitar el número de sesiones por conexión:
MaxSessions 2
Es un buen valor, a no ser que quieras tener muchas sesiones abiertas de SSH en tu servidor. Valóralo tú mismo según tus necesidades.
Deshabilitar reenvío de agentes y TCP
AllowAgentForwarding no
AllowTcpForwarding no
GatewayPorts no
- Al deshabilitar el reenvío de agentes (AllowAgentForwarding), previenes que las credenciales de autenticación del usuario (claves privadas) sean reenviadas a través de la conexión SSH a otros servidores. Esto ayuda a evitar que un servidor comprometido acceda a otras máquinas a las que el usuario tiene acceso.
- Con este valor de AllowTcpForwarding impides que los usuarios SSH configuren túneles TCP a través de tu servidor
- GatewayPorts en no evita el reenvío de puertos (port forwarding) en interfaces externas. Solo está permitido en la interfaz loopback (127.0.0.1).
Deshabilitar la reenvío de X11
X11Forwarding no
Con estos evitas que se ejecuten aplicaciones gráficas en el servidor y se muestren en el cliente a través de la conexión SSH. Estamos en un servidor Linux, la línea de comandos es lo que usamos.
Deshabilitar contraseñas vacías
PermitEmptyPasswords no
El nombre es bastante descriptivo. Es una buena práctica de seguridad en cualquier sistema.
KeepAlive y definir intervalos junto con TCPKeepAlive
ClientAliveInterval 300
ClientAliveCountMax 3
TCPKeepAlive no
KeepAlive yes
El primer valor ayuda a detectar y cerrar conexiones SSH inactivas o caídas, asegurando que los recursos del servidor no se queden bloqueados por conexiones que ya no están activas. El segundo asegura que las conexiones SSH no se mantengan abiertas indefinidamente si el cliente no responde. El tercer valor indica que el servidor no realizará comprobaciones periódicas a nivel de TCP para verificar la conectividad. El cuarto valor asegura que las conexiones inactivas se cierren a nivel de aplicación, liberando recursos del servidor.
Deshabilitar el uso de DNS para evitar retrasos en la conexión
UseDNS no
Al no realizar búsquedas DNS, se reduce la cantidad de información sobre el cliente que el servidor intenta obtener, lo que mejora la privacidad.
Establecer un banner de advertencia
Banner /etc/issue
En este caso estás indicando que hay un banner en /etc/issue, por lo que debes crearlo en esa dirección:
sudo vi /etc/issue
Puedes poner lo siguiente:
*****************************************************************
ADVERTENCIA: El acceso no autorizado a este sistema
está prohibido y será procesado en la mayor medida
de la ley. Todas las actividades en este sistema son monitoreadas y registradas.
*****************************************************************
Lo guardas dando a ESC y luego con :wq!
Esta es una buena práctica. Este banner aparecerá cuando se haga login mediante SSH.
Comprueba que el Protocolo SSH v1 no está activado en tu servidor
En distribuciones Linux modernas no debería estar activado. Por defecto, el protocolo SSH debería solo funcionar en la versión 2. Te vas a un Terminal y te intentas conectar a tu servidor:
ssh -1 usuario@direccionIP -p 2233
Y tendrá que salir algo como esto:
SSH protocol v.1 is no longer supported
Si te sale otra cosa, pon lo siguiente en el archivo de configuración:
Protocol 2
Manejamos las conexiones SFTP
Subsystem sftp /usr/libexec/openssh/sftp-server
Indicamos expresamente como manejar las conexiones con el protocolo SFTP. En este caso, la ruta corresponde a Rocky Linux 9. El servidor SSH utiliza el programa especificado en esta línea (/usr/libexec/openssh/sftp-server) para gestionar la sesión SFTP.
EXTRA: dejamos que solo determinados usuarios accedan y que solo lo hagan a su directorio en home
Por si quieres que únicamente determinados usuarios del servidor accedan mediante SSH:
AllowUsers NombreUsuario1 NombreUsuario2
Y con la siguiente orden, los confinamos en el directorio /home/NombreUsuario1, /home/NombreUsuario2 (tienes que tener la estructura creada en tu servidor). %u es un comodín que se sustituye por el nombre de usuario que se está conectando:
ChrootDirectory /home/%u
EXTRA (hacerlo con precaución): Permitir solo autenticación por clave pública en SSH
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
Lo pongo como extra, porque en este caso eliminas completamente la autenticación con password y te obliga a usar claves de autenticación que hay que configurar previamente. Tienes una buena guía de cómo hacerlo en https://www.linode.com/docs/guides/use-public-key-authentication-with-ssh/. Muy importante chequear que todo funciona correctamente para no quedarte fuera del servidor. Te cuento como lo he hecho yo en Cómo usar claves SSH para acceder a tu servidor y gestionarlas con 1Password.
Aquí tienes un ejemplo de archivo sshd_config actualizado con estas recomendaciones de seguridad (no he puesto PubkeyAuthentication yes ni PasswordAuthentication no, ni ChrootDirectory):
# $OpenBSD: sshd_config,v 1.104 2021/07/02 05:11:21 dtucker Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options override the
# default value.
# To modify the system-wide sshd configuration, create a *.conf file under
# /etc/ssh/sshd_config.d/ which will be automatically included below
Include /etc/ssh/sshd_config.d/*.conf
# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 2233
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
#HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_ecdsa_key
#HostKey /etc/ssh/ssh_host_ed25519_key
# Ciphers and keying
#RekeyLimit default none
# Logging
#SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 30
PermitRootLogin no
#StrictModes yes
MaxAuthTries 3
MaxSessions 2
#PubkeyAuthentication yes
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile .ssh/authorized_keys
#AuthorizedPrincipalsFile none
#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody
# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes
# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
PermitEmptyPasswords no
# Change to no to disable s/key passwords
#KbdInteractiveAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the KbdInteractiveAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via KbdInteractiveAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and KbdInteractiveAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in RHEL and may cause several
# problems.
#UsePAM no
AllowAgentForwarding no
AllowTcpForwarding no
#GatewayPorts no
X11Forwarding no
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
TCPKeepAlive no
#PermitUserEnvironment no
#Compression delayed
ClientAliveInterval 300
ClientAliveCountMax 3
UseDNS no
#PidFile /var/run/sshd.pid
MaxStartups 10:30:60
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none
# no default banner path
Banner /etc/issue
# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server
GatewayPorts no
KeepAlive yes
Protocol 2
# Example of overriding settings on a per-user basis
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
Conclusión
Como recomendación final, deberías tener activo y bien configurado tu Firewall para vigilar el puerto SSH configurado y ejecutar bloqueos automáticos si se producen más de un determinado número de conexiones. Esto se puede realizar fácilmente con programas como Fail2Ban y CSF/LFD.
Te puede interesar: Cómo instalar Rkhunter en Rocky Linux.
Tienes más referencias en:
- https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html-single/securing_networks/index
- https://docs.rockylinux.org/guides/security/ssh_public_private_keys/
- https://docs.datadoghq.com/security/default_rules/xccdf-org-ssgproject-content-rule-sshd-set-maxstartups/
- https://rockylinux.org/news/2024-07-01-rocky-linux-9-cve-2024-6378-regression
- https://linuxhandbook.com/ssh-hardening-tips/