Come configurare fail2ban per SSH

Installa fail2ban, crea /etc/fail2ban/jail.local con una jail [sshd] abilitata e backend = systemd, riavvia e controlla con fail2ban-client status sshd. Blocca gli indirizzi dopo ripetuti login falliti. Riduce il rumore e rallenta i tentativi di indovinare, ma disattivare l'accesso con password ti protegge molto di più.

Aggiornata il . Eseguito con fail2ban 1.1.0 su un container Debian 13 usa e getta avviato con systemd e che usa nftables, con OpenSSH 10.0, e login falliti reali da un secondo container. Il file della jail predefinita è stato letto anche su Ubuntu 24.04.

Cosa fa

fail2ban legge i log. Quando un indirizzo fallisce il login maxretry volte entro findtime, aggiunge una regola del firewall che blocca quell'indirizzo per bantime. Tutto qui. Non ispeziona il traffico SSH e non rende robusta una password debole.

Installa

sudo apt install fail2ban python3-systemd

python3-systemd gli permette di leggere il journal di systemd. Sui sistemi della famiglia Red Hat il pacchetto è in EPEL. Su Debian 13 e Ubuntu 24.04 il pacchetto abilita già la jail sshd, con il backend systemd e nftables, tramite /etc/fail2ban/jail.d/defaults-debian.conf.

Configura: jail.local

Non modificare jail.conf, perché gli aggiornamenti possono sostituirlo. Metti le tue impostazioni in /etc/fail2ban/jail.local:

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 203.0.113.10
bantime  = 1h
findtime = 10m
maxretry = 5

[sshd]
enabled = true
backend = systemd
ImpostazioneSignificatoValore predefinito del pacchetto
bantimeQuanto dura un ban10m
findtimeLa finestra in cui i fallimenti si sommano10m
maxretryFallimenti ammessi in quella finestra5
ignoreipIndirizzi mai bloccatinessuno
backendDa dove arrivano i logauto

Aggiungi a ignoreip il tuo indirizzo fisso, così qualche errore di battitura non può chiuderti fuori. Se il tuo indirizzo cambia, assicurati di avere una console a cui ripiegare.

Usa backend = systemd dove i log di SSH vanno nel journal, come su Debian recente, che può non avere affatto /var/log/auth.log. Su un sistema che scrive quel file, puoi usare invece backend = auto e logpath.

Se sshd ascolta su un'altra porta, aggiungi port = 2222 alla jail. La regola che abbiamo visto corrispondeva solo alla porta indicata nell'impostazione della jail (tcp dport 22), quindi un ban sulla porta sbagliata non blocca nulla.

Prova il file, poi riavvia:

sudo fail2ban-client -t
sudo systemctl restart fail2ban

Controlla che funzioni davvero

sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
|  |- Currently failed:	0
|  |- Total failed:	4
|  `- Journal matches:	_SYSTEMD_UNIT=ssh.service + _COMM=sshd
`- Actions
   |- Currently banned:	1
   |- Total banned:	1
   `- Banned IP list:	203.0.113.20

Fai una prova reale. Da un altro indirizzo, non il server stesso e non uno in ignoreip, fai fallire un login con password ed esegui di nuovo il comando. Total failed deve salire. Se resta a 0, la jail non sta leggendo i log giusti, e il resto non serve a nulla. Confronta la corrispondenza nel journal con il nome della tua unit, ssh.service o sshd.service, e controlla con journalctl -u ssh -n 20.

Una volta bloccato, il client vede questo:

ssh: connect to host 203.0.113.10 port 22: Connection refused

La regola del firewall si vede con sudo nft list ruleset:

table inet f2b-table {
	set addr-set-sshd {
		type ipv4_addr
		elements = { 203.0.113.20 }
	}
	chain f2b-chain {
		type filter hook input priority filter - 1; policy accept;
		tcp dport 22 ip saddr @addr-set-sshd reject with icmp port-unreachable
	}
}

Comandi di tutti i giorni

ObiettivoComando
Elencare le jailsudo fail2ban-client status
Togliere il ban a un indirizzosudo fail2ban-client set sshd unbanip 203.0.113.20
Togliere tutti i bansudo fail2ban-client unban --all
Bloccare a manosudo fail2ban-client set sshd banip 203.0.113.20
Vedere i ban e quando finisconosudo fail2ban-client get sshd banip --with-time
Ignorare un indirizzo subitosudo fail2ban-client set sshd addignoreip 203.0.113.10
Leggere le impostazioni in usosudo fail2ban-client get sshd bantime
Leggere il suo logsudo tail /var/log/fail2ban.log

La modifica con addignoreip dura solo fino al prossimo reload. Aggiungila a jail.local per mantenerla.

Cosa conta come fallimento

Abbiamo provato la modalità predefinita su OpenSSH 10.0 con questi risultati:

  • Una password sbagliata è stata contata, come anche una password sbagliata per un utente che non esiste.
  • Una disconnessione Too many authentication failures è stata contata come uno.
  • Le connessioni che offrivano una chiave sbagliata e poi si arrendevano non sono state contate. Nel log compaiono come Connection closed by authenticating user.

Con mode = aggressive nella jail [sshd], sono state contate anche le connessioni con chiave sbagliata. Ne cattura di più, e rende anche più facile bloccare qualcuno con un client configurato male, quindi tieni ignoreip aggiornato.

Da cosa non protegge

  • Una chiave rubata o una password trapelata. Un login corretto non è un fallimento, quindi non c'è nessun ban.
  • Tentativi lenti o distribuiti. Molti indirizzi che fanno uno o due tentativi ciascuno restano sotto il limite.
  • Una debolezza di sshd stesso. Reagisce alle righe di log, a cose fatte.
  • Altri servizi, a meno che abbiano le proprie jail.

Può anche farti male: tutti dietro il NAT di un ufficio condividono un indirizzo, quindi gli errori di una persona possono chiudere fuori l'intero ufficio.

Se una chiave finisce in mani sbagliate, serve sapere dove è installata e togliere la chiave SSH da ogni server.

Cosa conta di più

Se il server accetta solo chiavi, per i tentativi con password non c'è nulla da indovinare, qualunque sia il numero di tentativi. Quindi fai prima questo:

  1. Usa una chiave e disattiva l'accesso con password.
  2. Limita chi può raggiungere la porta 22 con un firewall o una VPN, se puoi.
  3. Rivedi il resto delle tue impostazioni di sshd.

Dopo, fail2ban è un extra utile che tiene i log più tranquilli. Inoltre, OpenSSH 9.8 e successivi hanno un proprio PerSourcePenalties, attivo per impostazione predefinita, che rifiuta per poco tempo gli indirizzi che si comportano male. È molto più breve di un tipico ban di fail2ban, quindi i due funzionano bene insieme.

Domande

Come si sblocca un IP in fail2ban?

Esegui sudo fail2ban-client set sshd unbanip seguito dall'indirizzo. sudo fail2ban-client unban --all toglie tutti i ban in tutte le jail.

Come controllo che fail2ban funzioni?

Esegui sudo fail2ban-client status sshd, sbaglia un login da un altro indirizzo e ripeti il comando. Total failed deve salire. Se resta a 0, la jail non legge i log di SSH.

Perché un client bloccato vede Connection refused?

Con l'azione nftables predefinita su Debian, un indirizzo bloccato riceve un reject, quindi ssh stampa Connection refused invece di un timeout. Un'azione che scarta i pacchetti sembrerebbe invece un timeout.

Le chiavi SSH sbagliate contano come fallimenti?

Non nella modalità predefinita. Nel nostro test, cinque connessioni con una chiave sbagliata non hanno aggiunto nulla al conteggio. mode = aggressive nella jail le ha contate.

Fonti

Altro in Mettere in sicurezza un server

Tutte le guide