REALIZZAZIONE DI UN TUNNEL SSL SULL'IMAP SERVER

1. IMPOSTAZIONE DEL PROBLEMA

La posta elettronica è indubbiamente uno di servizi telematici più usati da ogni sorta di utenza. Purtroppo è anche il punto più critico circa la sicurezza delle informazioni che trasporta, per il semplice fatto che normalmente tra il computer client (cioè quello che chiama) ed il server (quello che risponde) i dati transitano in chiaro. Nel gergo informatico "in chiaro" significa semplicemente "non criptato", e questo implica che chiunque si trovi sulla nostra stessa rete può facilmente ricostruire le nostre conversazioni. A parte il fatto che probabilmente nessuno di noi usa la posta elettronica per gestire una guerra fredda, direi che è molto fastidiosa la consapevolezza che la nostra privacy può essere violata assai facilmente.
Quando ci si rese conto di quanto insicure fossero le comunicazioni via Internet, con i ben noti fenomeni di hackeraggio dei numeri delle carte di credito usate per fare del commercio elettronico, si corse ai ripari introducendo appositi "protocolli sicuri", ovvero criptati. I più noti sono SSH (Secure SHell) ed SSL (Secur Soket Layer) ideato da Netscape e successivamente modificato negli anni per renderlo sempre più sicuro.
In questo articolo vorrei spiegare come ho realizzato un server di posta in grado di accettare connessioni sicure basandosi sull'openSSL, la versione free di SSL. Prima di descrivere i dettagli tecnici tenterò di gettare qualche minima base teorica su come i computer dialogano tra loro usando i protocolli di internet (TCP/IP); per gli esperti questa parte è superflua, ma credo che molti novizi siano interessati a capire almeno in linea di massima cosa accade quando il loro PC si affaccia sulla rete di Internet!
A tutti buona lettura.

2. LA COMUNICAZIONE TRA I COMPUTER

Esistono molti modi per far parlare tra loro due o più computer, ma qui siamo interessati alla comunicazione su grande scala che è Internet.
Per iniziare diciamo che nel momento in cui un calcolatore si immette in rete, esso deve essere individuato univocamente in tutto il mondo da una sorta di "targa" che in linguaggio più tecnico si chiama "numero IP", dove IP sta per Internet Protocol. Una volta stabilita l'univocità del computer, alcune macchine particolari che fungono da "corrieri" provvedono ad indirizzare i dati (suddivisi in piccoli pacchetti) al computer che deve riceverli; tali "corrieri" sono i "router". Detto in termini molto semplici, quando un programma vuole inviare un'informazione tramite rete, il kernel (cioè il cuore del Sistema Operativo) provvede a spezzettarla in tanti piccoli pacchetti, ognuno dei quali contiene un "intestazione" ed un "corpo": l'intestazione contiene i dati del mittente e del destinatario del pacchetto, oltre al preavviso di quanto sarà lungo il corpo dello stesso, cioè la parte di dati trasportata dal pacchetto in questione.


Schema (elementarissimo!) di comunicazione tra computer. Figura presa da "Linux, TCP/IP e le reti" di M. Daddi

Ogni pacchetto viene numerato, e l'informazione viene ricostruita dal destinatario man mano che i pacchetti (inviati a lui dal router) gli arrivano. Se ad un certo punto il kernel del ricevente vede che manca il pacchetto n°16, lo dice al router e questo lo fa a sua volta presente al mittente: "Huè, qui ci siamo persi un po' di roba, rimanda il pacchetto 16 e, per sicurezza, i due prima ed i due dopo". Il motivo per cui a volte la rete ci sembra lenta è proprio questo, cioè l'eccessiva frammentazione dei pacchetti a causa dell'alto traffico nei nodi Internet!
Oltre al fatto della suddivisione in pacchetti, c'è un'altra cosa che non posso esimermi dallo spiegare, anche solo sommariamente: si tratta del concetto di "porta", che alcune volte chiamerò (erroneamente!) "socket". Dunque, è evidente a tutti che noi, quando siamo in rete, usiamo una singola linea (un "filo", tanto per intenderci!) per fare più cose, ad esempio per la posta, per navigare con Netscape, per fare telnet, per le chat e chi più ne ha più ne metta. La domanda che uno si porre è: come fa il mio computer a capire a quale applicazione deve andare un pacchetto IP? Cioè, ammettiamo che io scarichi la posta e nel frattempo navighi in Internet; ebbene, sulla connessione di rete passeranno più pacchetti, tutti destinati al mio IP, ma poi chi dice ad un pacchetto di andare a Netscape e ad un altro di andare a kMail?!? È ovvio che ci deve essere una qualche organizzazione più fine dietro tutta la bella interfaccina grafica dei programmi... allora coraggio, vediamo di capirci qualcosa: non è per questo che usiamo Linux? ;-)
L'arcano si spiega "abbastanza" facilmente. Il kernel (sì, sempre lui!) suddivide la connessione di rete in molte parti, come se da un filo ne diramasse molti altri (tanti, si tratta di migliaia!), e su ogni filo mettesse in ascolto un guardiano che non controlla altro se non quello che gli spetta. In termini più tecnici possiamo dire che una singola interfaccia di rete viene suddivisa in più "porte", ognuna specializzata per ascoltare un determinato tipo di "protocollo". Eh già, perché una connessione Internet sfrutta più protocolli (infatti si parla della "famiglia di protocolli" TCP/IP), ad esempio l'SMTP per spedire la posta, il POP/IMAP per ritirarla e così via.


NMAP è un'utilità che permette di vedere quali sono le porte aperte su un server.

Quando arriva il primo pacchetto di dati, diciamo di una mail, il kernel va a leggere qual'è il protocollo usato, vede SMTP, sa che il guardiano ("daemon", come si è solito chiamarlo) per l'SMTP si deve trovare sulla porta numero 25 e quindi controlla che effettivamente questo sia "sveglio", cioé pronto a stabilire la connessione; all'occorrenza lo sveglia piuttosto bruscamente con un secco "Ragazzo, qui c'è un pacchetto per te", il poverino non ha neppure il tempo di capire cosa sta succedendo ed ecco il secondo, il terzo e via di seguito tutti i dati che arrivano in fila indiana. Se invece il computer non deve essere in grado di usare l'SMTP, l'amministratore avrà disabilitato quella porta (la 25) e non ci sarà nessuno pronto ad utilizzare i pacchetti: questi saranno rimandati indietro con un poco diplomatico "Connection refused by the server", o qualcosa di analogo. Ecco, tra l'altro, perché è importante chiudere tutte le porte che non si debbono usare: esattamente ciò che non fa Windows!


Un client viene allertato circa la sua "incapacità di connettersi" al server flypro.roma2.infn.it, il cui numero IP è 141.108.16.119

Riguardo tali porte posso aggiungere che non tutte sono "libere", cioè ne esiste una serie che di default svolgono un certo lavoro, come ad esempio si può leggere dal seguente stralcio del file di configurazione dei servizi:

    ftp                    21/tcp
    ssh                   22/tcp                            # SSH Remote Login Protocol
    telnet                23/tcp                            # 24 - private
    smtp                 25/tcp         mail
    nameserver       42/tcp         name           # IEN 116
    gopher              70/udp
    finger                79/tcp
    www                80/tcp         http             # WorldWideWeb HTTP
    imap                 143/tcp                          # Interactive Mail Access

si vede, ad esempio, come l'smtp viene assegnato alla porta 25, il telnet "classico" alla porta 23 e così via. Tuttavia moltissime porte (circa 30 mila!) rimangono libere e disponibili per gli utenti, oltre che per gli hacker!
Proprio l'esistenza di queste porte libere permette di creare nuovi servizi basandosi su quelli già esistenti. Tra poco verrà fornito un esempio che reputo molto utile e che riguarda la posta elettronica... A fine di questo "paragrafo" mi scuso con gli esperti: so perfettamente che stanno rabbrividendo per come ho esposto questi semplici cenni circa la comunicazione tra computer che, ribadisco, non hanno nessuna pretesa di completezza e formalità.

3. PROTOCOLLI SICURI E PORT-FORWARDING

Riepiloghiamo.
Finora abbiamo visto che la comunicazione via Internet è generalmente insicura a causa dell'assenza di crittografia, tuttavia nel tempo sono stati ideati algoritmi e protocolli per la trasmissione sicura (SSH ed SSL, ad esempio). I vari protocolli, che formano la famiglia TCP/IP, vengono riconosciuti dal kernel che dipendentemente dalla loro natura li indirizza sulla porta a loro dedicata oppure li rimanda indietro se questa non è disponibile. Le porte dei servizi comuni sono state standardizzate, ma ne rimane un gran numero per creare socket ad-hoc, cioè per creare servizi nuovi o non previsti. Inoltre nessuno ci vieta di spostare un servizio da una porta all'altra, ad esempio se vogliamo far parlare due calcolatori tramite ssh sulla porta 12419 (anziché sulla 23 che è quella standard) possiamo farlo semplicemente modificando il file services su entrambi i computer, semprechè questi non abbiano la porta 12419 già impegnata da altri servizi: mica vogliamo fare un'ammucchiata di demoni dentro una porta!... il kernel è molto pudico e non lo permetterebbe ;-)
Veniamo ora al motivo vero e proprio del presente articolo. Esistono vari modi per ritirare la posta da un server. I più comuni sono il POP3 e l'IMAP. La differenza sostanziale tra i due è che il POP3 lavora più "in locale" mentre l'IMAP lavora più "sul server"; in altre parole con il POP3 ci si collega, si ritira la posta, la si cancella dal server, ci si disconnette e si lavora a casuccia sul proprio PC mentre sul server non rimane più traccia di noi. Invece con l'IMAP lasciamo sempre copie aggiornate delle nostre mail, e questo può essere utile se vogliamo disporre della nostra posta in tutte le parti del mondo oppure se vogliamo "sfruttare" i continui backup solitamente effettuati sui server.
Supponiamo di voler usare l'IMAP, altrimenti dovreste attendere l'uscita dell'articolo "SSH tunneling over POP3", fate un po' voi!
Come noto (dal pezzetto di "services" riportato sopra) la porta del demone per l'IMAP3 è la 143. Questo significa che quando noi chiediamo al server di darci la posta, mandiamo dei pacchetti alla porta 143. La prima cosa che il server ci chiede è ovviamente il nome di login, quindi la password e se tutto va bene ci lascia entrare. Il punto critico è che login/password passano in chiaro, quindi chiunque le può leggere.


In questa sessione telnet si vede chiaramente come avviene la transazione tra server e client

Ma non finisce qui: anche la posta transiterà in chiaro! È a dir poco ovvio che così facendo non può esserci potenzialmente nessuna pretesa di riservatezza. Personalmente la cosa mi infastidisce parecchio perché, tanto per dirne una, se mia sorella diventasse un hacker potrebbe leggere tutte le tenerissime (ed imbarazzantissime) lettere d'amore che mi sono scambiato con la mia meravigliosa ex, Roberta, e la cosa non mi farebbe piacere in quanto non potrei più ricattarla come faccio ora visto che sono io il "root" del sistema!
A parte le battute, qualcuno potrebbe avere motivi più seri per evitare di essere "sniffato", ad esempio può mandare dati molto personali via mail, progetti, risultati di analisi o di esperimenti. La domanda che sorge quindi spontanea è: si può fare in modo che i dati di login e tutto il resto passino in maniera comprensibile solo dal server e dal mio PC? La risposta è affermativa: è possibile crittografare tutti i dati in transito su una connessione IMAP con un livello di complicatezza alto quasi a piacere, ed il trucco consiste nello sfruttare l'SSL. Il concetto è piuttosto semplice, e di questa semplicità bisogna ringraziare il kernel di Linux e tutti gli sviluppatori che ci lavorano!
Dunque, come primo passo si chiude la porta 143. Caspita, si dirà, così sì che è sicuro: non posso più fare la connessione! Ma quello che si fa è di aprire un'altra porta sulla quale metteremo in ascolto IMAPD (il demone di IMAP, si noti che finisce con la D di Daemon!) però "incapsulato" in qualche modo dentro la guaina dell'SSL che usa è un protocollo crittografato. In pratica si realizza un "tunnel" di SSL intorno al demone dell'IMAP, quindi tutto ciò che passa da/verso quest'ultimo rimane costantemente sotto il controllo dell'inviolabile SSL. Qualcuno obbietterà "perché inviolabile?". In informatica "inviolabile" sta per "raramente indovinabile", e a conti fatti sembra che per trovare la chiave di crittografia dell'SSL attuale occorra un tempo molto maggiore dell'età dell'Universo! Se anche così vi sentite insicuri, scrivete le vostre lettere a mano con inchiostro simpatico e consegnatele di persona...
Vorrei far notare che la tecnica del tunneling è più generale di quanto non emerga dalle mie poche parole. Si può fare il tunneling del POP3, dell'FTP ed addirittura di sessioni grafiche tramite SSH. È palese, tuttavia, che le connessioni "tunnel" saranno più lente di quelle standard, se non altro perché le macchine devono criptare e decriptare in real-time tutti i dati in transito. Nel mio caso ho un Pentium 133 che funge da server (di tutto!) ed avendo scelto inizialmente un eccessivo livello di crittografia alla terza connessione il processore "crepava" e con lui tutta la rete! Insomma, quello che voglio dirvi e di non esagerare altrimenti dovreste avere un server Alpha quadriprocessore per lavorare!

4. QUALCOSA IN PIÙ CIRCA L'SSL

Nelle prossime righe vorrei brevemente dire come funziona OpenSSL, per poi passare al conclusivo paragrafo circa i dettagli tecnici necessari per settare il server IMAP sicuro. Il punto chiave sta nella presenza di due certificati (o "firme" elettroniche) che permettono il riconoscimento reciproco e fidato di due computer in rete.
Anzitutto l'amministratore del server provvederà a generare due "chiavi", una detta "pubblica" ed una detta "privata". Ad un certo momento accade che un client invia una richiesta di connessione al server e che questo, in risposta, esibisca la sua chiave pubblica. L'utente del client viene dunque avvertito della richiesta di stabilire una connessione crittografata ed inizia la visualizzazione dei suoi dati caratteristici e tante altre amene cosine che qui tralascio!
Supponiamo che io (ovvero il client) decida di accettare la connessione criptata: a mia volta genererò (via la chiave pubblica del server) una chiave che sarà mantenuta localmente. Manderò la mia chiave al server e questo la decripterà grazie alla presenza della sua chiave privata!
Forse sembra il gioco delle matrioske, ma l'argomento è astuto: la chiave privata del server è super-sicura ed è essenziale per decriptare il certificato spedito dal client, a sua volta generato basandosi sulle informazioni contenute nella chiave pubblica del server. Questo significa che ogni client può generare un proprio certificato, ma solo il server può dire da quale client questo proviene!... Spero di non aver contribuito ad aumentare la confusione che di solito abbonda nella questione delle chiavi di crittografia ;-)
Un'ultima cosa: i certificati possono essere generati "privatamente" solo se non si usa il server per scopi di commercio elettronico ufficiale: in tal caso occorre rivolgersi ad enti appositi.

5. ED ORA PREPARIAMO IL TUNNEL...

Bene, a questo punto siamo padroni del TCP/IP e dei protocolli crottografati (?), quindi non ci resta che operare!
Anzitutto bisogna andare in giro per la rete a raccattare i vari pezzi che ci servono nel formato adatto alla distribuzione che usiamo. Siccome non è mia intenzione stare a descrivere come installare tutto il necessario su ogni versione di Linux, mi limiterò a quelle che uso io (Linux Mandrake 6.1 e 7.0, nonché RedHat 6.x) in quanto le differenze si riscontrerebbero solo nella "preparazione" del sistema: prendere i sorgenti, ./configure, make, make install... insomma lo trovate scritto in tutti "readme" di tutti i  pacchetti.
Dunque, lasciando che qualcuno storca il naso, io non ho compilato nulla perché mi sono scaricato i meravigliosi RPM che mi servivano e tutto ha funzionato senza lacrime.
Gli ingredienti per continuare sono:

        openssl                   (io uso la versione 0.9.4)
        openssl-devel          (io uso la versione 0.9.4)
        imap                       (io uso la versione 4.7 della W.U.)
        stunnel                    (io uso la versione 3.3)

I pacchetti, in formato RPM, possono essere scaricati da qualsiasi mirror della Mandrake, su rpmfind.net o su SuperAlberT.it ftp://ftp.SuperAlberT.it/pub/Apps/, e poi installati col solito "rpm -U nome_pacchetto". Ora veniamo al dunque, in pochi e semplici passi... Dopo il login (come root, ovviamente!) portiamoci nella directory /etc e modifichiamo i file di configurazione services ed inetd.conf come segue:

Nel file services aggiungiamo le righe

            # SSL tunneling over IMAP
            simap 993/tcp

Nel file inetd.conf aggiungiamo le righe

            # SSL tunneling over IMAP
            simap stream tcp nowait root /usr/sbin/stunnel stunnel -p /usr/local/ssl/certs/imapd.pem -l /usr/sbin/imapd imapd

Commentiamo quello che abbiamo fatto.
Nel file services noi stabiliamo una corrispondenza (univoca!) tra il numero di ciascuna porta ed il demone che dovrà sorvegliarla. Il mio consiglio, pertanto, è di verificare preventivamente che non ci siano altre righe in cui si assegna qualcosa alla porta 993! In particolare, si noti che i numeri di porta nel file services non sono (in generale) ordinati in ordine crescente, sicché conviene usare la funzione "find 993" comunemente posseduta da tutti gli editor, oppure il più linuxiano "grep 993 /etc/services".
Il secondo file, inetd.conf, è un pochino più complicato ed ogni sua riga presenta varie opzioni; in generale la sintassi di ogni riga è:

    service    socket-type    protocol    flag    user    server-path    server-args

dove "service" è il nome del servizio, "socket-type" è il tipo di socket (può essere stream o dgram per il TCP o l'UDP rispettivamente), "protocol" è il tipo di protocollo, "flag" indica se il server dovrà liberare la porta per consentire una nuova connessione (nowait) oppure se il servizio non sarà disponibile finché il server non avrà terminato la prima connessione (wait). Il campo "user" indica qual'è l'utente proprietario del server che sarà attivato. Infine "server-path" e "server-args" specificano la locazione del server e quale argomenti gli si vogliono passare nel momento in cui viene lanciato.
La riga non commentata aggiunta al file inetd.conf dunque definisce che il server "imaps", definito sulla famiglia TCP, viene avviato con i permessi dell'utente root e deve essere presente un nuovo demone ad aspettare connessioni sulla porta non appena il primo demone inizia il suo lavoro (cioé non accade che, se un utente arriva per secondo a leggere la sua posta, allora deve aspettare che il primo finisca i suoi comodi!). Infine la lunga espressione "/usr/sbin/stunnel stunnel -p /usr/local/ssl/certs/imapd.pem -l /usr/sbin/imapd imapd" sta a dire che il "vero" server è stunnel e si prende carico di /usr/sbin/imapd lanciato semplicemente, senza alcuna opzione aggiuntiva. La dicitura "-p /usr/local/ssl/certs/imad.pem" indica ad stunnel dove si trova il pemfile-certificate, nel nostro caso imapd.pem che ci accingiamo a generare.
Eh già, a questo punto non ci resta che creare il certificato da esibile al client non appena questo si collega! Per farlo spostiamoci nella directory /usr/local/ssl/certs/ e diamo il comando

    openssl req -new -x509 -nodes -out imapd.pem -keyout imapd.pem -days 999


Durante la generazione del certificato saranno poste alcune domande. Attenzione in particolare a quella circa il "Common Name"

Il sistema ci presenterà delle domande, peraltro non particolarmente imbarazzanti, alle quali possiamo rispondere un po' come vogliamo purché, è fondamentale, nel campo relativo al "common name" si inserisca il nome esatto del server (del tipo www.nome.server.it) e non una cosa qualsiasi: poi nessuno pianga se non funziona niente!

6. VERIFICA DEL SERVER

Nulla di più facile: aprite una sessione di Netscape, andate su "Preferenze", "Mail server" e definite il server che avete appena creato di tipo "IMAP"; nella sottosezione relativa alle proprietà della connessione bisogna selezionare "Use Secure Connection"; salvate e... coraggio: ritirate la posta.


È fondamentale ricordarsi di "costringere" il client ad utilizzare una connessione sicura!

Se tutto va come deve (?) verrete avvertiti della richiesta di connessione crittografata e vi verrà chiesto esplicitamente se volete continuare. Se dite di sì il famoso lucchetto in basso a sinistra sulla barra di Netscape passerà da aperto a chiuso: se lo cliccate potrete visualizzare tutti i dettagli del server sicuro che avete appena creato.


Se il nostro lavoro è stato eseguito correttamente, alla prima connessione il browser ce ne renderà merito  ;-)

Ora è ragionevole aspettarsi che nessuno, oltre il legittimo destinatario, potrà leggere la posta!