Marvin Pascale

[B.Log]

03 Marzo 2026

SSH Hardening

SSH Hardening

Qualche giorno fa ho iniziato a lavorare con un nuovo cliente.

Classico scenario: VPS economico, applicazione web in produzione, “va tutto bene”, nessun problema apparente.

Prime cose che faccio sempre in questi casi? Analisi dell’infrastruttura, programmo gli aggiornamenti, controllo servizi esposti… e poi uno sguardo ai log.

# journalctl -u ssh --since "30 days ago" | grep Failed | wc -l

Il numero non era drammatico. Era… costante.

Tentativi di login su root. Utenti random. IP da mezzo mondo.

Niente compromissioni, per fortuna. Ma abbastanza rumore da ricordarmi una cosa semplice:

Se SSH è esposto su Internet, qualcuno proverà ad entrarci. Sempre.

Da lì è partita una revisione completa dell’hardening. E, soprattutto, una riflessione più ampia.

Le basi che non dovrebbero essere opzionali

1. Root non deve poter entrare

Sul VPS del cliente era attivo.

PermitRootLogin yes

No.

La prima modifica è sempre questa:

PermitRootLogin no

Accesso solo con utente normale + sudo.

Motivi:

  • tracciabilità
  • riduzione del rischio
  • doppio layer da compromettere

Semplice. Ma fondamentale.

2. Password disabilitate

SSH esposto + password attive = attesa passiva di un brute force riuscito.

Configurazione minima:

PubkeyAuthentication yes
PasswordAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no

Chiavi ed25519, sempre:

ssh-keygen -t ed25519 -a 100

Dopo questa modifica, il rumore nei log diventa irrilevante.

3. Cambiare porta: serve davvero?

Sì.

Non è sicurezza strutturale. È riduzione del rumore automatico.

Port 2849

Con firewall aggiornato, ovviamente.

Nel VPS del cliente, dopo il cambio porta, i tentativi sono crollati drasticamente. Non perché il server sia “più sicuro” in senso assoluto, ma perché la maggior parte dei bot scansiona solo la 22.

Nel mondo reale, questo conta.

4. Ridurre tutto al minimo indispensabile

Alcune direttive che considero baseline:

MaxAuthTries 3
LoginGraceTime 30
AllowGroups sshusers admins
X11Forwarding no
AllowTcpForwarding no

Principio semplice: default deny, eccezioni mirate.

La domanda che mi ha fatto riflettere davvero

Mentre sistemavo il VPS mi sono chiesto:

Ma questo server deve davvero avere SSH esposto su Internet?

Perché spesso l’hardening diventa un esercizio tecnico… quando forse la soluzione più efficace è architetturale.

Quando NON dovresti esporre SSH

Negli ultimi anni sto spingendo sempre più verso modelli diversi.

Accesso via VPN

WireGuard su un nodo pubblico e SSH accessibile solo su subnet privata.

Risultato:

  • Porta SSH invisibile dall’esterno
  • Attacchi azzerati
  • Accesso controllato

Bastion host

Un solo server esposto, fortemente hardened, e tutti gli altri accessibili solo tramite quello.

Architettura classica, ancora perfettamente valida.

Apertura selettiva per IP

Se hai IP statico, puoi limitare l’accesso direttamente da firewall:

ufw allow from TUO_IP to any port 2849 proto tcp

Superficie di attacco ridotta praticamente a zero.

Ridurre l’esposizione > aggiungere regole

Questa è la vera lezione emersa dal VPS del cliente.

Puoi avere il miglior sshd_config del mondo. Ma un servizio non esposto è sempre più sicuro di uno perfettamente configurato ma pubblico.

A volte la miglior difesa è semplicemente non essere visibili.

CrowdSec: il passo successivo

Sul VPS del cliente era installato Fail2Ban.

Va benissimo. Fa il suo lavoro.

Ma negli ultimi tempi sto preferendo CrowdSec.

Perché?

Perché non è solo reattivo. È collaborativo.

CrowdSec:

  • analizza i log
  • identifica pattern malevoli
  • utilizza blacklist condivise
  • contribuisce in forma anonima alla community

In pratica: benefici della reputazione collettiva.

Installazione su Debian/Ubuntu

curl -s https://install.crowdsec.net | sudo bash
sudo apt install crowdsec
sudo apt install crowdsec-firewall-bouncer-iptables

SSH viene coperto automaticamente tramite le collection standard.

Controllo stato:

cscli metrics
cscli decisions list

Perché lo considero un upgrade rispetto a Fail2Ban

  • Analisi comportamentale più evoluta
  • Feed di reputazione condivisi
  • Ecosistema di bouncer (nginx, firewall, cloudflare…)
  • Dashboard e metriche più chiare

È come passare da una difesa locale a un sistema immunitario distribuito.

La mia baseline oggi

Se dobbiamo configurare un VPS esposto:

  • root login disabilitato;
  • solo chiavi moderne (es:ed25519);
  • porta non standard;
  • accesso limitato a gruppi specifici;
  • logLevel VERBOSE;
  • crowdSec attivo,
  • preferibilmente accesso via VPN.

E soprattutto:

SSH esposto solo se strettamente necessario.

Conclusione

Quel VPS non era compromesso. Non era configurato male in modo drammatico.

Era semplicemente “normale”.

Ed è proprio questo il problema.

Nel 2026, un server “normale” esposto su Internet è un bersaglio automatico.

L’hardening non è paranoia. È riduzione del rischio.

E spesso la mossa più intelligente non è aggiungere un’altra direttiva a sshd_config.

È chiudere la porta.


Le opinioni in quanto tali sono opinabili e nulla ti vieta di approfondire l’argomento.

Risorse: