Introduzione
In questo articolo approfondiremo la configurazione di un server SSH su Ubuntu/Debian con un livello di sicurezza un po’ piu’ elevato. Non ci limiteremo alla semplice attivazione del servizio, ma esploreremo una strategia di configurazione modulare utilizzando la directory sshd_config.d
. Questo approccio consente di creare differenti casistiche di accesso in base alla rete di provenienza, al metodo di autenticazione e all’utente che tenta di collegarsi. Inoltre, vedremo come:
- Limitare gli accessi esterni a determinati utenti e chiavi pubbliche, filtrando per indirizzi IP di origine.
- Permettere, da rete interna, l’accesso anche con password per tutti gli utenti.
- Integrare firewall e fail2ban per mitigare i tentativi di accesso non autorizzati.
- Esporre la porta SSH su una porta alta tramite port forwarding, aumentandone la sicurezza.
- Preparare il terreno per automatizzare questi processi in futuro.
Assumeremo i seguenti prerequisiti:
- Il server è basato su Ubuntu/Debian con
sudo
abilitato per l’utente di amministrazione. - OpenSSH Server è installato.
- Un firewall (ad esempio
ufw
) è attivo e configurato. - Fail2ban è installato per prevenire i tentativi di brute-force.
- Il server dispone di un IP interno (LAN) e di un IP pubblico (o di un router con port forwarding configurabile).
- L’utente di amministrazione appartiene al gruppo
sudo
.
Perche’� adottare una configurazione modulare con sshd_config.d
Il file principale /etc/ssh/sshd_config
definisce il comportamento globale del server SSH. Tuttavia, utilizzando la directory /etc/ssh/sshd_config.d
, possiamo inserire file aggiuntivi che sovrascrivono o integrano la configurazione di base. Questo approccio modulare permette di mantenere il file principale pulito e di organizzare le diverse casistiche di accesso in file separati. È particolarmente utile quando si gestiscono scenari complessi e si ha necessità di apportare modifiche incrementali senza rischiare di compromettere l’intera configurazione.
Configurazione di base di OpenSSH
Installazione
Se non lo avete già fatto, procedete all’installazione:
1 | sudo apt update |
Il servizio sshd
sarà avviato e abilitato automaticamente.
Configurazione del firewall (UFW)
Assicuratevi che il firewall ufw
sia installato e attivato:
1 | sudo apt install ufw |
Per consentire la connessione sulla porta SSH standard (22), eseguite:
1 | sudo ufw allow 22/tcp |
Successivamente, quando imposteremo un port forwarding su una porta differente, modificheremo le regole di conseguenza.
Configurazione di fail2ban
Fail2ban blocca gli indirizzi IP che tentano di eseguire accessi non autorizzati (brute-force). Se non presente:
1 | sudo apt install fail2ban |
Nella configurazione predefinita, fail2ban monitorerà il file di log di SSH e bloccherà automaticamente gli IP che generano troppi tentativi falliti. È possibile personalizzare /etc/fail2ban/jail.local
per definire tempi di ban, numero di tentativi e altro. Un esempio basilare (da aggiungere o modificare in /etc/fail2ban/jail.local
):
1 | [sshd] |
Dopo aver modificato i parametri:
1 | sudo systemctl restart fail2ban |
Con questa configurazione di base, fallimenti ripetuti di autenticazione verranno puniti con il blocco temporaneo dell’IP.
Gestione utenti e privilegi sudo
L’utente amministrativo dovrebbe appartenere al gruppo sudo
. Se state utilizzando un utente diverso, potete aggiungerlo al gruppo:
1 | sudo adduser mio_utente |
In questo modo mio_utente
potrà eseguire comandi sudo
e gestire la configurazione del sistema.
Creazione di scenari differenziati
L’obiettivo è creare due casi d’uso:
Accessi dall’esterno:
- Limitati a specifici utenti (ad esempio
deploy
) - Limitati a specifici IP di origine
- Autenticazione solo con chiave, niente password.
- Limitati a specifici utenti (ad esempio
Accessi dalla rete interna:
- Consentiti per tutti gli utenti di sistema (ad esempio
mio_utente
o altri) - Autenticazione con password abilitata e chiavi ammessa
- Nessuna restrizione di IP (ma ci si basa sul fatto che l’indirizzo IP provenga dalla rete interna, ad esempio
192.168.0.0/24
).
- Consentiti per tutti gli utenti di sistema (ad esempio
Configurazione di base di /etc/ssh/sshd_config
Nel file principale /etc/ssh/sshd_config
lasceremo impostazioni generali di sicurezza:
1 | sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak |
Modifichiamo /etc/ssh/sshd_config
per disabilitare l’accesso root e alcune opzioni generali:
1 | UsePAM yes |
Salviamo e chiudiamo. Con Include /etc/ssh/sshd_config.d/*.conf
abbiamo dato istruzioni a sshd
di leggere file aggiuntivi nella directory sshd_config.d
.
Creazione dei file di configurazione modulari
Creeremo due file all’interno di /etc/ssh/sshd_config.d
:
00-internal.conf
per la rete interna01-external.conf
per l’accesso esterno
Configurazione interna: /etc/ssh/sshd_config.d/00-internal.conf
Questa configurazione consente a chiunque si trovi all’interno della rete interna (es. 192.168.0.0/24
) di autenticarsi con password:
1 | sudo nano /etc/ssh/sshd_config.d/00-internal.conf |
Inseriamo:
1 | Match address 192.168.0.0/24 |
Salviamo e chiudiamo.
Configurazione esterna: /etc/ssh/sshd_config.d/01-external.conf
Per l’accesso esterno, supponiamo di avere un IP pubblico o di filtrare l’accesso tramite firewall. Ad esempio, immaginiamo che solo da un certo IP pubblico o da un range (ad esempio aa.bb.cc.dd
) possa accedere l’utente deploy
. Inoltre, vogliamo obbligare l’autenticazione solo tramite chiave.
1 | sudo nano /etc/ssh/sshd_config.d/01-external.conf |
Inseriamo:
1 | Match User deploy, Address aa.bb.cc.dd |
In questo modo, se la connessione proviene dall’indirizzo aa.bb.cc.dd
e l’utente che tenta di accedere è deploy
, la password non sarà accettata, ma solo la chiave pubblica. Nessun altro IP o utente potrà usufruire di queste impostazioni.
Riavviare il servizio SSH per applicare le modifiche
Dopo aver creato i file di configurazione, riavviamo SSH:
1 | sudo systemctl restart ssh |
Chiavi SSH
L’utente deploy
che accede da remoto dovrà avere una coppia di chiavi. Sul client remoto, generiamo una chiave:
1 | ssh-keygen -t ed25519 -C "deploy@example.com" |
Copiare la chiave pubblica sul server (da remoto):
1 | ssh-copy-id deploy@ip_o_dominio_del_server |
Il comando ssh-copy-id
aggiungerà la chiave a ~/.ssh/authorized_keys
dell’utente deploy
.
Configurazione del firewall per differenti casistiche
Poiché da esterno si deve accedere solo con chiave e da determinati IP, si puo’ò rafforzare il tutto tramite ufw
, consentendo solo l’IP esterno specifico:
1 | sudo ufw allow from aa.bb.cc.dd to any port 22 |
Se desiderate bloccare tutti gli altri tentativi di accesso esterni, assicuratevi di non eseguire un ufw allow 22/tcp
generico, ma solo quello limitato all’IP sopra indicato. In caso foste costretti ad aprire a tutti l’accesso per qualche motivo, ricordate che fail2ban entra in azione per mitigare i tentativi di brute force.
Fail2ban e le due casistiche di accesso
Fail2ban non fa distinzioni tra accessi interni o esterni di default, ma grazie alla sua configurazione blocca gli IP che tentano numerosi accessi non autorizzati. Questo è utile specialmente per gli attacchi provenienti da Internet. Se notate che IP interni vengono bloccati, potete modificare la configurazione ignoreip
in /etc/fail2ban/jail.local
:
1 | [sshd] |
In questo modo gli IP interni non saranno bloccati, permettendo maggiore flessibilità nella LAN.
Dopo le modifiche:
1 | sudo systemctl restart fail2ban |
Spostare la porta SSH esterna su una porta alta con port forwarding
È una buona pratica non esporre la porta 22 direttamente su Internet. Si può configurare il router per effettuare un port forwarding da una porta alta (ad esempio 22222) verso la porta 22 del server.
Passi generali
Sul router/NAT:
Accedete all’interfaccia di gestione del vostro router e individuate la sezione “Port Forwarding” o “Virtual Server”.
Create una regola che inoltri la porta esterna 22222 (TCP) all’indirizzo IP interno del vostro server sulla porta 22.Configurazione del firewall interno per la nuova porta:
Poiché la porta 22 rimane aperta internamente, nella rete LAN tutto rimane come prima. Dall’esterno, però, l’utente si collegherà a
ssh -p 22222 deploy@mio_dominio
(se avete un nome di dominio puntato sul vostro IP pubblico).Se volete che il firewall accetti esplicitamente connessioni solo su 22 in LAN e non dall’esterno, potete chiudere la 22 dall’esterno e lasciare aperta solo tramite la regola del router:
1
sudo ufw deny 22/tcp
Ma questo bloccherebbe completamente SSH via 22 (anche internamente), quindi meglio gestire il firewall sul router o, se il server deve essere raggiungibile da LAN su 22, lasciare
ufw allow 22/tcp
ma consentire accesso esterno solo tramite l’IP specifico. Dipende dalla vostra topologia di rete.
Se volete segmentare, potete usare regole UFW avanzate per differenziare l’accesso esterno/interno (ad esempio definendoallow from 192.168.0.0/24 to any port 22
per la LAN, e negare tutto il resto).
Collegamento esterno sulla porta alta
Da un host remoto:
1 | ssh -p 22222 deploy@mio_dominio |
La connessione arriverà al vostro router, che la inoltrerà alla porta 22 del server, passando le regole di sshd
. Ricordate che l’utente deploy
ha l’accesso da quell’IP autorizzato e soltanto con chiave.
Considerazioni finali e spunti per l’automazione
Abbiamo creato una configurazione modulare che differenzia gli accessi SSH sulla base della rete di provenienza, del metodo di autenticazione e dell’utente, utilizzando i file in sshd_config.d
. Abbiamo integrato firewall, fail2ban e illustrato come effettuare un port forwarding per aumentare la sicurezza.
Questo approccio è solido, ma la sua gestione manuale puo’ò diventare complessa in ambienti di grandi dimensioni o con frequenti variazioni. Nel prossimo articolo potremmo esplorare meccanismi di automazione, utilizzando tool come Ansible, Puppet o Chef, per distribuire e mantenere queste configurazioni in maniera scalabile e ripetibile. L’automazione permetterebbe di applicare, testare e aggiornare queste configurazioni su un parco macchine esteso, riducendo il rischio di errori umani e semplificando il lavoro dell’amministratore di sistema.
Con questi spunti, si chiude questo lungo articolo, augurandoci che le informazioni fornite siano utili per implementare un accesso SSH sicuro, flessibile e ben organizzato.
Possibili Miglioramenti
Un ulteriore passo avanti verso una configurazione più robusta e scalabile potrebbe essere l’utilizzo di un reverse proxy posizionato davanti alla porta SSH esposta su Internet. In particolare, adottare un servizio come Cloudflare (gratuito nella fascia free per il traffico su porte HTTP/HTTPS, ma non per la porta SSH) consentirebbe di usufruire della loro rete globale di distribuzione, di strumenti di mitigazione avanzati contro attacchi DDoS, e di ulteriori livelli di filtraggio del traffico.
Tuttavia, questa configurazione introduce complessità aggiuntive: occorrerebbe consentire l’accesso solo agli indirizzi IP di Cloudflare, con una conseguente modifica delle regole firewall, una gestione più granulare delle liste di trusted IP e una combinazione di impostazioni su Cloudflare stesso.
Questa soluzione, pur più articolata, incrementa significativamente la resilienza del sistema e riduce l’esposizione diretta della vostra infrastruttura, rendendola meno vulnerabile alle minacce provenienti da Internet. Consideratela un’evoluzione del setup descritto in quest’articolo, una strada da intraprendere quando le esigenze di sicurezza e affidabilità diventano più stringenti.