OpenSSH proporciona una muy buena seguridad inicial, ya que utiliza separación de privilegios y sandboxing. De esta manera, la parte de escucha y autenticación de la pequeña red se separa del resto, es decir, se ejecuta como un usuario diferente sin privilegios y con sandbox también puede hacer solo llamadas limitadas al sistema.
El problema principal es el sondeo de contraseñas de fuerza bruta. La forma más fácil de limitar su superficie de ataque aquí es deshabilitar la autenticación de contraseña, es decir, solo permitir la autenticación de clave pública o al menos limitar la autenticación de contraseña a pocos usuarios con contraseñas conocidas difíciles de adivinar. Porque, una vez que el atacante tiene acceso como usuario local, a menudo es fácil utilizar un exploit de escalado de privilegios para obtener acceso completo al sistema.
Además, limitar la cantidad de intentos de conexión SSH limita la superficie de ataque, al igual que el movimiento a un puerto no estándar.
Ejemplos de mi sshd_config:
Port 22 # port 22 gets rate limit with iptables
Port 22922 # use an uncommon port where nobody probes for unlimited access
AllowUsers user1 user2 trusted_user # limit users which might connect
PasswordAuthentication no # no password authentication by default
# allow password authentication only for users which care about their password
Match User trusted_user
PasswordAuthentication yes
Y las reglas de iptables que utilizo para limitar la velocidad de conexión para SSH.
iptables -N SSH_CHECK
# limit ssh on default port from same IP to 3/40 sec
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_CHECK
iptables -A SSH_CHECK -m recent --set --name SSH
iptables -A SSH_CHECK -m recent --update --seconds 40 --hitcount 3 --name SSH -j DROP
Y si piensa que estos métodos combinados no le dan tiempo suficiente para reaccionar en caso de un problema de seguridad importante, puede configurar un sistema de varias etapas. Por ejemplo, podría ejecutar el demonio SSH visible externamente en algún tipo de zona de pruebas (chroot, contenedor, máquina virtual o real) y hacer que el usuario inicie sesión allí. Después del primer inicio de sesión exitoso, el usuario debe continuar iniciando sesión en la siguiente etapa de su sistema, etc.