Un server Linux con SSH aperto su Internet riceve tentativi di accesso automatici di continuo, a qualunque ora. La difesa efficace non è una collezione di trucchi ma tre livelli coerenti: SSH che accetta solo chiavi, fail2ban che blocca chi insiste, UFW che lascia aperte solo le porte necessarie. Questa guida li configura su Ubuntu 26.04 e Debian 13 con una procedura pensata per non chiudersi mai fuori dal server.
In breve
- Tempo: 30–40 minuti.
- Difficoltà: media.
- Cosa serve: un server Ubuntu 26.04 LTS o Debian 13, un utente con
sudoche entra già con chiave SSH, l’accesso alla console web del provider come emergenza.
Versioni di riferimento: OpenSSH 10.2, fail2ban 1.1.0, UFW 0.36.2 (pacchetti di Ubuntu 26.04; Debian 13 ha le stesse versioni di fail2ban e UFW). Procedura verificata sulla documentazione ufficiale al 4 novembre 2026.
Prerequisiti: le tre regole per non chiudersi fuori
- Una sessione aperta, una di prova. Ogni modifica a SSH o al firewall si collauda da una seconda finestra del terminale. La prima resta aperta finché la seconda non entra.
- La console di emergenza. Individuate nel pannello del provider la console web (VNC/KVM): funziona anche con SSH spento.
- Snapshot o copia della configurazione. La documentazione di Ubuntu suggerisce di conservare una copia protetta dell’originale:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.originalesudo chmod a-w /etc/ssh/sshd_config.original.
Se non avete ancora creato l’utente amministrativo e copiato la chiave, partite dalla guida https://hardwarfare.it/ai-software/linux/primo-setup-vps-ubuntu-ssh-firewall/.
Passo 1: fotografare cosa è esposto
Prima di blindare, guardiamo cosa ascolta davvero sulla rete:
sudo ss -tulpnL’elenco mostra porte TCP e UDP in ascolto e il processo che le apre. Tutto ciò che ascolta su 0.0.0.0 o [::] è raggiungibile dall’esterno se il firewall lo consente; ciò che ascolta su 127.0.0.1 no. Un database o un pannello di amministrazione su un indirizzo pubblico sono il primo problema da risolvere, prima ancora di SSH.
Su Ubuntu 26.04 la porta 22 può risultare aperta da systemd oltre che da sshd: Ubuntu usa l’attivazione via socket (ssh.socket), che tiene la porta in ascolto e avvia il demone alla prima connessione. È normale.
Passo 2: SSH solo a chiavi, con un drop-in
Ubuntu include in cima a /etc/ssh/sshd_config la riga Include /etc/ssh/sshd_config.d/*.conf. Il manuale di OpenSSH precisa che per ogni parola chiave vale il primo valore ottenuto e che i file inclusi con caratteri jolly sono letti in ordine lessicale. Conseguenza pratica: le impostazioni vanno in un file a parte, con un nome che venga prima di eventuali file aggiunti dal provider o da cloud-init.
sudo nano /etc/ssh/sshd_config.d/00-hardening.conf
# solo chiavi pubbliche
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
# niente accesso diretto come root
PermitRootLogin no
# solo questi utenti possono entrare
AllowUsers NOMEUTENTE
# meno tentativi per connessione (il default è 6)
MaxAuthTries 3AllowUsers è la direttiva più efficace e la più pericolosa: se il nome è scritto male, nessuno entra. Mettete tutti gli utenti che devono accedere, separati da spazi.
sudo sshd -t
sudo systemctl restart ssh.serviceVerifica: sshd -T (modalità di test estesa) stampa la configurazione effettiva dopo aver applicato tutti i file. Con sudo sshd -T | grep -E 'passwordauthentication|kbdinteractiveauthentication|permitrootlogin|allowusers|maxauthtries' dovete leggere esattamente i valori impostati. Poi, da una seconda finestra: ssh NOMEUTENTE@IP_SERVER deve entrare, mentre ssh -o PubkeyAuthentication=no NOMEUTENTE@IP_SERVER deve rispondere Permission denied (publickey).
Passo 3: UFW con regola limit per SSH
Se UFW non è attivo, abilitatelo come spiegato nella guida al primo setup. Qui sostituiamo la regola semplice per SSH con una a frequenza limitata: secondo il manuale di ufw, una regola limit blocca un indirizzo che apre 6 o più connessioni in 30 secondi.
sudo ufw limit 22/tcp
sudo ufw delete allow OpenSSH
sudo ufw status numberedL’ordine conta: prima si aggiunge la nuova regola, poi si toglie la vecchia, così SSH non resta mai scoperto.
Verifica: sudo ufw status verbose deve mostrare 22/tcp LIMIT IN per IPv4 e IPv6 e nessuna regola ALLOW residua per la 22. Confrontate le altre regole con l’output di ss -tulpn: ogni porta aperta deve corrispondere a un servizio che volete esporre.
Se usate Docker, ricordate che le porte pubblicate dai container scavalcano UFW: il motivo e le soluzioni sono nella guida https://hardwarfare.it/ai-software/linux/installare-docker-compose-ubuntu-debian/.
Passo 4: installare e configurare fail2ban
fail2ban legge i log, conta i tentativi falliti e blocca temporaneamente gli indirizzi che superano la soglia. Su Ubuntu 26.04 il pacchetto arriva già pronto per i sistemi senza file di log tradizionali: il file /etc/fail2ban/jail.d/defaults-debian.conf attiva la jail sshd con backend = systemd (legge dal journal) e usa nftables per i blocchi.
sudo apt install fail2banLe modifiche non vanno mai fatte in jail.conf, che viene sovrascritto dagli aggiornamenti: il manuale di fail2ban indica di usare file .local, letti dopo i .conf. Create /etc/fail2ban/jail.local:
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
# indirizzi mai bloccati: localhost e, se fisso, il vostro IP
ignoreip = 127.0.0.1/8 ::1 VOSTRO_IP_FISSO
# primo blocco di un'ora
bantime = 1h
# finestra di osservazione
findtime = 10m
# tentativi ammessi nella finestra
maxretry = 5
# i recidivi vengono bloccati per tempi via via più lunghi
bantime.increment = true
[sshd]
enabled = true
backend = systemdSe non avete un IP fisso, togliete VOSTRO_IP_FISSO dalla riga: meglio nessuna eccezione che un’eccezione sbagliata. bantime.increment usa il database di fail2ban per moltiplicare la durata del blocco a ogni recidiva (1, 2, 4, 8 volte e così via). Indicare backend = systemd anche qui rende la configurazione valida pure su Debian 13, che di default non scrive /var/log/auth.log.
sudo systemctl restart fail2ban
sudo systemctl enable fail2banVerifica: sudo fail2ban-client status deve elencare la jail sshd; sudo fail2ban-client status sshd mostra quanti tentativi falliti ha visto e quali indirizzi sono bloccati in questo momento. Su un server esposto da qualche ora, è raro che l’elenco resti vuoto.
Passo 5: leggere i log degli attacchi
Vale la pena guardare almeno una volta cosa arriva. Il journal di SSH su Ubuntu:
sudo journalctl -u ssh.service --since "1 hour ago"Le righe tipiche sono Invalid user admin from INDIRIZZO port PORTA, cioè tentativi con nomi utente inesistenti presi da elenchi standard (admin, test, oracle, postgres). Con le password disattivate sono innocui, ma fanno rumore e consumano risorse. Le decisioni di fail2ban sono invece in /var/log/fail2ban.log, con righe del tipo [sshd] Ban INDIRIZZO:
sudo tail -n 30 /var/log/fail2ban.logCosa non serve (o serve meno di quanto si dica)
| Misura | Effetto reale | Il nostro giudizio |
|---|---|---|
| Cambiare la porta di SSH | Riduce il rumore nei log, non ferma un attacco mirato: una scansione trova la nuova porta in pochi secondi | Facoltativo. Su Ubuntu richiede di gestire anche ssh.socket, e un errore vi chiude fuori. Mai come unica difesa |
| Password SSH lunghissime | Restano indovinabili o riutilizzabili | Inutile se le password sono disattivate |
| fail2ban senza chiavi SSH | Rallenta i bot, non elimina il rischio | Complemento, non sostituto |
| Bloccare il ping | Nessun beneficio pratico | Non serve |
| Chiavi con passphrase | Proteggono se il PC viene rubato o compromesso | Consigliate |
| Aggiornamenti automatici | Chiudono le vulnerabilità note senza intervento | Indispensabili |
Se qualcosa va storto
- Vi siete bloccati da soli con fail2ban (per esempio dopo vari tentativi con la chiave sbagliata): dalla console web,
sudo fail2ban-client set sshd unbanip VOSTRO_IPper la sola jail SSH, oppuresudo fail2ban-client unban VOSTRO_IPper tutte. Per evitare che ricapiti, se avete un IP fisso aggiungetelo aignoreip. Permission denied (publickey).dopo il passo 2: quasi sempre èAllowUserscon un nome sbagliato. Dalla console web correggete il file, poisudo sshd -tesudo systemctl restart ssh.service.sshd -tsegnala un errore: indica file e numero di riga. Non riavviate SSH finché il test non passa senza messaggi.- fail2ban non parte:
sudo fail2ban-client -dstampa la configurazione interpretata e fa emergere errori di sintassi injail.local. Controllate anchesudo systemctl status fail2ban. - La jail
sshdnon vede tentativi: il backend non èsystemd, oppure state cercando in/var/log/auth.logsu un sistema che non lo scrive. Verificate la rigabackendnella sezione[sshd].
Come tornare indietro
Per SSH basta rimuovere il drop-in e riavviare: sudo rm /etc/ssh/sshd_config.d/00-hardening.conf, sudo sshd -t, sudo systemctl restart ssh.service. Per fail2ban, sudo systemctl disable --now fail2ban sospende i blocchi; sudo apt purge fail2ban lo rimuove con la configurazione (salvate prima jail.local se vi serve). In UFW la regola limit si torna a sostituire con sudo ufw allow OpenSSH seguito da sudo ufw delete limit 22/tcp.
La nostra lettura
Su un server personale, la combinazione chiavi SSH, AllowUsers, UFW e aggiornamenti automatici copre la quasi totalità degli attacchi che vedrete nei log. fail2ban aggiunge pulizia e risparmio di risorse, non un muro in più. Il resto della sicurezza si gioca sui servizi che esponete: se pubblicate un sito, il passo naturale è https://hardwarfare.it/ai-software/linux/certificato-https-lets-encrypt-certbot/; se l’obiettivo è raggiungere la rete di casa senza aprire porte, guardate https://hardwarfare.it/guide/tutorial/vpn-casa-wireguard-fritzbox-server-linux/.
Fonti
- OpenBSD, sshd_config(5)
- OpenBSD, sshd(8)
- Ubuntu Server docs, OpenSSH
- fail2ban su GitHub
- Ubuntu manpages, fail2ban-client
- Ubuntu manpages, ufw(8)
- Ubuntu Community, UFW
Immagine di copertina: Wikimedia Foundation Servers 2015-4.jpg di VGrigas (WMF), licenza CC BY-SA 3.0, via Wikimedia Commons; elaborazione grafica HardWarfare.
Articolo redatto con il supporto di strumenti di intelligenza artificiale e verificato dalla redazione. Come usiamo l'AI · Come lavoriamo
