<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>SSH on My personal blog</title>
        <link>https://www.matteobianchi.eu/tags/ssh/</link>
        <description>Recent content in SSH on My personal blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en</language>
        <lastBuildDate>Tue, 17 Feb 2026 09:00:00 +0100</lastBuildDate><atom:link href="https://www.matteobianchi.eu/tags/ssh/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Hardening di SSH</title>
        <link>https://www.matteobianchi.eu/p/hardening-ssh/</link>
        <pubDate>Tue, 17 Feb 2026 09:00:00 +0100</pubDate>
        
        <guid>https://www.matteobianchi.eu/p/hardening-ssh/</guid>
        <description>&lt;img src="https://www.matteobianchi.eu/p/hardening-ssh/cover.png" alt="Featured image of post Hardening di SSH" /&gt;&lt;h2 id=&#34;perché-conta&#34;&gt;Perché conta
&lt;/h2&gt;&lt;p&gt;Apri un server su Internet e in pochi minuti vedrai nei log tentativi di login SSH da indirizzi di
tutto il mondo: bot che provano &lt;code&gt;root&lt;/code&gt;/&lt;code&gt;admin&lt;/code&gt; con password comuni, senza sosta. SSH è la porta
principale e il bersaglio costante. La buona notizia: irrobustirlo è tra gli interventi col miglior
rapporto sforzo/beneficio. L&amp;rsquo;idea guida è eliminare ciò che i bot attaccano — le password — e ridurre
chi e come può entrare.&lt;/p&gt;
&lt;h2 id=&#34;il-passo-decisivo-solo-chiavi&#34;&gt;Il passo decisivo: solo chiavi
&lt;/h2&gt;&lt;p&gt;Una chiave Ed25519 non si indovina con il bruteforce come una password. Genera la coppia sul tuo
client, installa la pubblica sul server, verifica di poter entrare, &lt;em&gt;poi&lt;/em&gt; disabilita le password.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# sul CLIENT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh-keygen -t ed25519 -C &lt;span class=&#34;s2&#34;&gt;&amp;#34;matteo@laptop&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh-copy-id -i ~/.ssh/id_ed25519.pub matteo@server
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ssh matteo@server    &lt;span class=&#34;c1&#34;&gt;# verifica che la chiave funzioni PRIMA di togliere le password&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;sshd_config-riga-per-riga&#34;&gt;sshd_config, riga per riga
&lt;/h2&gt;&lt;p&gt;Metti le direttive in un drop-in dedicato (&lt;code&gt;/etc/ssh/sshd_config.d/hardening.conf&lt;/code&gt;) così
aggiornamenti e pacchetti non le sovrascrivono:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# /etc/ssh/sshd_config.d/10-hardening.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PermitRootLogin no               # root non entra mai direttamente: si usa sudo
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PasswordAuthentication no        # niente password: solo chiavi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;KbdInteractiveAuthentication no  # chiude anche la via &amp;#34;interattiva&amp;#34; alle password
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PubkeyAuthentication yes
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;AuthenticationMethods publickey
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;AllowUsers matteo deploy         # SOLO questi utenti possono fare SSH (whitelist)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MaxAuthTries 3                   # pochi tentativi per connessione
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;LoginGraceTime 20                # 20s per autenticarsi, poi chiude
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;X11Forwarding no                 # disattiva ciò che non usi
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;AllowAgentForwarding no
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;PermitRootLogin no&lt;/code&gt; e &lt;code&gt;PasswordAuthentication no&lt;/code&gt; da soli azzerano la quasi totalità dei bruteforce.
&lt;code&gt;AllowUsers&lt;/code&gt; è potente: anche se un account di servizio avesse una password debole, non è nella lista,
quindi SSH lo rifiuta a priori.&lt;/p&gt;
&lt;h2 id=&#34;algoritmi-moderni&#34;&gt;Algoritmi moderni
&lt;/h2&gt;&lt;p&gt;Limita cifrari e scambio di chiavi a quelli robusti (evita algoritmi legacy):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;# stesso file drop-in
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;applicare-in-sicurezza&#34;&gt;Applicare in sicurezza
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Non chiuderti fuori.&lt;/strong&gt; Valida la configurazione e tieni una sessione aperta mentre ne apri una nuova
per provare.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sshd -t                      &lt;span class=&#34;c1&#34;&gt;# valida la sintassi: se stampa errori, NON riavviare&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl reload sshd        &lt;span class=&#34;c1&#34;&gt;# applica senza buttare giù le connessioni attive&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# poi, da un ALTRO terminale: ssh matteo@server  → se funziona, sei a posto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;difese-di-contorno&#34;&gt;Difese di contorno
&lt;/h2&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;hl&#34;&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- fail2ban / sshguard: bannano gli IP dopo N tentativi falliti (meno rumore nei log)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- cambiare la porta 22: NON è sicurezza, riduce solo il rumore degli scanner
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line hl&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- limitare SSH al firewall: accettare la 22 solo da reti fidate (vedi cap. nftables)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- 2FA con PAM: aggiungere un secondo fattore (TOTP) oltre alla chiave (vedi cap. PAM)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Nota onesta: cambiare porta e fail2ban &lt;strong&gt;riducono il rumore&lt;/strong&gt;, non sostituiscono le chiavi. La vera
sicurezza è &amp;ldquo;niente password + whitelist utenti + chiavi forti&amp;rdquo;.&lt;/p&gt;


&lt;details&gt;
&lt;summary&gt;&lt;strong&gt;Domanda:&lt;/strong&gt; se uso già fail2ban che banna i bruteforce e cambio la porta SSH, i bot non mi trovano e non insistono. Serve davvero disabilitare le password e passare alle chiavi?&lt;/summary&gt;
&lt;p&gt;Sì, perché fail2ban e la porta non standard risolvono il &lt;em&gt;sintomo&lt;/em&gt; (il rumore dei bot di massa)
ma non la &lt;em&gt;vulnerabilità&lt;/em&gt; (una password indovinabile resta indovinabile). Sono difese utili come
contorno, non come sostituti, e la differenza emerge appena l&#39;attaccante non è un bot stupido. La porta
diversa dalla 22 ferma solo gli scanner pigri: chi ti prende di mira fa un port scan e trova il servizio
SSH in pochi secondi, qualunque porta tu usi — è security by obscurity, abbassa il rumore di fondo ma non
l&#39;attaccante mirato. fail2ban banna dopo N tentativi, ma non protegge da un attacco lento e distribuito
(pochi tentativi da molti IP, sotto la soglia), né da una password che compare in un leak e viene provata
una volta sola, con successo, senza mai scattare il ban. Soprattutto, entrambi presuppongono che esista
ancora qualcosa da indovinare: finché le password sono abilitate, la sicurezza del tuo server dipende
dalla password più debole tra tutti gli account abilitati — incluso magari un account di servizio o di
test che hai dimenticato. Passare alle chiavi elimina il problema alla radice: una chiave Ed25519 non si
indovina con la forza bruta in tempi umani, quindi i tentativi di login con password semplicemente non
possono riuscire, bannati o no. A quel punto fail2ban e la porta diventano quello che devono essere —
riduzione del rumore sopra una base già solida — invece dell&#39;unica cosa che ti separa da una
compromissione. L&#39;ordine giusto è: prima togli ciò che si può indovinare (password), poi aggiungi il
contorno. Non il contrario.&lt;/p&gt;
&lt;/details&gt;


&lt;h2 id=&#34;conclusione&#34;&gt;Conclusione
&lt;/h2&gt;&lt;p&gt;Chiavi al posto delle password, niente root diretto, whitelist di utenti, algoritmi moderni e un reload
validato: SSH passa da porta più attaccata a porta più solida. SSH è un consumatore del sistema di
autenticazione sottostante; per il secondo fattore, le policy password e il blocco dopo troppi
tentativi, bisogna scendere al livello che governa &lt;em&gt;come&lt;/em&gt; Linux autentica: &lt;a class=&#34;link&#34; href=&#34;https://www.matteobianchi.eu/p/autenticazione-pam/&#34; &gt;PAM&lt;/a&gt;, prossimo capitolo.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
