OpenSSH offre un'ottima sicurezza iniziale, poiché utilizza la separazione dei privilegi e il sandboxing. In questo modo, la piccola rete in ascolto e la parte di autenticazione sono separate dal resto, cioè viene eseguito come un utente diverso non privilegiato e con sandboxing può anche effettuare solo chiamate di sistema limitate.
Il problema principale è quindi il rilevamento della password a forza bruta. Il modo più semplice per limitare la superficie di attacco qui è disabilitare l'autenticazione della password, cioè consentire solo l'autenticazione a chiave pubblica o almeno limitare l'autenticazione della password a pochi utenti con password difficili da indovinare. Perché, una volta che l'utente malintenzionato ha accesso come utente locale, è spesso facile utilizzare un exploit di escalation di privilegi per ottenere l'accesso completo al sistema.
Inoltre, la limitazione della quantità di tentativi di connessione SSH limita la superficie di attacco mentre si sposta su una porta non standard.
Esempi dal mio 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
E le regole di iptables che uso per limitare la velocità di connessione per 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
E se pensi che questi metodi combinati non ti diano abbastanza tempo per reagire in caso di problemi di sicurezza importanti, puoi configurare un sistema multi-stage. Ad esempio, è possibile eseguire il daemon SSH visibile esternamente in una sorta di sandbox (chroot, container, macchina virtuale o reale) e fare in modo che l'utente effettui il login. Dopo il primo accesso riuscito, l'utente deve quindi accedere al prossimo livello del sistema ecc.