Come rendere più sicuro sshd_config: una checklist che puoi provare

Metti le tue impostazioni in un file drop-in come /etc/ssh/sshd_config.d/10-hardening.conf: PermitRootLogin no, PasswordAuthentication no, KbdInteractiveAuthentication no, AllowUsers con il tuo login, e valori più bassi per MaxAuthTries e LoginGraceTime. Controlla con sudo sshd -t, ricarica sshd e prova un nuovo login mentre la sessione attuale resta aperta.

Aggiornata il . Configurazione, sshd -t, sshd -T, sshd -T -C e ogni rifiuto mostrato qui sono stati eseguiti su OpenSSH 10.0p1 su Debian 13 in un container usa e getta, con un client OpenSSH 10.3 su macOS.

Tieni una sessione aperta mentre provi

Ricaricare sshd non termina le connessioni esistenti. Nel nostro test, una sessione aperta prima del reload ha continuato a funzionare e si è conclusa normalmente dopo. Quindi lascia aperta una sessione con i privilegi di root e fai tutte le prove da un secondo terminale. Se un'impostazione ti chiude fuori, la correggi dalla prima.

Prima di impostare PasswordAuthentication no, assicurati che l'accesso con chiave funzioni. Vedi come disabilitare l'accesso SSH con password.

Usa un file drop-in, e ricorda che vince il primo valore

Per la maggior parte delle impostazioni, sshd tiene il primo valore che legge. Debian e Ubuntu hanno Include /etc/ssh/sshd_config.d/*.conf in cima a sshd_config, quindi un drop-in prevale su una riga più in basso nel file principale. Sul nostro sistema di prova il file principale aveva PasswordAuthentication yes alla riga 125, e ha vinto il drop-in con no.

I file in quella cartella vengono letti in ordine di nome, e alcune immagini cloud ne aggiungono di propri, quindi un numero basso come 10- è una scelta sicura. Se il tuo sistema non ha una riga Include, modifica direttamente sshd_config e metti le impostazioni prima di qualsiasi blocco Match.

Le impostazioni

# /etc/ssh/sshd_config.d/10-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
AllowUsers deploy
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
ImpostazioneValore predefinito upstreamCosa fa la modifica
PermitRootLogin noprohibit-passwordRoot non può entrare affatto, nemmeno con una chiave. Le persone entrano con il proprio utente e usano sudo, che lascia traccia di chi ha fatto cosa.
PasswordAuthentication noyesElimina l'attacco di indovinare le password.
KbdInteractiveAuthentication noyesChiude l'altra strada verso una richiesta di password. Lasciala attiva se usi codici monouso tramite PAM.
AllowUsers deployNon impostato: qualsiasi account può provareSolo gli account elencati possono entrare. Un errore di battitura qui chiude fuori tutti, ed è per questo che la prima sessione resta aperta.
MaxAuthTries 36Meno tentativi per connessione. Ogni chiave offerta da un client conta, quindi un client con molte chiavi può esaurirli. Vedi Too many authentication failures.
LoginGraceTime 30120 secondiLe connessioni non autenticate vengono chiuse prima.
X11Forwarding nono, ma il file di Debian imposta yesDisattiva una funzione che la maggior parte dei server non usa mai.
AllowAgentForwarding noyesVedi i rischi dell'agent forwarding.
AllowTcpForwarding noyesImpedisce i tunnel SSH attraverso questo server e il suo uso come jump host. Non impostarlo se usi l'una o l'altra cosa.

Il manuale è chiaro su un limite: disattivare il TCP forwarding non migliora la sicurezza se agli utenti non viene negata anche la shell, perché chiunque abbia una shell può eseguire un proprio forwarder. Consideralo una pulizia per gli account che hanno una shell, e una vera restrizione solo per quelli che non ce l'hanno.

Lascia MaxStartups e PerSourcePenalties ai valori predefiniti, a meno che tu abbia un motivo. Nelle versioni attuali rallentano già le ondate di connessioni.

Controlla prima di ricaricare

sshd -t controlla la sintassi e le chiavi host. Non stampa nulla quando è tutto a posto. Un errore di battitura dà un errore e un codice di uscita diverso da zero:

$ sudo sshd -t
/etc/ssh/sshd_config.d/99-typo.conf: line 1: Bad configuration option: PermitRootLogn
/etc/ssh/sshd_config.d/99-typo.conf: terminating, 1 bad configuration options

sshd -T stampa i valori che sshd userà davvero, dopo aver combinato tutti i file. I nomi compaiono in minuscolo:

sudo sshd -T | grep -iE '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|allowusers|maxauthtries|logingracetime|x11forwarding|allowagentforwarding|allowtcpforwarding) '

Se usi blocchi Match, aggiungi -C per vedere il risultato per una connessione particolare:

sudo sshd -T -C user=deploy,host=example.com,addr=203.0.113.10 | grep -i allowtcpforwarding

sshd -T legge i file su disco, non ciò che il daemon in esecuzione ha caricato. Mostra cosa otterrai dopo il reload.

Ricarica e prova da un secondo terminale

# Debian, Ubuntu
sudo systemctl reload ssh
# Red Hat family
sudo systemctl reload sshd

Poi prova ciascuno di questi. Il primo deve riuscire e gli altri devono fallire:

ssh deploy@server 'echo ok'
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password deploy@server
ssh root@server
ssh -N -L 8022:127.0.0.1:22 deploy@server

L'ultimo comando non fallisce al login. Si collega, e l'inoltro viene rifiutato quando usi la porta locale. Il log del server mostra allora una riga come questa:

refused local port forward: originator 127.0.0.1 port 63434, target 127.0.0.1 port 22

Un login di root rifiutato compare nel log come User root from 203.0.113.10 not allowed because not listed in AllowUsers.

Algoritmi moderni: solo se ti serve restringerli

I valori predefiniti attuali di OpenSSH sono buoni. Su OpenSSH 10.0 l'elenco predefinito dello scambio di chiavi inizia con l'ibrido post-quantistico mlkem768x25519-sha256. Impostare propri elenchi significa doverli mantenere, quindi fallo quando lo richiede un audit o quando il tuo sistema è vecchio. Questo insieme tiene solo scelte moderne:

KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

Le versioni più vecchie di OpenSSH non conoscono alcuni di questi nomi. Esegui ssh -Q kex, ssh -Q cipher e ssh -Q mac sul server e rimuovi ciò che non è elencato. Controlla cosa negozia davvero un client:

ssh -v deploy@server true 2>&1 | grep -E 'kex: algorithm|server->client cipher'

I client e i dispositivi vecchi falliranno con questo messaggio, che ha una guida propria:

Unable to negotiate with 203.0.113.10 port 22: no matching key exchange method found.

Questo elenco elimina anche la curva NIST e gli scambi Diffie-Hellman, quindi prova ogni dispositivo e script che si collega al server prima di tenerlo.

Cosa non copre

Queste impostazioni riducono ciò che si può tentare contro sshd. Non correggono OpenSSH, quindi tienilo aggiornato. E non limitano ciò che può fare un utente che ha fatto il login. Per gli attacchi ripetuti nei tuoi log, vedi fail2ban per SSH.

Per vedere chi ci prova, vedi come controllare i tentativi di accesso SSH.

Domande

Ricaricare sshd chiude la mia sessione SSH aperta?

No. Le sessioni esistenti continuano dopo il reload. Solo i nuovi accessi usano le nuove impostazioni, per questo si prova da un secondo terminale.

Dove metto le mie impostazioni di sshd?

In un file dentro /etc/ssh/sshd_config.d/ con un numero basso, come 10-hardening.conf. sshd tiene il primo valore che legge, quindi vince un drop-in letto presto.

Come controllo se sshd_config ha errori?

Esegui sudo sshd -t. Non stampa nulla se la configurazione è valida, e un errore con codice di uscita diverso da zero se non lo è.

Fonti

Altro in Mettere in sicurezza un server

Tutte le guide