JustVit

SSH: basi per la sicurezza

Eccoci di nuovo dopo il mio ultimo post sulla sicurezza riguardo la disabilitazione dell’account root su Ubuntu / Debian. Questa volta vi illustrerò come ho scelto di implementare alcune best practice di sicurezza con OpenSSH su alcune macchine che gestisco con sistemi operativi basati su Linux come Ubuntu, ma funziona anche con altre distribuzioni basate su Debian.

In questa guida cercherò di spiegare come mettere in sicurezza un servizio macchina ampiamente utilizzato chiamato OpenSSH da attacchi malevoli. Questi vengono solitamente eseguiti sfruttando alcune vulnerabilità di un sistema non configurato correttamente, lasciando il vostro server o PC disponibile a possibili attacchi.

Cos’è OpenSSH?

OpenSSH o più semplicemente ssh (secure socket shell) è un servizio ospitato da una macchina (server o host) che permette a un altro PC (client) di connettersi alla sua shell.

Questo servizio è di default in ascolto per connessioni sulla porta 22 dell’host.
La comunicazione è criptata dal servizio mettendo in sicurezza tutte le informazioni che verranno scambiate.

Come servizio predefinito su una macchina, questo servizio sarà già lì in attesa che qualcuno si connetta ad esso, anche se non lo userete mai.
La configurazione predefinita di Ssh di solito ha un’impostazione di sicurezza di base fornita dal sistema operativo che state per utilizzare o dal vostro provider di hosting, ecco perché uno dei primi passi è mettere in sicurezza le connessioni ssh.

Di seguito troverete alcuni suggerimenti per rafforzare il vostro servizio ssh.
Potete seguirli tutti o solo alcuni, questo dipende da quanto i servizi che state ospitando sono esposti ai pirati del web.

Come configuro il mio SSH?

Il vostro servizio OpenSSH lato server verrà eseguito nel sistema sotto il nome di “sshd” e può essere configurato personalizzando le vostre regole all’interno di un file di testo.

Apriamolo:

$ sudo nano /etc/ssh/sshd_config

In questo file saranno ospitate tutte le regole per sshd (sshd_config è per il server, ssh_config è per il client). Qui potete trovare le regole attive e le regole che non sono attive con un “#” all’inizio. Vi incoraggio a dedicare del tempo ad esplorare cosa c’è già all’interno.

Ricordate di salvare le modifiche che state per fare e cercate di ricontrollare sempre quello che state facendo. Se siete lontani dalla macchina o non avete altro modo di accedere alla macchina potreste bloccare voi stessi.

NOTA: dopo ogni modifica che state per fare al file sshd_config il servizio sshd deve essere riavviato:

$ sudo service sshd restart

Non sono responsabile per eventuali danni che potreste fare utilizzando le informazioni in questo articolo, qui troverete conoscenze con il solo scopo di mostrarvi come la sicurezza del servizio ssh può essere rafforzata.

Disabilitare il login root.

ATTENZIONE: prima di eseguire questo passaggio assicuratevi di non essere effettivamente loggati come utente root e di eseguire questi passaggi come utente sudo.
Se non siete sicuri di come farlo controllate in questa guida: Disabilitazione dell’account root su Ubuntu / Debian

Di default l’utente root è in grado di accedere al vostro sistema e questo è l’obiettivo principale per ampi attacchi a tutto campo. È evidente quanto sia importante evitare un possibile login da un utente con tali poteri.

Ora aggiungete su una riga vuota (di solito preferisco all’inizio del file):

PermitRootLogin no

Se non potete evitare di usare l’utente “root” saltate questo passaggio e concentratevi sui punti successivi per mettere in sicurezza ssh al meglio sulla vostra macchina.

Limitare l’accesso a utenti specifici

Se conosciamo gli utenti specifici che utilizzeranno il servizio ssh possiamo limitare l’accesso solo a quelli.

Possiamo farlo aggiungendo/modificando la riga:

AllowUsers Walter.W Jessie.P Saul.G 

Se dobbiamo specificare per un utente uno specifico IP da cui dovrebbe connettersi possiamo aggiungerlo in questo modo:

AllowUsers Jessie.P@10.10.0.122 Gustavo.F@pollos.hermanos.net

Allo stesso modo possiamo negare l’accesso a certi utenti questa volta con la regola:

DenyUsers Hector.S Tuco.S Todd.A

Limitare l’accesso a IP specifici

Come prima possiamo passare un elenco di IP al nostro servizio sshd dai quali garantiamo l’accesso alla nostra macchina.

Possiamo farlo aggiungendo al nostro sshd_config la regola:

ListenAddress 192.168.1.159 2001:0620::0211:24FF:FE80:C12C pollos.hermanos.net

Prima di salvare e riavviare il servizio assicuratevi che la macchina stia leggendo correttamente il vostro IP, se siete in un’altra rete potrebbe essere visto in modo diverso.

Cambiare porta del servizio

Poiché la porta standard del servizio ssh è sempre di default il numero 22 dovremmo considerare di cambiarla per mettere in sicurezza da attacchi ssh da bot che cercano sistemi in ascolto su quella porta.
Prima dovremmo assicurarci di scegliere un numero di porta che non sia in uso e che non verrà utilizzato in futuro e il suo numero sia tra 1024 e 65535.

Quando pronti aggiungete questa riga al vostro file:

Port 52022

Disabilitare password vuote

Di default il sistema permette agli utenti di impostare password vuote per i loro account.
Questo è molto insicuro e potete mettere in sicurezza ssh per rifiutare il login da un utente che ha una password vuota:

PermitEmptyPasswords no

Di default su molte regole il valore è già “no” (disabilitato) ma è meglio averlo scritto. Solo per essere sicuri. XD

Disabilitare l’autenticazione basata su host

Questo metodo di autenticazione vi dà un modo per effettuare il login in una macchina automaticamente grazie a una configurazione precedente sia sull’host che sul client di una chiave.

Poiché questo metodo è più probabilmente configurato quando state per lavorare con un pool di macchine lo disabiliteremo:

HostbasedAuthentication no

TCP wrapping

Anche se si chiama wrapping in realtà non lo faremo davvero, ma quello che questo metodo fa è eseguire un controllo sulle connessioni in entrata e vedere se corrispondono alla nostra configurazione.

Quindi quando una connessione vuole essere stabilita prima passa attraverso il servizio TCP-wrapper (libwrap). Questo demone confronterà l’origine delle connessioni con questi file:

/etc/host.allow
/etc/host.deny

Il programma passa attraverso i file in questo ordine.
Se c’è una corrispondenza allora la connessione verrà accettata o rifiutata.
Questo dipende di solito da quale file (.allow o .deny) verrà trovata la corrispondenza.
Se non viene trovata alcuna corrispondenza di default la connessione è permessa.

Questo strumento è perfetto per mettere in sicurezza ssh in combinazione con un firewall poiché un firewall non può esaminare cosa c’è all’interno delle connessioni criptate.

Questo argomento è piuttosto ampio con molte capacità e non possiamo approfondirlo qui in questo articolo, forse in un futuro articolo.

Aggiungerò un esempio di cosa potete fare con un approccio base:

#
# /etc/host.allow
#
# permetti tutte le connessioni dalla mia rete o localhost
ALL : 192.168.10.0/255.255.255.0 localhost

# permetti connessione a questi servizi da ovunque
ipop3d imapd sshd1 : ALL

# permetti connessione dall'host
sshd2 : david.v1t.it

e di solito nel file .deny andrete semplicemente a negare tutto il resto:

#
# /etc/host.deny
#
ALL : ALL

Impostare limite di tempo per i tentativi di login

Quando stiamo cercando di effettuare il login abbiamo un sacco di tempo per inserire username e password ma possiamo e dobbiamo accorciare questo tempo per evitare che possibili attacchi abbiano troppo tempo per stare lì e provare a testare il nostro sistema.

Possiamo aggiungere al nostro file di configurazione la riga:

LoginGraceTime 60

Più corto è meglio è.

Impostare limite di tempo per le sessioni

La connessione ssh tra client e server dopo essere stata stabilita rimane aperta fino a quando uno dei due decide di chiuderla o la connessione cadrà.
Questo può dare l’opportunità ad altri di arrivare al vostro computer quando non ci siete se di solito lo lasciate non protetto e fare quello che vogliono. Inoltre la connessione non chiusa correttamente può rimanere attiva e tenere occupate alcune risorse di sistema. A questo punto possiamo aggiungere regole per controllare l’inattività della sessione e chiudere la connessione dal lato server.

Questo sistema si basa sul fare un certo numero di controlli ogni x secondi e dopo che risulteranno tutti in uno stato inattivo chiudere la connessione.

Per impostare il tempo tra un controllo e l’altro dobbiamo aggiungere il seguente parametro:

ClientAliveInterval 60

e poi il contatore dopo quante volte il controllo è fallito prima di chiudere la connessione:

ClientAliveCountMax 60

In questo caso il sistema eseguirà 60 controlli con 60 secondi da uno all’altro:
60 x 60 = 3600 sec => 1 ora
prima che la connessione venga terminata per inattività.

Di default il sistema usa la funzione TCPKeepAlive per controllare se il client è ancora lì e chiudere la connessione solo se si è verificato un errore di comunicazione.
Questo metodo, a differenza del precedente che abbiamo impostato che avviene nel canale criptato, è meno sicuro poiché questo pacchetto di controllo che il sistema invia non è criptato e può essere falsificabile.
Quindi di solito lo disabilito dopo aver impostato il metodo precedente:

TCPKeepAlive no

Personalizzare il banner quando si fa login ssh

Quando proviamo a effettuare il login possiamo mostrare all’utente che sta cercando di effettuare il login un banner.
All’interno di questo banner possiamo aggiungere diverse informazioni e una delle best practice è aggiungere informazioni per un possibile attaccante per spaventarlo.

Anche se questa pratica non è un modo “ufficiale” per mettere in sicurezza ssh è comunque in grado di intimidire chi sta per attaccare il vostro sistema.

Possiamo farlo sembrare un dispositivo governativo o se stiamo conducendo un business consultare un avvocato prima di pubblicare qualsiasi cosa. Specialmente se terze persone lo useranno.

Il file potete crearlo ma di default il sistema ha già un file destinato a questo scopo:

$ sudo nano /etc/issue

Per impostare il file che OpenSSH utilizzerà per stampare al login dobbiamo aggiungere la regola:

Banner /etc/issue

Disabilitare il file di login .rhosts

Nel sistema, durante il tentativo di login, il file ~/.rhosts e ~/.shosts vengono analizzati per controllare se c’è qualche combinazione host-utente all’interno.

Se una combinazione host-utente è presente in questo file che corrisponde all’utente che sta cercando di effettuare il login gli verrà concesso l’accesso senza chiedere la password.

Poiché questa pratica è davvero insicura e un altro utente o servizio può arrivare a modificare questi file è molto suggerito di evitare che il nostro servizio ssh utilizzi questa funzione:

IgnoreRhosts yes

Forzare l’uso del Protocollo 2

Il nuovo protocollo 2 ha molti miglioramenti rispetto al vecchio protocollo 1 ma ancora la connessione può essere eseguita usando quello vecchio.
Oggi lo standard è la 2a versione e non è compatibile con quella vecchia.
Tuttavia dando alla connessione un parametro specifico la connessione può ancora essere eseguita.
Per evitare questa possibilità imposteremo la regola nel nostro file che impone di usare solo il protocollo 2 rifiutando quello vecchio:

Protocol 2

possiamo provare a connetterci al server con il parametro -1 e controllare quale sarà la risposta. (ricordate di salvare e riavviare il servizio prima)

$ ssh -1 Walter.W@10.10.0.100

Limitare i tentativi di password

Gli attacchi brute-force si basano sul provare un’enorme quantità di password cercando quella giusta. Per rendere la vita difficile a questi tentativi possiamo mettere in sicurezza ssh impostando un numero di password sbagliate fornite dopo il quale la connessione cadrà.

Dobbiamo impostare la regola:

MaxAuthTries 4

Quando i tentativi di connessione saranno più della metà del numero selezionato verranno registrati.

Questo metodo fa cadere la connessione ma una nuova può essere impostata immediatamente dopo dallo stesso client.
Per una migliore prevenzione contro questo tipo di attacchi è meglio migliorare un servizio Fail2Ban nel nostro server.

Non uso SSH, devo fare tutto questo?

No, la vostra migliore opzione a questo punto è rimuovere completamente il servizio.
Basta digitare questo comando e confermare:

$ sudo apt purge openssh-server

Questo comando cancellerà anche tutte le configurazioni e dipendenze.
Se volete mantenerle usate:

$ sudo apt remove openssh-server

Potrete sempre reinstallarlo attraverso il comando:

$ sudo apt install openssh-server

ChallengeResponseAuthentication

Questo valore è su molti sistemi di default “yes” ma cosa significa realmente?

Quando avviamo una connessione a un server ssh ci viene richiesto username e password. Ma se voglio anche altre informazioni per concedere a un utente l’accesso?

Fondamentalmente questa regola permette/nega la “keyboard-interactive authentication” (che deve essere abilitata attraverso un’altra regola di cui non parleremo qui).
In combinazione con altre regole permette al sistema di sfidare il processo di login chiedendo altre informazioni. Come cosa?

Come usare un’autenticazione a due fattori come quella di Google Authenticator, kerberos, RADIUS, ecc.

Se non avrete questi servizi aggiuntivi in esecuzione ora aggiungete semplicemente al vostro file:

ChallengeResponseAuthentication no

Evitare connessioni X11

Attraverso SSH è anche possibile stabilire una connessione con un’interfaccia grafica del vostro server.
Se non usate questa funzionalità è meglio disattivarla per evitare un possibile punto debole in futuro.

Potete farlo aggiungendo al file di configurazione la regola:

X11Forwarding no

Testare la vostra configurazione

Dopo aver aggiunto una regola nel vostro file sshd_config non potete stare lì a testarle tutte se sono state implementate.
Fortunatamente il servizio ha una routine che farà questo per voi.
Potete eseguirla con:

$ sudo sshd -t

Con l’opzione -T eseguirete quella estesa

Altre cose che potete fare per mettere in sicurezza ssh:

  • Usare l’autenticazione con chiave pubblica invece della password
  • Usare un servizio come Fail2Ban per prevenire attacchi bruteforce
  • Limitare l’accesso solo alla cartella utente per prevenire l’accesso alle cartelle root
  • Implementare un’autenticazione a 2 fattori
  • Usare l’autenticazione keychain (aiuta a gestire l’auth. con chiave pubblica)
  • Implementare un “honeypot”
  • Usare il “port knocking” per abilitare la porta solo quando necessario dall’esterno

Se avete richieste per il prossimo argomento sulla sicurezza postate semplicemente un commento e vedrò di programmarlo da qualche parte.

Il prossimo post sarà sul progetto a cui sto lavorando nella casa di un amico per creare un cervello domotico con un Raspberry usando OpenHab collegando tutte le sue luci, tende e immagino anche di più. 🙂

Commenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *