Hardening SSH: checklist operativa per proteggere i tuoi server
SSH è la porta d'ingresso principale ai tuoi server. Questa checklist di 15 step elimina il 95% degli attacchi automatizzati. Configurazione completa con esempi.

Ogni server Linux espone SSH. Ogni giorno, migliaia di bot cercano di forzare la porta 22 con password comuni. Se gestisci server per clienti, non puoi permetterti una configurazione SSH di default.
Questa checklist copre i 15 step che applichiamo su ogni server. Non sono opinioni: sono controlli che prevengono il 95% degli attacchi automatizzati.
Se stai lavorando dopo una compromissione già avvenuta, leggi prima Incident response: cosa fare nella prima ora di un server compromesso. Se invece vuoi inquadrare il lavoro come servizio continuativo, trovi qui la pagina Security Hardening.
Step 1: Chiavi SSH, basta con le password
La prima regola: disabilita l'accesso con password.
# Genera chiave (se non l'hai già)
ssh-keygen -t ed25519 -C "[email protected]"
# Copia sul server
ssh-copy-id -i ~/.ssh/id_ed25519.pub utente@server
# Testa l'accesso con chiave PRIMA di disabilitare password
ssh -i ~/.ssh/id_ed25519 utente@server
# Poi modifica sshd_config
sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication no/' /etc/ssh/sshd_config
sed -i 's/^#\?ChallengeResponseAuthentication.*/ChallengeResponseAuthentication no/' /etc/ssh/sshd_config
systemctl restart sshd
Se disabiliti l'accesso password senza aver verificato che la chiave funziona, rischi di perdere l'accesso. Sempre testare in una sessione SSH separata.
Step 2: Disabilita root login
sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
Usa un utente normale con sudo. Se qualcuno compromette la chiave di un utente, deve commeno indovinare la password sudo.
Step 3: Cambia la porta SSH
Non fermare gli attacchi, ma riduci il rumore:
sed -i 's/^#\?Port.*/Port 2222/' /etc/ssh/sshd_config
Aggiorna il firewall:
# nftables
nft add rule inet filter input tcp dport 2222 accept
# iptables
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP
Step 4: Fail2ban (sempre)
apt install fail2ban
cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
EOF
systemctl enable --now fail2ban
Step 5: Limita utenti SSH
# Solo utenti specifici
echo "AllowUsers admin deploy" >> /etc/ssh/sshd_config
Step 6: Timeout di sessione
echo "ClientAliveInterval 300" >> /etc/ssh/sshd_config
echo "ClientAliveCountMax 2" >> /etc/ssh/sshd_config
Dopo 10 minuti di inattività, la sessione muore.
Step 7: Disabilita forwarding
sed -i 's/^#\?AllowTcpForwarding.*/AllowTcpForwarding no/' /etc/ssh/sshd_config
sed -i 's/^#\?X11Forwarding.*/X11Forwarding no/' /etc/ssh/sshd_config
Step 8: Audit log dettagliato
sed -i 's/^#\?LogLevel.*/LogLevel VERBOSE/' /etc/ssh/sshd_config
Ora vedi nel log ogni tentativo di accesso, incluso l'utente usato.
Step 9: Limita algoritmi crittografici
cat >> /etc/ssh/sshd_config << 'EOF'
# Algoritmi sicuri (disabilita quelli obsoleti)
KexAlgorithms [email protected],diffie-hellman-group16-sha512
Ciphers [email protected],[email protected]
MACs [email protected],[email protected]
EOF
Step 10: Banner di avviso
echo "Authorized access only. All activity is monitored." > /etc/ssh/banner
echo "Banner /etc/ssh/banner" >> /etc/ssh/sshd_config
Step 11: Motd personalizzato
cat > /etc/motd << 'EOF'
========================================
Server: production-web-01
Owner: Web Agency S.r.l.
All connections are logged.
Unauthorized access is prohibited.
========================================
EOF
Step 12: Rate limiting su firewall
# nftables: max 5 connessioni/minuto
nft add rule inet filter input tcp dport 2222 \
ct state new limit rate 5/minute burst 5 packets accept
Step 13: 2FA con Google Authenticator (opzionale)
apt install libpam-google-authenticator
google-authenticator # segui il wizard
# Aggiungi a PAM
echo "auth required pam_google_authenticator.so" >> /etc/pam.d/sshd
# In sshd_config
echo "ChallengeResponseAuthentication yes" >> /etc/ssh/sshd_config
echo "AuthenticationMethods publickey,keyboard-interactive" >> /etc/ssh/sshd_config
Step 14: Monitoraggio tentativi di accesso
# Crea script di monitoring
cat > /usr/local/bin/ssh-watch.sh << 'EOF'
#!/bin/bash
FAILED=$(grep "Failed password" /var/log/auth.log | wc -l)
echo "Failed SSH attempts today: $FAILED"
if [ "$FAILED" -gt 100 ]; then
echo "WARNING: High number of failed SSH attempts!" | \
mail -s "SSH Alert: $(hostname)" [email protected]
fi
EOF
chmod +x /usr/local/bin/ssh-watch.sh
# Esegui giornalmente
echo "0 8 * * * /usr/local/bin/ssh-watch.sh" | crontab -
Step 15: Backup della configurazione
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%Y%m%d)
Checklist completa
Dopo aver applicato tutti gli step:
# Verifica configurazione
sshd -t
# Riavvia SSH
systemctl restart sshd
# Testa accesso
ssh -p 2222 -i ~/.ssh/id_ed25519 utente@server
# Verifica fail2ban
fail2ban-client status sshd
# Controlla log
tail -f /var/log/auth.log
| Step | Configurazione | Risultato | |------|---------------|-----------| | 1 | Chiavi SSH | Accesso senza password | | 2 | No root login | Utente normale + sudo | | 3 | Porta 2222 | Riduce scansione automatica | | 4 | Fail2ban | 3 tentativi = ban 1h | | 5 | AllowUsers | Solo utenti autorizzati | | 6 | Timeout | Sessioni morte dopo 10min | | 7 | No forwarding | Niente tunnel | | 8 | Log verbose | Audit completo | | 9 | Algoritmi | Solo crittografia moderna | | 10 | Banner | Avviso legale | | 11 | MOTD | Identificazione server | | 12 | Rate limit | Max 5 conn/min | | 13 | 2FA | Autenticazione a due fattori | | 14 | Monitoring | Alert su attacchi | | 15 | Backup config | Rollback rapido |
Quando applicare
Applica questa checklist su ogni nuovo server, prima di metterlo in produzione. Non aspettare il primo attacco.
Subito dopo SSH, il passo successivo è verificare patching, firewall applicativo, permessi file e backup immutabili. Per questo vale la pena collegare questa checklist a un runbook più ampio come Backup 3-2-1 per WordPress o a un assessment su audit gratuito.
La configurazione SSH è come le cinture di sicurezza: non serve finché non serve. E quando serve, salva la vita.
Pronto a smettere di occuparti dei server?
Audit scritto, zero impegni, report PDF con assessment della tua situazione.
Altri playbook collegati.
Guide che completano questo scenario operativo e ti aiutano a chiudere il cerchio tra diagnosi, prevenzione e continuità.
Come pulire un sito WordPress infetto senza peggiorare la situazione
Pulire WordPress non significa cancellare file a caso. Devi contenere, capire cosa è stato toccato, bonificare e chiudere il vettore prima di tornare online.
Hardening Linux 2026 per web agency: baseline seria per server di produzione
L'hardening non è una checklist cosmetica. È la baseline che decide quanto un server è facile da compromettere e quanto sei veloce a reagire quando succede qualcosa.
Joomla compromesso: checklist rapida di analisi e recovery
Joomla compromesso non va trattato come semplice errore CMS. Serve una checklist rapida per capire perimetro, accessi, file alterati e recovery sensato.