---------------------[ previous ]---[ index ]---[ next ]---------------------- ============================================================================== ------------[ BFi numero 7, anno 2 - 25/12/1999 - file 15 di 22 ]------------- ============================================================================== -[ CRYPT0GRAPHY ]------------------------------------------------------------- ---[ CRiTT0GRAFiA SPiCCi0LA: OPENSSL & STUNNEL - Kobaiashi Titolo: Crittografia spicciola Sottotitolo: lo Zen e l'arte della crittografia. Aloha... sono Kobaiashi (no il mio nick NON viene ne' da I soliti sospetti ne' dai manga - leggere le KobaFAQ :). Questo e' il mio primo (e non ultimo, tempo permettendo) articolo per BFi... in realta' voleva essere una presentazione-comparazione approfondita dei firewall integrati nei vari sistemi operativi Open Source (ipchains, ipfw, ipfilter); per mere questioni temporali sono stato costretto a desistere.. ragion per cui vi presento un breve (beh, almeno rispetto alla Bibbia) how-to sull'utilizzo di openssl e stunnel nella creazione di collegamenti crittografati (cifrati, cioe' codificati in maniera che sia impossibile "capirne" il significato anche analizzandone il contenuto) e verifica dell'identita' tramite protocollo TCP. Non aspettatevi un articolo tecnico, ma un breve tutorial pratico sull'integrazione di questi strumenti nell'uso quotidiano. Premessa: inizialmente mi dilunghero' nell'introdurre, spiegare ed esemplificare concetti che il 90% di voi gia' conosce (o pensa di conoscere). Se proprio vi sentite T0 3l1T33 passate direttamente alla sezione "Strumenti necessari" (si' ci sono i comandi da utilizzare...), o al prossimo articolo... Per ogni acronimo o concetto di "difficile" comprensione ho cercato di aggiungere (tra parentesi) un esempio o una spiegazione nelle immediate vicinanze (tipo qui). Altri concetti vengono inizialmente solo nominati e saranno approfonditi proseguendo con la lettura. Altri ancora (imap, pop3, etc.) sono nominati senza spiegazione alcuna - se non vi sono familiari non e' un problema (siamo qui per imparare), ma vi ricordo che state leggendo BFi, non il manuale delle giovani marmotte. Se siete ancora qui, benvenuti e buona lettura (odio quelli T0 3l1T33) Ma veniamo al sodo... Consumo: un uovo (BWHAHAHAHAHAHAHAHAHA) Cui prodest? Una delle problematiche maggiori legate all'utilizzo di sistemi di autenticazione nel networking e' TUTTORA la trasmissione di password e altre informazioni sensibili in chiaro (ovvero non cifrate). Sebbene la crittografia sia gia' molto usata nell'e-commerce ed i browser piu' diffusi (Netscrape o Internet Exploder + Outluck, p. es.) abbiano il supporto SSL/TLS integrato per la navigazione e l'accesso a imap e/o smtp in maniera sicura (cifrata), un numero considerevole di informazioni vengono ancora scambiate in chiaro, password comprese, tra client e server e tra server e server (un esempio su tutti, la posta elettronica - inutile utilizzare ssh sulla vostra preziosa shell quando poi accedete in chiaro al pop3 con lo stesso username/password). Tramite gli strumenti qui descritti (o altri simili) e' possibile creare con pochissimo sforzo ed in maniera "trasparente" alle applicazioni (cioe' continuando ad utilizzare i vostri client preferiti e senza nessun aggiornamento) connessioni crittografate (e standard) per la maggior parte dei servizi che utilizzano TCP, ed, opzionalmente, verificare l'identita' del server e/o del client tramite certificati X.509. E' interessante notare che e' possibile anche per un singolo utente senza privilegi di root installare (smenando un po' nel configure e nei Makefile) ed utilizzare sia openssl sia stunnel (per gli ircari piu' 3l1t33.. si', potete tunnelarvi il vostro bnc). Cosa tunnelare? E' possibile tunnelare (trasportare un protocollo all'interno di un altro) qualsiasi connessione TCP, ad esclusione dell'ftp e di altri protocolli "multiporta" o con implementazioni particolari. Personalmente ho provato smtp, pop3, bnc (e telnet - vedi le note in seguito), su sistemi operativi OpenBSD, FreeBSD, Linux e (brevemente) Win98. Quanto e' sicuro? Senza entrare in dettagli tecnici sulla solidita' degli algoritmi di crittografia, sulla generazione pseudocasuale di numeri e sulle problematiche dell'utilizzo di PKI (Public Key Infrastructure) per l'autenticazione [cioe': se l'NSA vi sta dietro non pensiate di risolvere i vostri problemi cosi'], personalmente NON mi sento di raccomandare questo tipo di implementazione in sistemi in cui sia necessario un grado di sicurezza elevato (server commerciali, p. es.), almeno non prima di aver effettuato un adeguato auditing sui sorgenti di openssl e stunnel. Certamente pero' puo' mettere al riparo le vostre trasmissioni dai curiosi occasionali e proteggere i vostri server dagli "script kiddies". Per gli amanti dei numeri: stunnel (openssl) puo' utilizzare chiavi RSA o DH di qualsiasi dimensione (default: 512 bit per lo scambio delle chiavi, 1024 bit per i certificati) e algoritmi di crittografia a 128 bit e oltre (default: triple-des a 168 bit). Come funziona? Stunnel incorpora sia la modalita' "client" che la modalita' server e puo' essere utilizzato sia da inetd che in daemon-mode; sia come redirect verso un servizio gia' attivo su un'altra porta che lanciando direttamente il programma da tunnelare (Nota: d'ora in poi mi riferiro' per comodita' a stunnel in modalita' server come "stunnel_server" e in modalita' client come "stunnel_client", anche se il programma da utilizzare e' lo stesso, variano solamente i parametri). L'utilizzo piu' semplice (e quello che io preferisco) e' come redirect verso una porta dove sia gia' attivo un daemon o un servizio inetd standard - questo ci permette di utilizzare piu' facilmente stunnel_server con privilegi NON root e "separare" i compiti che le varie componenti del sistema devono svolgere, garantendo maggiore sicurezza. Esempio pratico. I dati sono plausibili, ma NON obbligatori. L'esempio presuppone che abbiate almeno un accesso root o user sulla macchina che contiene la vostra casella di posta POP3; oppure che vi siate "intortati" il sysadm convincendolo ad installare stunnel o un qualsiasi altro sistema compatibile con SSL o TLS. Supponiamo di voler accedere alla nostra casella di posta in maniera che sia impossibile per chiunque leggere il contenuto dei nostri messaggi o "rubare" la nostra password. (E' da notare che e' comunque possibile intercettare il contenuto dei messaggi "a monte", mentre vengono inviati dal server di posta del mittente a quello di destinazione, poiche' nella quasi totalita' dei casi il protocollo smtp viene utilizzato in chiaro). Attiveremo stunnel_server sulla porta 995 della macchina su cui risiede il POP3 che vogliamo interrogare (mail.s0ftpj.org) e lo configureremo in modo che tutte le connessioni SSL in arrivo sulla porta 995 vengano decrittate e reindirizzate verso la porta 110 della stessa macchina (nota: e' possibile reindirizzare la connessione anche verso un servizio attivo su un'altra macchina, per esempio all'interno di una rete dietro un firewall o dove piu' vi aggrada; ovviamente le connessioni da stunnel_server alla porta reindirizzata saranno IN CHIARO, quindi questo utilizzo e' SCONSIGLIATO). Sulla macchina da cui vogliamo poter scaricare la posta attiveremo invece stunnel_client configurato per reindirizzare, crittografate, tutte le connessioni ricevute sulla porta 110 (localhost) verso la porta 995 del server di posta reale. Infine, nel client che siamo soliti utilizzare per la posta, modificheremo l'indirizzo del server POP3, specificando localhost al posto di mail.s0ftpj.org. Abbiamo gia' raggiunto il nostro obbiettivo iniziale, proteggere il contenuto dei i dati in transito: tutte le connessioni tra stunnel_client e stunnel_server (porta 110 localhost <-> porta 995 mail.s0ftpj.org) avverranno in maniera cifrata, i dati in chiaro verranno trasmessi solamente attraverso l'interfaccia loopback (lo - un'interfaccia di rete virtuale - ip: 127.0.0.1; funziona piu' o meno come una qualsiasi interfaccia "reale", ma i dati non vengono "fisicamente" inviati all'esterno dello stack tcp/ip del sistema operativo e non e' possibile raggiungerla tramite gli indirizzi reali, salvo in caso di "apposite istruzioni" o redirect. Il succo del discorso e': per il vostro vicino di scrivania attaccato al vostro stesso cavo ethernet e' comunque impossibile analizzare quello che passa sulla vostra interfaccia loopback. Ovviamente, con un accesso locale e privilegi di root o simili e' possibile sniffare il traffico sull'interfaccia loopback. - si': lo c'e' anche sotto Windozz - provate ping 127.0.0.1 - anche se non viene riportata nel Pannello di Controllo... :) Con un altro piccolo sforzo e' pero' possibile aggiungere "quel tocco di sicurezza in piu' che non guasta mai" e metterci al riparo dal famoso "man in the middle" attack (un attaccante puo' fingere - tramite dns spoofing, p. es. - di essere il server a cui vogliamo collegarci - comportandosi in maniera analoga, p. es. con un tunnel ssl sulla porta 995 ed un server POP3 "fake" per "rubare" le password che il nostro client comunichera'), chiedendo a stunnel_client di verificare il certificato (l'identita') del server a cui ci stiamo collegando. E' anche possibile impostare stunnel_server in modo che verifichi il certificato dei client e permettere l'accesso solamente agli utenti autorizzati. Come funziona tecnicamente? SSL (Secure Socket Layer protocol) e' un protocollo sviluppato dalla Netscape per garantire maggiore sicurezza nelle trasmissioni su rete tcp/ip (Internet, p. es. :). Permette di utilizzare qualsiasi protocollo e fornisce funzioni di crittografazione e verifica dell'integrita' dei dati trasmessi e autenticazione dei server e dei client. La verifica dell'identita' e' ottenuta tramite "certificati" (particolari meccanismi possibili grazie ai digest - metodi per estrarre da un dato documento di lunghezza qualsiasi una "stringa" univoca di lunghezza definita; ed alla crittografia a chiave pubblica - crittografia che utilizza due distinte chiavi per proteggere i dati, una privata da mantenere segreta ed una pubblica da distribuire liberamente. Utilizzando la chiave pubblica di Tizio e' possibile cifrare un messaggio/file/etc. in modo che solamente Tizio riuscira' a decifrarlo utilizzando la sua chiave privata - e' anche possibile per Tizio "firmare" un blocco di dati con la sua chiave privata. Chiunque in possesso della chiave pubblica di Tizio potra' verificare l'effettiva appartenenza della firma e l'integrita' dei dati); le informazioni tra client e server vengono scambiate utilizzando la crittografia "tradizionale" (crittografia simmetrica - i dati vengono cifrati e decifrati con un'unica chiave che deve essere conosciuta sia dal mittente che dal ricevente) con una chiave generata casualmente e scambiata in maniera "sicura" tramite tecniche di crittografia a chiave pubblica (questo perche', anche con le attuali tecnologie, utilizzare la crittografia a chiave pubblica per grandi quantita' di dati comporta un enorme utilizzo di risorse di calcolo, mentre la crittografia simmetrica, una volta risolto il problema dello scambio delle chiavi tra le parti coinvolte, garantisce un grado di sicurezza analogo e velocita' notevolmente maggiore); l'integrita' dei dati e' garantita utilizzando nuovamente i digest e le funzioni di "firma" della crittografia a chiave pubblica. Attualmente l'ultima versione del protocollo SSL pubblicata dalla Netscape e' SSLv3 (http://www.netscape.com/eng/ssl3/); un apposito "working group" dell'IETF (Internet Engineering Task Force - http://www.itef.org -, un gruppo eterogeno di persone che volontariamente si occupa di studiare, proporre e promuovere gli standard che "regolano" ogni aspetto delle comunicazioni su Internet - pubblicandoli prima come "internet-drafts" e successivamente come RFC, una volta "definitivi" - ma non e' semplicissimo il concetto :) ha recentemente pubblicato le specifiche per il protocollo TLS (Transport Layer Security protocol) v. 1.0 (RFC 2246 - http://www.ietf.org/rfc/rfc2246.txt), basato su SSLv3. Anche se i due protocolli non sono compatibili, sono tuttavia molto simili, e generalmente i software che implementano TLS possono comunicare anche con software che implementano solamente SSLv3 o SSLv2 (http://www.netscape.com/eng/security/SSL_2.html - che e' ancora utilizzato ma in fase di abbandono per alcuni noti problemi di sicurezza). OpenSSL (http://www.openssl.org) e' una libreria Open Source (basata su SSLeay - http://www.ssleay.org - non piu' sviluppata) che fornisce funzioni per implementare SSL v2/v3 e TLS v1; funzioni di crittografia generale (simmetrica: des, 3des, rc2, rc4, IDEA, Blowhfish; asimmetrica: RSA, DSA, Diffie-Hellman; digest: MD2, MD4, SHA, SHA-1, MDC2, RMD160), gestione certificati X.509v3 (creazione, certificazione, verifica, etc.) e funzionalita' mimime per implementare CA (Certification Authority). Stunnel utilizza le funzionalita' fornite da questa libreria per creare "tunnel" tcp in modalita' client/server, con verifica opzionale dei certificati. E' da notare che e' possibile utilizzare stunnel come client per servizi SSLv2/v3 e TLS v1 anche non basati su stunnel o non basati su openssl e viceversa. A grandi linee, il tutto funziona cosi': il client ssl invia una richiesta di connessione (se si utilizza, p. es., stunnel_client per il POP3 con Netscape, la richiesta di connessione verra' inviata "trasparentemente" quando si utilizzera' la funzione "Check Mail") verso il server remoto (per esempio la porta 995 di mail.s0ftpj.org) "negoziando" le opzioni necessarie a stabilire una comunicazione sicura tramite l'handshake SSL. Viene verificato che sia possibile comunicare utilizzando TLS o SSL in una delle versioni supportate (stunnel_client utilizza SSLv3 - stunnel_server supporta client SSLv2, SSLv3 e TLSv1); viene scelta la CipherSuite (vedi dopo) da utilizzare (il client comunica in ordine di preferenza quelle supportate ed il server "sceglie" la prima "ammissibile"); vengono scambiati altri dati di varia utilita', tra cui un "identificativo di sessione" (Session ID, generalmente viene comunicato dal server ed utilizzato per tutta la durata del collegamento, ma puo' essere comunicato anche dal client per "ripristinare" collegamenti interrotti o creare nuovi collegamenti tra lo stesso client e lo stesso server senza effettuare nuovamente lo scambio delle chiavi e la negoziazione dei parametri di sicurezza, qualora non sia intercorso piu' di un certo timeout dall'ultimo collegamento; il default in stunnel e' 300 secondi, ma e' possibile utilizzare questa "session-cache" solamente se utilizzato come daemon, non da inetd) ed alcuni dati "random" (generati casualmente) utilizzati successivamente. Il server trasmette il proprio certificato (se ne ha uno e/o se e' stata richiesta l'autenticazione da parte del client - stunnel_server invia SEMPRE quella presente in stunnel.pem, anche qualora il client non lo richieda espressamente) ed (opzionalmente) una seconda chiave pubblica generata casualmente, se la prima (contenuta all'interno del certificato) non fosse utilizzabile per cifrare dati (p. es. una chiave DSS) o se deciso in fase di implementazione del software (stunnel_server utilizza SEMPRE anche una seconda chiave; lanciato come daemon generata una chiave RSA temporanea che viene utilizzata per tutti i collegamenti fino a quando il daemon non viene "terminato"; lanciato da inetd genera ad ogni sessione una chiave temporanea ex-novo. Viene anche inizializzato DH se presente l'apposito parametro - un numero primo di una certa lunghezza, generalmente 512 cifre - nel file stunnel.pem - in base alla CipherSuite scelta dal client, verra' fornita la chiave RSA o un parametro da usarsi con DH). Il client verifica il certificato del server, qualora l'utente (o il software che utilizza) abbia richiesto l'autenticazione del server, ed invia (qualora il server lo specifichi) il proprio certificato per essere a sua volta autenticato. Il client genera casualmente una "premaster-key" e la invia cifrata tramite la chiave pubblica del server. Il client ed il server applicano lo stesso meccanismo matematico per ottenere dalla "premaster-key" (e da altri dati, tra cui i dati random scambiati precedentemente) una chiave da utilizzare tramite l'algoritmo "simmetrico" precedentemente scelto (negoziazione CipherSuite) e verificano di poter effettivamente comunicare tra loro utilizzando questo algoritmo e questa chiave. La comunicazione viene finalmente "trasferita" ai client reali, che possono a loro volta negoziare il protocollo, l'autenticazione, etc. come se le comunicazione fosse "diretta". E' da notare che la prima parte dell'handshake SSL avviene IN CHIARO (fino a quando il server non comunica la propria chiave pubblica); sia il client che il server non trasmettono nessun dato ai corrispettivi client/server "nascosti" fino a quando non abbiano stabilito congiuntamente che la comunicazione e' sicura (un qualsiasi errore di protocollo, di verifica, di autenticazione, etc. nell'handshake provoca l'interruzione del collegamento - anche successivamente vengono trasmessi solamente i dati che siano cifrati con la corretta chiave e siano verificati tramite digest e "firma"). CipherSuite? La CipherSuite e' un codice standard che definisce la combinazione dell'algoritmo di scambio delle chiavi, dell'algoritmo di crittografazione dei dati e dell'algoritmo per la generazione dei digest. Come CipherSuite di default openssl specifica EDH-RSA-DES-CBC3-SHA. Il primo parametro e' il meccanismo di scambio delle chiavi (EDH - protocollo sviluppato da Diffie e Hellman nel 1976 per la negoziazione di chiavi private utilizzando canali in chiaro, nella versione "Ephemeral" permette di aggiungere controlli sull'autenticazione delle due parti). Il secondo parametro e' il tipo di certificato utilizzato (RSA - algoritmo di crittografia a chiave pubblica che permette sia la cifrazione/decifrazione che la "firma" di certificati o altri dati, sviluppato da Rivest, Shamir e Adleman nel '77). Il terzo parametro e' il tipo di crittografia simmetrica utilizzata nei successivi scambi di dati, una volta che i due lati siano reciprocamente autenticati (se necessario) ed abbiamo "deciso" una chiave "segreta" da utilizzare durante la sessione (DES-CBC3 - Data Encryption Standard anche noto come Data Encryption Algorithm, sviluppato dall'IBM con il "controllo" e su mandato di NSA e NIST - due organismi governativi USA; in una delle sue "ultime" rivistazioni, cioe' "triple-des", ovvero utilizzando 3 distinte chiavi di 56 bit per cifrare ogni blocco di dati ripetutamente; CBC - Cipher Block Chaining - e' una delle possibili modalita' di processare un "block cipher", ovvero un algoritmo di crittografazione a chiave simmetrica che produce per ogni dato blocco di dati non crittografati - generalmente 64 o 128 bit - un blocco di dati cifrato di lunghezza eguale). L'ultimo parametro e' il tipo di "digest" utilizzato per verificare l'integrita' dei dati trasmessi (SHA- Secure Hash Algorithm, sviluppato dal NIST e riveduto nel '94 come SHA-1 per problemi di sicurezza - openssl supporta entrambi, ma utilizza solamente il secondo nella scelta delle CipherSuite). E' da notare che la terminologia utilizzata da openssl per le CipherSuite e' leggermete diversa da quella usata nei documenti dell'IETF, ma facilmente deducibile (in particolar modo, il meccanismo di scambio delle chiavi - il primo parametro viene specificato solamente se EDH, altrimenti si assume implicitamente che sia RSA; se non e' specificato nemmeno il secondo parametro, la connessione viene effettuata "anonimamente" - cioe' non e' possibile verificare l'identita' delle parti coinvolte). Per esempio nella documentazione ufficiale di TLSv1, la CipherSuite di default di openssl (EDH-RSA-DES-CBC3-SHA) e' indicata come: TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA. Quello che segue e' l'elenco delle CipherSuite supportate da openssl: ---> shell kppc:~/work/crittografia_spicciola$ openssl ciphers EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:IDEA-CBC-SHA:RC4-SHA :RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:DES-CBC3-MD5:I DEA-CBC-MD5:RC2-CBC-MD5:RC4-MD5:RC4-64-MD5:DES-CBC-MD5:EXP-EDH-RSA-DES-CBC- SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5:EXP -RC2-CBC-MD5:EXP-RC4-MD5 ---< Ogni codice e' separato dal successivo tramite ":". DSS sono i certificati generati tramite l'algoritmo DSA (questo algoritmo prevede solamente funzioni di firma digitale e non di cifratura dei dati). Se non e' specificato ne' DSS ne RSA - cioe' manca il secondo parametro - la negoziazione e' "anonima" e non si puo' verificare l'identita' delle due parti, solamente comunicare in maniera cifrata). IDEA, RC2 e RC4 sono altri algoritmi di crittografia a chiave simmetrica, utilizzabili al posto di des (DES) o triple des (DES-xxx3) - Tranne RC4, che e' uno stream cipher (brevemente: i dati da crittografare non sono processati a blocchi di bit di lunghezza fissa, ma nella loro interezza - principalmente per garantire maggiore velocita'), gli altri sono tutti block cipher ed utilizzano la modalita' CBC. MD5 e' un algoritmo digest utilizzabile al posto di SHA (e generalmente considerato "meno sicuro"). EXP significa che si intendono utilizzare chiavi di lunghezza "conforme" alle limitazioni imposte dalle leggi USA (e altri stati) per l'export di software contenenti funzioni di crittografia (tipicamente max. 512 bit per gli algoritmi a chiave privata e max. 40 bit per gli algoritmi a chiave simmetrica). E' da notare che se utilizzate stunnel come client per connettervi ad un server basato su software prodotto negli USA (tutti i software di Microsoft, Netscape e Sun, p. es.) e questo server non e' situato negli USA, probabilmente utilizza una versione che che supporta solamente CipherSuite "esportabili". Recentemente le leggi americane sono state modificate, aumentando il numero di bit utilizzabili per la crittografia "esportabile" (56 bit per la cifrazione con crittografia simmetrica, 1024 bit per lo scambio delle chiavi con crittografia a chiave pubblica, inoltre il software puo' contenere supporto anche per chiavi a numero di bit maggiore, se usato SOLAMENTE per le funzionalita' di "firma"). Ovviamente bisognera' procedere all'aggiornamento del software utilizzato sul server (se disponibile :). Esiste una progetto (http://www.fortify.net) che produce e distribuisce patch (modifiche all'eseguibile orginale) da applicare a Netscape Navigator/Communicator (praticamente tutte le versioni per tutti i sistemi operativi) che permettono di abilitare nelle funzioni di crittografia gia' presenti nel software l'utilizzo di chiavi con lunghezza considerata sicura (quindi non "EXP") anche nelle versioni distribuite all'esterno degli USA. PKI? Certificati? CA? ... Il meccanismo della certificazione permette a due soggetti senza nessuna precedente "conoscenza" diretta di verificare l'identita' reciproca, confidando nella "garanzia" fornita da una o piu' autorita' prestabilite, comunemente dette Certification Authority. Si tratta di meccanismi possibili grazie alla crittografia a chiave pubblica ed ai digest, legati da regole piuttosto nuove, mutevoli e decisamente complesse. In breve funziona all'incirca cosi': le CA "firmano" tramite le loro chiavi private le chiavi pubbliche dei soggetti da "certificare", dopo aver adeguatamente (?) appurato la loro identita'. Qualora Tizio voglia verificare l'identita' di Caio - o viceversa - chiedera' a questi di inviare il proprio certificato (composto dalla chiave pubblica e altri dati quali nome, durata, etc., "firmati" dalla CA con la propria chiave privata). Tramite la chiave pubblica della CA sara' quindi possibile per Tizio verificare l'effettiva validita' del certificato e di tutti i dati contenuti nel certificato e quindi "identificare" con certezza Caio. Fin qui e' tutto piuttosto semplice... Quando oltre a dover appurare l'identita' di Caio, Tizio dovra' decidere se autorizzarlo ad accedere ai propri dati o server, e con quali diritti; oppure verificare che il certificato dello stesso non sia stato revocato dalla CA; etc., il tutto diventa piuttosto intricato. Tutta questa brodaglia viene comunemente appellata come PKI (Public Key Infrastructure). Amen. Per quel che riguarda questo how-to, la verifica dell'identita' corrisponde _quasi_ automaticamente all'autorizzazione, quindi e' opportuno istituire un'apposita CA (o una "chiave" di questa CA) con cui autenticare SOLAMENTE i client che realmente possono accedere ai servizi che si intendono proteggere ed i server che necessitano di essere "verificati" e utilizzare l'opzione di stunnel che non solo verifica la certificazione del client, ma richiede che una copia della chiave pubblica dello stesso sia contenuta in una directory sul server. Spesso le situazioni reali sono piu' complicate, ed istituire una chiave od una CA diversa per ogni servizio, oppure mantenere una copia delle chiavi dei client su ogni server risulta non praticabile. In questi casi e' opportuno utilizzare un apposito software per la gestione della CA e delle regole di accesso (anche se non molti e non molto sofisticati, esistono anche dei software Open Source per la gestione delle CA). Cos'e' una CRL (Certificate Revocation List) ? Una CRL e' un elenco emesso periodicamente da una CA per specificare l'elenco dei certificati "firmati" che sono da ritenersi NON piu' validi. I motivi che possono portare alla revoca di un certificato vanno dalla compromissione della chiave privata (e' stata "rubata", oppure l'utente non ricorda piu' la password per accedervi, etc.) e conseguente generazione di un nuovo certificato, alla cessazione del rapporto tra un utente e la CA - per esempio quando mi butteranno fuori da s0ftpj, etc. :). E' da notare che questa revoca non ha nulla a che fare con la normale "scadenza" di un certificato (ognuno di essi ha una data di inizio e fine validita' - solitamente di 365 giorni). Le CRL sono ancora uno dei punti critici nella sicurezza delle infrastrtutture di PKI, in particolar modo quel che riguarda la distribuzione e l'aggiornamento tempestivo di queste liste (si possono infatti creare dei "buchi neri".. potrebbe per esempio essere possibile utilizzare un certificato revocato per accedere a servizi protetti qualora il software o il gestore del server non abbiano ancora aggiornato la CRL corrente). Stunnel NON utilizza le CRL nell'autenticazione degli utenti. Consiglio di leggere le specifice techniche dei protocolli SSL e TLS e una mezza tonnellata di FAQ's, how-to, RFC sulla crittografia, sulle PKI, etc. per maggioni informazioni... (ci sono un tot di link in fondo al documento). Strumenti necessari: * un server unix o windows (bleah) qualsiasi. * un client unix o windows. * openssl >= 0.9.2b (http://www.openssl.org) * [oppure] ssleay >= 0.9.0b (http://www.ssleay.org) * stunnel >= 3.4a (http://mike.daewoo.com.pl/computer/stunnel) se intendete utilzzare windows potete prelevare direttamente l'eseguibile win e le dll necessarie, senza bisogno di ssleay o openssl). * opzionalmente MZtelnet o altri client abilitati SSL (http://www.openssl.org/related/apps.html contiene un elenco di applicazioni che possono utilizzare ssl, tra cui tunnel generici, telnet, ftp, rsh, patch TLS per qmail, sendmail e postfix, etc.) * sprezzo del pericolo e audacia da leoni. Prima di cominciare: Se installate openssl e stunnel come pacchetti "precotti" di una delle varie distribuzioni Linux (Debian, p. es.) o dal "ports-tree" di FreeBSD, le directory di riferimento NON sono piu' quelle riportate (p. es: i binari sotto debian stanno in /usr/bin - o /usr/local/bin, non ricordo esattamente, comunque potete usare which openssl per scoprirlo -, mentre configurazione e certificati in /etc/ssl e /etc/ssl/certs; FreeBSD invece rinomina /usr/local/ssl in /usr/local/openssl, ma la struttura rimane equivalente.. ln -s /usr/local/openssl /usr/local/ssl e siete a cavallo ["hey, mi passa il microfono.. hello, qui e' l'auto... che auto siamo? - cinque cinque - hello, qui e' l'auto cinquantacinque, siamo.. siamo a cavallo hihihihihi" (**) :). Dovreste trovare nei rispettivi siti anche i binari di openssl per varie piattaforme e l'rpm di stunnel. Se invece volete avventurarvi nel magico mondo del "self-made", compilate ed installate (per i frettolosi: cd dirsource ; echo "Le cose tra parentesi sono commenti, non da mettere nei comandi" (capito?) ; ./config (openssl) oppure ./configure (stunnel); make ; make test (solo openssl) - quindi, con id root - make install ; ma si sa, la fretta e' cattiva consigliera, LEGGETE I DOCS, in particolare gli immancabili INSTALL e README) sia openssl (prima) che stunnel (dopo) seguendo le apposite istruzioni accluse ed installateli nelle directory di default (/usr/local/ssl per openssl e /usr/local/sbin per stunnel, in teoria ci pensa gia' "make install") o dove volete, tenendo presente che gli esempi si riferiranno a queste directory. Ripetete queste operazioni sia sul server che sul client. Shakerate e servite freddo. Per compilare correttamente stunnel con openssl 0.9.4 e' NECESSARIO aggiungere un NULL alla chiamata PEM_read_bio_DHparams( bio, NULL, NULL ) alla riga 205 di ssl.c, che diventa quindi PEM_read_bio_DHparams( bio, NULL, NULL, NULL ) Openssl di default e' installato in una directory (/usr/local/ssl/bin) non raggiungibile nella path. E' consigliabile aggiungere questa directory oppure creare un link in /usr/local/bin o altra directory simile per evitare di inserire tutto il percorso ogni volta (ln -s /usr/local/ssl/bin/openssl /usr/local/bin). Lanciando openssl direttamente, senza nessuna opzione, si entra in una modalita' simil-interattiva a linea di comando, che sconsiglio a tutti :). I comandi openssl sono composti in questa maniera: openssl comando -opz_3 -opz_2 ... -opz_n Sebbene non sia presente un'opzione di help, passando un argomento non valido viene visualizzata una breve descrizione dei comandi e delle opzioni utilizzabili.. ---> shell kppc:~/work/crittografia_spicciola$ openssl help openssl:Error: 'help' is an invalid command. Standard commands asn1parse ca ciphers crl crl2pkcs7 dgst dh dsa dsaparam enc errstr gendh gendsa genrsa nseq pkcs12 pkcs7 pkcs8 req rsa s_client s_server s_time sess_id speed verify version x509 Message Digest commands (see the `dgst' command for more details) md2 md5 mdc2 rmd160 sha sha1 Cipher commands (see the `enc' command for more details) base64 bf bf-cbc bf-cfb bf-ecb bf-ofb cast cast-cbc cast5-cbc cast5-cfb cast5-ecb cast5-ofb des des-cbc des-cfb des-ecb des-ede des-ede-cbc des-ede-cfb des-ede-ofb des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb des-ofb des3 desx idea idea-cbc idea-cfb idea-ecb idea-ofb rc2 rc2-cbc rc2-cfb rc2-ecb rc2-ofb rc4 rc5 rc5-cbc rc5-cfb rc5-ecb rc5-ofb kppc:~/work/crittografia_spicciola$ openssl req help unknown option help req [options] <infile >outfile where options are -inform arg input format - one of DER TXT PEM -outform arg output format - one of DER TXT PEM -in arg input file -out arg output file -text text form of request -noout do not output REQ -verify verify signature on REQ -modulus RSA modulus -nodes don't encrypt the output key -key file use the private key contained in file -keyform arg key file format -keyout arg file to send the key to -newkey rsa:bits generate a new RSA key of 'bits' in size -newkey dsa:file generate a new DSA key, parameters taken from CA in 'file' -[digest] Digest to sign with (md5, sha1, md2, mdc2) -config file request template file. -new new request. -x509 output a x509 structure instead of a cert. req. -days number of days a x509 generated by -x509 is valid for. -asn1-kludge Output the 'request' in a format that is wrong but some CA's have been reported as requiring [ It is now always turned on but can be turned off with -no-asn1-kludge ] ---< [etc. etc, per ognuno degli "Standard commands" e' presente un'apposita schermata di aiuti - consiglio di perdere un po' di tempo e visualizzarle tutte :] Se utilizzate SSLeay al posto di openssl, non cambia praticamente nulla (a parte qualche nome di directory) - semplicemente dovrete digitare il comando direttamente invece che "mediarlo" tramite openssl (p.es.: openssl cipher -> ciphers ; openssl req -text -noout -in stunnel.pem -> req -text -noout -in stunnel.peml; etc.) Personalmente ho utilizzato con successo ssleay 0.9.0b, openssl 0.9.3a e 0.9.4, stunnel 3.4a, MZtelnet 0.11.2 e SSLtelnet 0.13 su Linux (intel/ppc), OpenBSD (intel), FreeBSD (intel). Per completezza ho effettuato anche qualche test di utilizzo di stunnel-3.4a.exe in modalita' client su Win98 senza riscontrare problemi. Dalla teoria alla pratica: Se avete seguito le istruzioni ed installato sia openssl che stunnel come da copione, dovreste avere una directory /usr/local/ssl ed un file /usr/local/sbin/stunnel. Dentro /usr/local/ssl/certs dovrebbe essere presente il certificato (stunnel.pem) che il Makefile di stunnel genera automaticamente quando quando si lancia il "make" oppure a richiesta con "make stunnel.pem". Utilizzando il comando "openssl x509 -text -noout -in stunnel.pem" e' possibile avere un output testuale del contenuto di questo certificato... Il certificato che stunnel utilizza di default (generalmente /usr/local/ssl/certs/stunnel.pem, ma e' possibile cambiarlo da linea di comando) contiene dati fittizi (i certificati X509 standard normalmente contengono i dati reali del server o dell'utente, visto che devono certificarne l'identita'!), una chiave privata RSA 1024 bit e parametri DH a 512 bit. Se non si intende utilizzare la verifica dell'identita', questo certificato sara' sufficente.. altrimenti e' consigliabile generarne uno "ad hoc" (vedi dopo). I comandi che riporto sono pensati avendo accesso root sia al server che al client.. se cosi' non fosse (in particolare per il server :) e' comunque possibile installare/utilizzare stunnel - i comandi rimangono piu' o meno simili, cambieranno le directory ed i permessi utente (se siete su una shell, ed avete un semplice accesso come utente, utilizzate i VOSTRI permessi per far girare stunnel e create una struttura di subdirectory nella vostra home). Se utilizzate Windowz, la sintassi di stunnel rimane invariata, ma dovrete cambiare i nomi delle directory e modificare i comandi unix che riporto con i corrispettivi comandi win (se esistono :). E' consigliabile utilizzare stunnel (soprattutto il server) con un id apposito, tipo ssl o stunnel o quel che e'.. quindi addate (adduser stunnel - ricordate di disabilitare il login!!) l'apposito utente e modificate /usr/local/ssl/certs/stunnel.pem in modo che sia scrivibile solo da root e leggibile anche (e solo) da stunnel (o gid che avete scelto). Per gli esempi utilizzero' un utente con uid e gid stunnel (se utilizzate altre applicazioni che necessitano di accedere ai certificati openssl - generalmente altro software linkato a queste librerie - potete, p. es., creare un gruppo ssl e quindi creare vari utenti - stunnel, mztelnet, etc. membri di questo gruppo, oppure utilizzare per tutte un generico gruppo ssl e amen). I permessi di /usr/local/ssl/certs/stunnel.pem e di eventuali altri file che contengano certificati da usare con stunnel e quelli dell'eventuale directory mystrusted (che contiene i certificati da utilizzare con l'opzione -v 3 - vedi dopo) dovranno essere: ---> shell kppc:/usr/local/ssl/certs# chown root:stunnel stunnel.pem kppc:/usr/local/ssl/certs# chmod 640 stunnel.pem kppc:/usr/local/ssl/certs# chown root:stunnel mytrusted kppc:/usr/local/ssl/certs# chmod 750 mytrusted kppc:/usr/local/ssl/certs# ls -l total 3 drwxr-x--- 2 root stunnel 1024 Nov 2 03:49 mytrusted -rw-r----- 1 root stunnel 1224 Nov 2 02:09 stunnel.pem ---< Se non avete intenzione di verificare i certificati dei client, il gioco e' presto fatto.. (il file stunnel.pem serve COMUNQUE, almeno sul server)! Server: Se intendete utilizzare stunnel come daemon con privilegi non root dovrete lanciarlo "a mano" o tramite su o meccanismi simili (purtroppo non prevede funzioni per il cambio di uid in automatico) e NON potrete utilizzarlo per le porte TCP "priviliged" (<=1024). Per Debian/Linux esiste authbind che _dovrebbe_ risolvere questo problema (ma potrebbe crearne altri :); _suppongo_ sia possibile utilizzarlo anche con distribuzioni Linux diverse. Scaricate il binario per la vostra architettura, o il sorgente se intendete avventurarvi in un porting: http://www.debian.org/Packages/unstable/utils/authbind.htm Personalmente sconsiglio l'utilizzo come daemon anche se non root, nonostante i vantaggi (la chiave temporanea e l'ambiente SSL vengono inizializzati una volta sola con un conseguente - notevole - guadagno in termini "velocistici" - soprattutto con keylegth maggiori di 512 bit): se un attaccante riuscisse infatti a far "terminare" il vostro stunnel (per esempio con un Denial Of Serivice, etc.) e fosse in possesso di un account non root su quella macchina, potrebbe "fingere" di essere il vostro server utilizzando la stessa porta - in questo caso e' FONDAMENTALE verificare dai client il certificato del server. La sintassi per creare un tunnel verso, p. es., la vostra porta 110 (POP3) accettando connessioni SSL sulla porta 1995 (o sulla porta che volete > 1024) e' quindi: stunnel -d 1995 -r 110 (se non fosse nella path, ricordo che stunnel sta in /usr/local/sbin). Utilizzandolo da inetd e' invece possibile utilizzare porte <= 1024 anche senza privilegi root. Aggiungete in /etc/inetd.conf la riga riportata in seguito e reinizializzate inetd (killall -HUP inetd oppure kill -HUP xxx dove xxx e' il pid - numero del processo - di inetd; ps aux|grep inetd per scoprirlo ): 995 stream tcp nowait stunnel /usr/local/sbin/stunnel stunnel -r 110 Ovviamente, poiche' stunnel (con questa sintassi) effettua un semplice redirect dei dati che riceve, dopo averli decrittati, il server POP3 reale deve essere attivo (daemon o inetd) e accettare connessioni sulla porta 110 di (almeno) localhost. Se intendete autorizzare l'accesso al POP3 SOLAMENTE tramite la porta ssl 1995 (o 995 - il numero non e' casuale, 995/tcp e' la porta standard per il pop3s e 1995 e' 995 + 1000) sara' vostra cura limitare l'accesso alla porta 110 ESCLUSIVAMENTE da localhost (127.0.0.1) tramite tcp_wrapper, opzioni specifiche del pop3d o firewall (o tutti e tre :). E' comunque possibile lanciare un programma qualsiasi di quelli utilizzabili da inetd direttamente (quindi senza che il servizio debba essere attivo da inetd o come daemon) con l'opzione -l: stunnel -d 995 -l /usr/libexec/in.pop3d -- in.pop3d -s (daemon-mode) oppure (inetd - su un'unica riga e senza "\"): 995 stream tcp nowait stunnel /usr/local/sbin/stunnel \ stunnel -r 110 -l /usr/libexec/in.pop3d -- in.pop3d -s (il -- e' necessario solo se si specificano parametri al programma, quindi, p. es. -l /usr/libexec/in.pop3d in.pop3d) o un programma che usa STDIN e STDOUT tramite l'opzione -L. Il programma lanciato avra' uid/gid del deamon stunnel, quindi per utilizzare in.pop3d, p. es., dovete fare girare stunnel con privilegi di root (normalmente il daemon POP3 necessita dei privilegi di root per accedere al file di password - anche se ci sono sistemi per utilizzarlo in ambiente chroot o con privilegi minori, quali qmail + vchkpw - ma non e' argomento che affronteremo qui). Come non mi stanchero' di ripetere, questo utilizzo e' sconsigliato. CHE NON VI VENGA POI IN MENTE DI METTERE STUNNEL SETUID ROOT, altrimenti qualche vostro utente sara' ben lieto di mettere come programma da eseguire con -l una shell :) Client: La sintassi per utilizzare la modalita' client e' pressoche' analoga a quella per la modalita' server, aggiungendo l'opzione -c. Per esempio sul computer da cui vogliamo collegarci al server POP3 protetto, lanceremo: stunnel -c -d 127.0.0.1:1110 -r mail.s0ftpj.org 995 oppure aggiungeremo nell'inetd la riga: 110 stream tcp nowait stunnel /usr/local/sbin/stunnel stunnel -c \ -r mail.s0ftpj.org:995 Nel nostro programma di posta sceglieremo come pop server localhost e porta 1110 (la porta di default e' 110, se il vostro programma non prevede esplicitamente l'opzione per cambiare questa porta, provate con la sintassi localhost:1110). L'utilizzo che consiglio per i client, non tanto per la velocita' (la chiave RSA temporanea non viene generata) quanto per la flessibilita' di utilizzo e la SICUREZZA e' invece la modalita' daemon. E' da notare che se utilizzato da inetd, stunnel accettera' connessioni anche dall'ip pubblico del computer (quello della scheda di rete oppure quello del ppp durante un collegamento via modem); questo permettera' a chiunque conosca il vostro ip (e a eventuali curiosi occasionali dotati di un qualsiasi portscan) di collegarsi al server remoto UTILIZZANDOVI come bouncer. Se avete anche scelto di attivare l'autenticazione, questi verranno autenticati con il vostro certificato personale! E' NECESSARIO, QUALORA SI UTILIZZI STUNNEL IN MODALITA' CLIENT DALL'INETD, LIMITARE L'ACCESSO ALLA PORTA CHE UTILIZZATE PER CONNETTERVI solamente a localhost (127.0.0.1) tramite hosts.deny e/o hosts.allow (stunnel fornisce autonomamente il supporto, se compilato con le necessarie libwrap) e/o tramite un firewall (possibilmente installato sulla stessa macchina, a meno che non abbiate una fiducia cieca delle altre persone che popolano la vostra - eventuale - rete locale). Utilizzato in modalita' demon e' invece possibile specificare direttamente nella linea di comando di accettare connessioni solamente da 127.0.0.1 (p. es.: -d 127.0.0.1:1110). Se sulla vostra macchina sono presenti degli altri utenti (voluti o non voluti :), sara' per loro possibile utilizzare il vostro stunnel per collegarsi al server remoto. In questo caso si puo' utilizzare il parametro -u e forzare il nome utente, per esempio: stunnel -c -d 127.0.0.1:1110 -r mail.s0ftpj.org:995 -u koba accettera' di iniziare connessioni solo se localhost risolve l'ident dell'utente che inizia la connessione come "koba". Ovviamente dovete avere un identd funzionante e correttamente configurato - quindi non un fake identd che ritorna "true" a tutto, tipo quelli che si utilizzano per collegarsi piu' rapidamente a irc - e possibilmente protetto da firewall o tcp_wappers, visto che l'identd puo' fornire informazioni interessanti ad un eventuale curioso :) . E' anche possibile utilizzare hosts.deny e/o hosts.allow per limitare gli utenti che possono accedere a certe risorse. Anche se (generalmente) i computer personali (soprattutto se non sono collegati permanentemente ad internet, oppure sono dietro un firewall - o ci sono dei pazzi in giro?) presentano meno problematiche di sicurezza rispetto ad un server con accesso pubblico, e' comunque consigliabile utilizzare stunnel (in modalita' daemon) con i vostri privilegi utente o (meglio ancora) con un utente apposito e non con privilegi di root, sempre che nel vostro programma di posta (o nel client che intendete utilizzare con ssl) sia possibile scegliere una porta a cui collegarsi > 1024 Generalmente e' questo e' possibile, anche se con alcuni client che non accettano esplicitamente l'opzione, tipo Netscape, e' necessario specificare la sintassi server:porta (p. es. localhost:1110). Molto utile per incominciare a testare stunnel ed avere un "feedback" di quello che avviene sia sul client che sul server puo' essere l'opzione -D 7 (massimo livello di debug) in congiunzione con -f (foreground mode, stunnel non entra in background ma rimane attivo e visualizza a video l'output del log) in modalita' daemon (da inetd purtroppo -D 7 non funziona correttamente ed i livelli minori - da 1 a 5 - sono piuttosto inutili). Se non si utilizza l'opzione -f l'output del debug sara' scritto sul syslog (quindi in /var/log/messagges o /var/log/syslog o /var/log/daemon etc. dipendentemente da come e' configurato il vostro syslog; tail -f /var/log/nomefile per visualizzaro real-time). Visualizziamo un breve esempio: ---> shell (client) kppc:~$ stunnel -D 7 -c -d 127.0.0.1:1110 -r mail.s0ftpj.org:1110 -f LOG7[1627:1024]: Service name to be used: mail.s0ftpj.org.1110 LOG5[1627:1024]: stunnel 3.4a on powerpc-unknown-linux-gnu PTHREAD LOG3[1627:1024]: /var/run/stunnel.mail.sikurezza.org.1110.pid: Permission denied (13) LOG7[1627:1024]: mail.s0ftpj.org.1110 bound to 127.0.0.1:1110 ---< il fatto che non sia possibile scrivere /var/run/stunnel.mail.sikurezza.org.1110.pid e' normale (non siamo root) e possiamo ignorare ques'errore ---> shell (server) s0ftpj:~$ stunnel -D 7 -d 1110 -r 110 -f LOG7[32076:0]: Service name to be used: 110 LOG7[32076:0]: Generating 1024 bit temporary RSA key... LOG7[32076:0]: Temporary RSA key generated LOG7[32076:0]: Certificate: /usr/local/ssl/certs/stunnel.pem LOG5[32076:0]: stunnel 3.4a on i386-unknown-openbsd2.5 FORK+LIBWRAP LOG3[32076:0]: /var/run/stunnel.23.pid: Permission denied (13) LOG7[32076:0]: 110 bound to 0.0.0.0:1110 ---< quando lanceremo il check mail su Netscape (con server localhost:1110), potremmo vedere sui rispettivi stunnel client e server: ---> (client) LOG7[1632:1026]: mail.s0ftpj.org.1110 started LOG5[1632:1026]: mail.s0ftpj.org.1110 connected from 127.0.0.1:1598 LOG7[1632:1026]: mail.s0ftpj.org.1110 connecting 195.32.69.44:1110 LOG7[1632:1026]: Remote host connected LOG7[1632:1026]: before/connect initialization LOG7[1632:1026]: before/connect initialization LOG7[1632:1026]: SSLv3 write client hello A LOG7[1632:1026]: SSLv3 read server hello A LOG7[1632:1026]: SSLv3 read server certificate A LOG7[1632:1026]: SSLv3 read server done A LOG7[1632:1026]: SSLv3 write client key exchange A LOG7[1632:1026]: SSLv3 write change cipher spec A LOG7[1632:1026]: SSLv3 write finished A LOG7[1632:1026]: SSLv3 flush data LOG7[1632:1026]: SSLv3 read finished A LOG7[1632:1026]: SSL negotiation finished successfully LOG7[1632:1026]: 1 items in the session cache LOG7[1632:1026]: 1 client connects (SSL_connect()) LOG7[1632:1026]: 1 client connects that finished LOG7[1632:1026]: 0 client renegotiatations requested LOG7[1632:1026]: 0 server connects (SSL_accept()) LOG7[1632:1026]: 0 server connects that finished LOG7[1632:1026]: 0 server renegotiatiations requested LOG7[1632:1026]: 0 session cache hits LOG7[1632:1026]: 0 session cache misses LOG7[1632:1026]: 0 session cache timeouts LOG7[1632:1026]: SSL negotiation finished successfully LOG6[1632:1026]: mail.s0ftpj.org.1110 opened with SSLv3, cipher DES-CBC3-SHA (192 bits) LOG7[1632:1026]: Sockets set to non-blocking mode LOG7[1632:1026]: SSL closed on read LOG5[1632:1026]: Connection closed: 348 bytes sent to SSL, 229 bytes sent to socket LOG7[1632:1026]: mail.s0ftpj.org.1110 finished (0 left) ---< ---> (server) LOG7[5489:0]: 110 started LOG5[5489:0]: 110 connected from 151.20.225.239:1599 LOG7[5489:0]: 110 connecting 127.0.0.1:110 LOG7[5489:0]: Remote host connected LOG7[5489:0]: before/accept initialization LOG7[5489:0]: before/accept initialization LOG7[5489:0]: SSLv3 read client hello A LOG7[5489:0]: SSLv3 write server hello A LOG7[5489:0]: SSLv3 write certificate A LOG7[5489:0]: SSLv3 write server done A LOG7[5489:0]: SSLv3 flush data LOG7[5489:0]: SSLv3 read client key exchange A LOG7[5489:0]: SSLv3 read finished A LOG7[5489:0]: SSLv3 write change cipher spec A LOG7[5489:0]: SSLv3 write finished A LOG7[5489:0]: SSLv3 flush data LOG7[5489:0]: SSL negotiation finished successfully LOG7[5489:0]: 1 items in the session cache LOG7[5489:0]: 0 client connects (SSL_connect()) LOG7[5489:0]: 0 client connects that finished LOG7[5489:0]: 0 client renegotiatations requested LOG7[5489:0]: 1 server connects (SSL_accept()) LOG7[5489:0]: 1 server connects that finished LOG7[5489:0]: 0 server renegotiatiations requested LOG7[5489:0]: 0 session cache hits LOG7[5489:0]: 0 session cache misses LOG7[5489:0]: 0 session cache timeouts LOG7[5489:0]: SSL negotiation finished successfully LOG6[5489:0]: 23 opened with SSLv3, cipher DES-CBC3-SHA (192 bits) LOG7[5489:0]: Sockets set to non-blocking mode LOG7[5489:0]: Socket closed on read LOG5[5489:0]: Connection closed: 229 bytes sent to SSL, 348 bytes sent to socket LOG7[32076:0]: 23[5489] finished with code 0 (0 left) ---< Note sul telnet: Sebbene nelle FAQ di stunnel ed di altri wrapper ssl sia chiaramente specificato che non e' possibile tunnelare telnet, perche' il protocollo dipende da alcuni fantomatici OOB data, posso garantirvi che ho usato con successo telnet+stunnel innumerevoli volte. sia tunnelando un client ed un telnet server non abilitati SSL, sia utilizzando MZtelnet o SSLtelnet per collegarmi ad un telnetd standard+stunnel, sia utilizzando un telnet+stunnel standard per collegarmi al telnetd di MZtelnet o SSLtelnet. Un breve colloquio col mio guru tcp preferito (indovinate chi e' :) ed una sfogliata veloce allo Stevens mi hanno confermato che questi dati OOB (Out of Band) sono "segnali" che il server telnet invia al client con il flag TCP URG settato per particolari utilizzi (lo Stevens ci fa anche notare che il termine OOB, sebbene utilizzato da alcune API, e' da considerarsi errato, poiche' questi segnali seguono comunque il normale flusso dei dati e sono semplicemente segnati con il flag URG - sta al client telnet processarli per primi ignorando altri dati arrivati prima :). Questi OOB data dovrebbero segnalare l'interruzione ed il ripristino dell'invio del flusso di dati da parte del server al client relativamente all'utilizzo di CTRL+S o CTRL+Q o a resize di finestre di terminale e cose simili. Devo dire che ho provato ad analizzare tcpdump alla mano il traffico tra il server telnet e stunnel daemon (sull'interfaccia lo0 del server) mentre giocavo con questi tasti, resizavo la finestra di rxvt, saltavo sulla sedia e mi scaccolavo. Non ho visto un solo pacchetto flaggato URG passare.. il comportamento del terminale mi e' sembrato del tutto normale e comunque ho utilizzato telnet via stunnel per parecchio tempo senza riscontrare il minimo problema. Puo' essere che problemi si verifichino solamente utilizzando altri telnetd (altri OS, magari meno recenti) o utilizzando collegamenti in dial-up, o nelle notti di plenilunio, etc. Chi ha altre informazioni me le comunichi :) Comunque personalmente preferisco utilizzare un client ed un server telnet che contengano direttamente il supporto SSL. A questo punto avrei una gran voglia di scrivere [FINE PRIMA PARTE], spegnere baracca burattini ed infilarmi a letto, visto che e' gia' la quarta notte che tiro le 3 per scrivere questo articolo... - si, io domani lavoro, mica come quegli scioperati universitari di fuzzo e piggo - ma pensare alla password del vostro bnc che viene sniffata da un'orda di hacker cattivissimi (ho letto qualche fanzine spassevole al riguardo) mi rovinerebbe il sonno quindi.... giochiamo coi certificati... Giochiamo coi certificati Abbiamo visto come sia possibile rendere le nostre comunicazioni non intercettabili... vediamo ora come essere sicuri che il server che stiamo contattando sia REALMENTE il server che vogliamo contattare, e, viceversa, come sia possibile autorizzare ad accedere al nostro servizio solamente un'utenza "selezionata": Per prima cosa, il server DEVE essere stato precedentemente autenticato da una CA che ne abbia "firmato" il certificato (se volete fare in casa, leggete dopo). Abbiamo quindi bisogno di una copia della chiave pubblica di questa CA (o di un'altra CA che certifichi a sua volta che la CA che ha certificato il server, ARGH, evviva le PKI :) in locale sul nostro disco, nella directory /usr/local/ssl/certs, opportunamente "hashata". In openssl, i certificati vengono ritrovati all'interno della directory cercando un file chiamato xxxxxxxx.0, dove xxxxxxxx e' l'hash (digest) della chiave da cercare. Generalmente questo file (p.es: 681bb4bc.0) e' un link che punta al nome "umano" del file che contiene realmente la chiave (p.es: s0ftpj_CA.pem) e che, sempre generalmente, risiede nella stessa directory. Insieme ad openssl e' distribuita un'apposita utility (/usr/local/ssl/bin/c_rehash) che si occupa di creare questi link e da lanciare (eventualmente cancellando a mano quelli vecchi rm -rf *.0) ogni volta si aggiungano o cancellino chiavi in questa directory. E' anche possibile creare questi link a mano di volta in volta (p. es: ln -s s0ftpj_CA.pem `openssl x509 -noout -hash -in s0ftpj_CA.pem`.0). In stunnel, le opzioni di verifica dei certificati vengono specificate tramite l'opzione -v -v 1: verifica i certificati, SE POSSIBILE. Questo significa che il vostro stunnel verifichera' il certificato della controparte SOLO se questa e' disposta a fornirne uno. Se la controparte fornisce un certificato, e questo non risulta valido il collegamento viene interrotto. Se la controparte non fornisce un certificato, il collegamento prosegue con negoziazione "anomima", cioe' crittografato ma senza che sia stata effettivamente verificata l'identita'. E' da notare che stunnel_server fornisce SEMPRE un certificato, quindi utilizzare stunnel client con l'opzione -v 1 verso un server stunnel la cui chiave non sia certificata (quella di default, p.es.), provochera' sempre un errore. Considero quest'opzione piuttosto inutile (almeno in un programma dove si creano dei "tunnel", cioe' relazioni abbastanza "statiche" tra le parti in causa). -v 2: verifica i certificati SEMPRE; Per ogni certificato viene controllata la validita' e la firma, tramite una copia della chiave pubblica della CA, che deve essere in locale (/usr/local/ssl/certs e correttamente "hashata"). E' utile principalmente sui client (sui server e' preferible l'opzione -v 3, vedi dopo), poiche' stunnel NON GESTISCE le CRL. Sara' cura dell'utente verificare periodicamente la validita' della chiave pubblica della CA (anche se GENERALMENTE la chiave pubblica di una CA non dovrebbe MAI essere revocata, se non in caso di compromissione della sicurezza della stessa - ma non sarebbe una CA molto affidabile. In caso di scadenza "naturale" della chiave, sara' openssl stesso a segnalarlo). -v 3: verifica i certificati SEMPRE, confrontandoli con una copia degli stessi che deve essere presente IN LOCALE; Per ogni certificato viene controllata la validita' e la firma sia con la copia della chiave pubblica della CA, SIA con una copia dello stesso certificato, che deve essere presente in locale. E' utile principalmente sui server. Aggiunge un grado di sicurezza "in piu'" (e anche di sbattimento per il sysadm :). Serve, p. es., per permettere l'accesso alle risorse protette solamente ad alcuni client (di cui sara' presente una copia della chiave pubblica in una directory locale sul server). Un client, anche se in possesso di un certificato regolarmente firmato da una CA autorizzata, NON potra' accedere alle risorse se il suo certificato non sara' presente in locale. Come gestire una CA? (Anche se intendete utilizzare una CA esterna, vi consiglio di leggere COMUNQUE questo capitolo... spieghero' brevemente alcune opzioni di configurazione ed alcuni parametri di openssl utili anche se generate solo le richieste di certificato) Qualora NON si desiderasse utilizzare una CA esterna, per ragioni che variano dalla semplice comodita' di utilizzo ad intricate necessita' di privacy e segretezza, etc., e' comunque possibile utilizzare openssl per impiantare e gestire una mini-CA "casalinga". E' da notare che le funzionalita' di generazione e firma dei certificati di openssl sono perfettamente "standard" e compatibili con "il resto del mondo", ma il suo utilizzo "pratico" a livello "commerciale" e' sconsigliabile per diversi fattori: il software comprende funzioni di key-managment piuttosto limitate e tutte le operazioni (o quasi) sono da effettuarsi manualmente... (quando si tratta di una dozzina di certificati, l'operazione e' fattibile.. se cominciamo a parlare di centinaia o migliaia di chiavi, con gestione "avanzata" dei permessi, delle CRL - Certificate Revocation Lists -, etc., diventa un'impresa improponibile). Per prima cosa bisognera' apportare qualche modifica al file di configurazione di openssl (/usr/local/ssl/openssl.cnf). Ovviamente e' consigliabile tenere una copia della vecchia configurazione da cui ripartire in caso di "problemi". Per il nostro esempio, cambieremo nella sezione [ CA_default ] dir = ./demoCA # Where everything is kept in dir = /usr/local/ssl/CA # Where everything is kept e personalizzeremo la sezione [ req_distinguished_name ] in questa maniera (potete sostituire interamente la sezione originale con quella riportata, cambiando i nomi - per proteggere gli innocenti :) ---> /usr/local/ssl/openssl.cnf (parte) [ req_distinguished_name ] countryName = STATO (codice 2 lettere) countryName_default = IT countryName_min = 2 countryName_max = 2 stateOrProvinceName = Nome stato (nome intero) stateOrProvinceName_default = ITALY localityName = S0ftpjlandia 0.organizationName = Nome organizzazione (p. es: ditta) 0.organizationName_default = s0ftpj organizationalUnitName = Nome dipartimento (p. es: sezione) commonName = Nome (p. es: il VOSTRO nome) commonName_max = 64 emailAddress = Indirizzo di posta emailAddress_max = 40 ---< L'utente piu' smaliziato trovera' poi utile analizzare e "personalizzare" altre sezioni di questo file di configurazione (non solo quello utilizzato per la CA, ma anche nei server e nei client). E' possibile, per esempio, cambiare la lunghezza (in bit) delle chiavi generate di default, la validita' (in giorni) dei certificati, e altre IMPORTANTI opzioni avanzate, p. es. quelle relative alle CRL (Certificate Revocation List) o quelle relative alla gestione e alle "policy" (regole) della CA (utili per impostare limiti ai certificati che sara' possibile firmare). In generale consiglio a tutti di leggere le voci ed i commenti presenti in openssl.cnf . E' da notare che nella distribuzione di openssl (e ssleay) sono presenti 2 script (CA.sh, CA.pl - dal funzionamento equivalente) che permettono di automatizzare maggiormente la gestione delle funzionalita' di CA del programma. Riportero' sia la sintassi per utilizzare direttamente openssl, sia quella degli script (personalmente uso gli script solo per generare la struttura delle directory e faccio a mano il resto). Se intendete utilizzare uno dei due script, e' consigliabile copiarlo dalla directory di distribuzione di openssl in /usr/local/ssl/bin o una directory di quelle della path (cp dir_dist_openssl/apps/CA.sh /usr/local/ssl/bin/) ed e' necessario modificare la directory di riferimento all'interno dello stesso (CATOP=./demoCA -> CATOP=/usr/local/ssl/CA in CA.sh - oppure $CATOP="/usr/local/ssl/CA" in CA.pl) Per i miei esempi, assumero' che sia openssl che CA.sh siano in una directory della path (direttamente o come link). E' da notare che i nomi di file che utilizzo nelle opzioni -out e -keyout possono essere cambiati A PIACERE, ma sono quelli utilizzati in CA.sh e ho preferito mantenerli per maggior "coerenza". In questa maniera i comandi riporatati sono ESATTAMENTE quelli utilizzati da CA.sh (o .pl). Generiamo quindi la struttura delle directory necessarie, come specificato nel file di configurazione.. ---> /usr/local/ssl/openssl.cnf (parte) [ CA_default ] dir = /usr/local/ssl/CA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem# The private key RANDFILE = $dir/private/.rand # private random number file ---< ---> shell (attenzione ai [commenti]!) kppc:/usr/local/ssl# CA.sh -help usage: CA -newcert|-newreq|-newca|-sign|-verify kppc:/usr/local/ssl# CA.sh -newca CA certificate filename (or enter to create) [premere invio, o inserire il nome di un certificato gia' creato e valido per la CA] Making CA certificate ... Using configuration from /usr/local/ssl/openssl.cnf Generating a 1024 bit RSA private key .+++++ .......+++++ writing new private key to '/usr/local/ssl/CA/private/./cakey.pem' Enter PEM pass phrase: [inserire la parola d'ordine con cui proteggere la chiave privata della CA, ovviamente "parola d'ordine" non e' una buona scelta :) ] Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- STATO (codice 2 lettere) [IT]: [reinserire la parola d'ordine per conferma, quindi rispondere ai vari quesiti. E' consigliabile utilizzare dati reali, per una maggiore "coerenza", soprattutto se si dovranno certificare molti server/utenti Premendo invio verra' scelto il default, IT in questo caso] Nome stato (nome intero) [ITALY]: S0ftpjlandia []: Nome organizzazione (p. es: ditta) [s0ftpj]: Nome dipartimento (p. es: sezione) []:Certification Authority Nome (p. es: il VOSTRO nome) []:Admin Indirizzo di posta []:admin@s0ftpj.org ---< Come potete notare, avendo precedentemente personalizzato il file di configurazione, e' stato sufficente inserire il "Nome dipartimento" (indicato come organizationalUnitName nella conf. originale), il nome dell'"intestatario" di quel certificato (commonName) e l'indirizzo email dello stesso (emailAddress). Avremmo anche potuto fare "a mano": ---> shell kppc:/usr/local/ssl/CA# mkdir certs kppc:/usr/local/ssl/CA# mkdir crl kppc:/usr/local/ssl/CA# mkdir newcerts kppc:/usr/local/ssl/CA# mkdir private kppc:/usr/local/ssl/CA# echo "01" > serial kppc:/usr/local/ssl/CA# touch index.txt kppc:/usr/local/ssl/CA# openssl req -new -x509 -keyout private/cakey.pem -out cacert.pem -days 365 Using configuration from /usr/local/ssl/openssl.cnf Generating a 1024 bit RSA private key ..................+++++ ....+++++ writing new private key to 'private/cakey.pem' Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- STATO (codice 2 lettere) [IT]: Nome stato (nome intero) [ITALY]: S0ftpjlandia []: Nome organizzazione (p. es: ditta) [s0ftpj]: Nome dipartimento (p. es: sezione) []:Certification Authority Nome (p. es: il VOSTRO nome) []:Admin Indirizzo di posta []:admin@s0ftpj.org ---< In entrambi i casi avremmo una directory /usr/local/ssl/CA cosi' strutturata: ---> shell kppc:/usr/local/ssl/CA# tree . |-- cacert.pem |-- certs |-- crl |-- index.txt |-- newcerts |-- private | -- cakey.pem -- serial 4 directories, 4 files ---< cacert.pem - e' la chiave pubblica della nostra nuova CA index.txt - serve a openssl per tenere l'elenco dei certificati emessi serial - numero seriale dell'ultimo certificato emesso certs - directory dove posizionare i certificati autenticati (in realta' openssl di suo non mette nulla in questa directory, ma puo' risultare comunque utile) newcerts - directory dove vengono posizionati i certificati appena autenticati private - directory dove posizionare le chiavi private cakey.pem - la chiave privata della CA (DA TENERE ASSOLUTAMENTE SEGRETA) A questo punto possiamo cambiare i permessi generali per la directory ed i file. E' DA NOTARE che questa operazione va COMUNQUE effettuata a mano CA.sh o .pl NON MODIFICANO i permessi standard delle directory) E' ALTAMENTE consigliabile che questa directory sia utilizzabile solamente da chi effettivamente e' l'amministratore della CA (nel mio esempio, root): ---< shell kppc:/usr/local/ssl/CA# chmod 700 . kppc:/usr/local/ssl/CA# chmod -R og= * kppc:/usr/local/ssl/CA# ls -al total 9 drwx------ 6 root staff 1024 Nov 1 02:10 . drwxr-sr-x 10 root staff 1024 Nov 1 02:08 .. -rw------- 1 root staff 1224 Nov 1 02:10 cacert.pem drwx------ 2 root staff 1024 Nov 1 02:08 certs drwx------ 2 root staff 1024 Nov 1 02:08 crl -rw------- 1 root staff 0 Nov 1 02:08 index.txt drwx------ 2 root staff 1024 Nov 1 02:08 newcerts drwx------ 2 root staff 1024 Nov 1 02:10 private -rw------- 1 root staff 3 Nov 1 02:08 serial kppc:/usr/local/ssl/CA# tree -p . |-- [-rw-------] cacert.pem |-- [drwx------] certs |-- [drwx------] crl |-- [-rw-------] index.txt |-- [drwx------] newcerts |-- [drwx------] private | -- [-rw-------] cakey.pem -- [-rw-------] serial 4 directories, 4 files ---< Abbiamo creato un certificato RSA (con corrispettiva chiave privata) a 1024 bit intestato all'organizzazione "s0ftpj", sottosezione "Certification Authority", nome "Admin" e indirizzo di posta "admin@s0ftpj.org", della citta' "S0ftpjlandia", stato "ITALY", codice "IT", valido 365 giorni, numero seriale "0" e utilizzabile per firmare altri certificati. Analizziamolo in dettaglio: ---> shell kppc:/usr/local/ssl/CA# openssl x509 -text -noout -in cacert.pem Certificate: Data: Version: 3 (0x2) Serial Number: 0 (0x0) Signature Algorithm: md5WithRSAEncryption Issuer: C=IT, ST=ITALY, O=s0ftpj, OU=Certification Authority, CN=Admin/ Email=admin@s0ftpj.org Validity Not Before: Nov 1 03:45:46 1999 GMT Not After : Oct 31 03:45:46 2000 GMT Subject: C=IT, ST=ITALY, O=s0ftpj, OU=Certification Authority, CN=Admin /Email=admin@s0ftpj.org Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:cc:49:cd:15:81:f6:d4:79:b2:dc:95:64:9b:3b: 8f:a1:c6:73:84:f0:38:6c:12:eb:04:7c:a6:ec:95: 69:ac:d2:b5:b0:b2:cd:b7:4c:a4:8f:a6:60:d2:8b: 93:63:23:6a:a6:0d:e3:70:bc:7a:91:3e:eb:c1:82: 58:de:50:11:3a:5f:09:9f:e9:d3:a0:07:49:06:b6: 4b:e8:db:c9:b2:cb:2f:fb:97:68:42:f4:b7:e4:95: 27:61:1d:17:4b:71:16:7f:05:09:19:83:43:9f:2e: 91:9e:32:c8:77:77:d9:2d:0b:00:f3:28:65:b1:f0: 1a:c6:3a:48:72:d4:c1:3f:6d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 54:02:32:70:F4:C4:65:67:DB:B8:B4:8E:BE:9A:74:17:D8:29:CA:8B X509v3 Authority Key Identifier: keyid:54:02:32:70:F4:C4:65:67:DB:B8:B4:8E:BE:9A:74:17:D8:29:CA: 8B DirName:/C=IT/ST=ITALY/O=s0ftpj/OU=Certification Authority/CN=A dmin/Email=admin@s0ftpj.org serial:00 X509v3 Basic Constraints: CA:TRUE Signature Algorithm: md5WithRSAEncryption 75:e5:a1:e5:a8:b1:9c:ba:63:b3:7d:5a:8c:ee:2b:cd:65:30: ad:c8:a6:0c:11:34:43:75:50:3a:1d:f1:4e:9c:8b:ac:47:bf: 59:a7:9c:16:23:7c:9e:f9:9a:be:37:e6:f9:12:32:4d:77:66: 39:7d:94:02:e1:82:69:88:5d:32:49:a3:ee:74:fb:e4:78:54: eb:e6:36:dc:09:bb:dd:9c:63:be:bf:aa:7f:bf:8f:f2:c3:a2: b4:e1:1a:04:a3:39:0e:9a:c5:50:11:22:14:76:81:33:00:53: c3:6a:eb:0e:e3:fb:ab:94:18:55:da:de:88:f5:7c:55:63:be: 7b:bd kppc:/usr/local/ssl/CA# cat cacert.pem -----BEGIN CERTIFICATE----- MIIDXDCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgTELMAkGA1UEBhMCSVQx DjAMBgNVBAgTBUlUQUxZMQ8wDQYDVQQKEwZzMGZ0cGoxIDAeBgNVBAsTF0NlcnRp ZmljYXRpb24gQXV0aG9yaXR5MQ4wDAYDVQQDEwVBZG1pbjEfMB0GCSqGSIb3DQEJ ARYQYWRtaW5AczBmdHBqLm9yZzAeFw05OTExMDEwMzQ1NDZaFw0wMDEwMzEwMzQ1 NDZaMIGBMQswCQYDVQQGEwJJVDEOMAwGA1UECBMFSVRBTFkxDzANBgNVBAoTBnMw ZnRwajEgMB4GA1UECxMXQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDjAMBgNVBAMT BUFkbWluMR8wHQYJKoZIhvcNAQkBFhBhZG1pbkBzMGZ0cGoub3JnMIGfMA0GCSqG SIb3DQEBAQUAA4GNADCBiQKBgQDMSc0VgfbUebLclWSbO4+hxnOE8DhsEusEfKbs lWms0rWwss23TKSPpmDSi5NjI2qmDeNwvHqRPuvBgljeUBE6Xwmf6dOgB0kGtkvo 28myyy/7l2hC9LfklSdhHRdLcRZ/BQkZg0OfLpGeMsh3d9ktCwDzKGWx8BrGOkhy 1ME/bQIDAQABo4HhMIHeMB0GA1UdDgQWBBRUAjJw9MRlZ9u4tI6+mnQX2CnKizCB rgYDVR0jBIGmMIGjgBRUAjJw9MRlZ9u4tI6+mnQX2CnKi6GBh6SBhDCBgTELMAkG A1UEBhMCSVQxDjAMBgNVBAgTBUlUQUxZMQ8wDQYDVQQKEwZzMGZ0cGoxIDAeBgNV BAsTF0NlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ4wDAYDVQQDEwVBZG1pbjEfMB0G CSqGSIb3DQEJARYQYWRtaW5AczBmdHBqLm9yZ4IBADAMBgNVHRMEBTADAQH/MA0G CSqGSIb3DQEBBAUAA4GBAHXloeWosZy6Y7N9WozuK81lMK3IpgwRNEN1UDod8U6c i6xHv1mnnBYjfJ75mr435vkSMk13Zjl9lALhgmmIXTJJo+50++R4VOvmNtwJu92c Y76/qn+/j/LDorThGgSjOQ6axVARIhR2gTMAU8Nq6w7j+6uUGFXa3oj1fFVjvnu9 -----END CERTIFICATE----- kppc:/usr/local/ssl/CA# cat private/cakey.pem -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,9A085D61C1681DC4 KmUbmLM4ganJQP63gpzWJ8PXKmXF3LB4B/4iUx3fIbbhI4bl1kDgNGQoOCAg+ynV UjPM/k5lXE4lsqSIO2uanfOm06G8zyJuXcW1Y1BfTKEbfqkE4H31EPt8F6SYs+Sh NsiHi2EV1emf5MPx2hmf6AvhSkIvNAckLdwJOrgjNEns36tfMQUnvm15gmb26yti vMZkQL0olGz4gVyWjziWxFYvkvcZh9vnpJP0U4Use48DDsgMzBn2JrxWnwZHw6Qs yH55IKh30U1BzzPn6KXt/6ZNpCennull4nGdepJUecw1yV1cQGZUvfaSxbeD8Rpy gBQ2FiZB7r8j206/WqBkhgOTLE8eVwKH7GakROogmKCR173dyqfzmq1s+gZu5p6g ek3ulat1sTezj/g79fgtY3hahGS06csRiWLRAN/eo32GFG5svt4gPh4BJZNpaEnz BrKxVkvrYHz4rfqg48fAUgE9Tmata0oYdFD1XICVgAUEGqK0KFUg/kUkNVCeh3KQ /rC6X80sp15kp5H1o27gR8lsvUTHoOo0TXPuq41LfiBWwS5hh/xo0rr/7n4c1CP7 yLP2xUSqI0ovwG0bB9dZokI8gdLuwsxSyBRGK83xzm7fhd9iAbfONqZrpI4RDslf zlIQZjJfUCfRvoRojE9adT00AoHhq4OEM0HC0LPScrvxtSzOudMLy5mumsD5UhXo 4JyHQosHYSpUo8CaMWQnTGXLCbdxWQm4O1tTfIdU0hbM7kqsR9AKjP9Rh4QkTpXM QWqreomK4dIN3lDZAv5aegmoin0B1QuXGQHCbQSR6Q/oGf3UxPfFIg== -----END RSA PRIVATE KEY----- ---< Il primo comando visualizza il certificato nella sua forma ASN.1 (una notazione "standard" per la diffusione di informazioni in formato testuale). Il secondo visualizza il contenuto del file cacert.pem, che contiene il certificato pubblico "fatto e finito" della nostra CA, cioe' il certificato che openssl (o altri programmi) utilizzeranno per verificare i certificati da voi "firmati". Il terzo visualizza il contenuto del file private/cakey.pem. Questo file contiene (in forma crittografata) la chiave privata della vostra CA. OVVIAMENTE NON E' PROPRIO IL CASO DI DISTRIBUIRE O FAR VISUALIZZARE AD ALTRI QUESTA CHIAVE, ANCHE NELLA SUA FORMA CIFRATA (viene qui riportata solamente come esempio). Prima di continuare, per generare una chiave con un numero di bit maggiori, potete aggiungere il parametro -newkey rsa:2048 oppure cambiare il parametro default_bits nella sezione [req] del file di configurazione. Per utilizzare invece l'algoritmo DSA/DSS e' necessario specificare il parametro -newkey dsa:bit (di default openssl genera chiavi RSA). Se, seguendo gli esempi riportati senza aver letto tutto l'articolo (SCONSIGLIATO) avete gia' generato la chiave della CA come RSA/1024 bit ed intendete cambiarla, dovete RIGENERARLA. E' importante decidere PRIMA il tipo di chiave ed il numero di bit da utilizzare, infatti cambiare la chiave della CA dopo aver gia' firmato dei certificati, vi obblighera' a RIFIRMARLI con la nuova chiave. Peggio ancora se avete gia' diffuso la chiave pubblica, dovrete ridistribuire il nuovo certificato (chiave pubblica) ed assicurarvi che TUTTI i client ed i server che la utilizzano ne siano informati e provvedano all'aggiornamento. Per un uso "domestico" una chiave a 1024 bit e' considerata "sufficente", tuttavia, almeno per le CA, e' consigliabile utilizzare una chiave a 2048 o 4096 bit (e queste chiavi dovrebbero venire generate in locale, su macchine non connesse a nessuna rete, protette con particolare attenzione, etc. etc. etc.). Il file cacert.pem deve essere "distribuito" come chiave pubblica "ufficiale" della CA, possibilmente rinominato in qualcosa di piu' comprensibile, tipo s0ftpj_CA.pem. E' anche consigliabile che sia possibile per un utente o chiunque ne abbia bisogno ritrovare "autonomamente" questa chiave pubblica, per esempio pubblicandola sul web server, mettendola a disposizione via ftp, tramite una richiesta di finger, etc. I certificati per gli utenti. Abbiamo preparato la nostra CA e siamo pronti per generare i vari certificati. Ai fini di openssl, i certificati dei server e dei client sono uguali (ci sarebbe il campo nsCertType - che stunnel non usa - per specificare per quale validita' ha il certificato - p. es: client, email, server, objsign, etc. - pero', ARGH!, questo e' un mini-howto su come tunnelarvi il bnc e il pop3, non su come impiantare una CA commerciale e diventare miliardari - se qualcuno comunque vuole sbattersi ad approfondire ulteriormente, faccia pure e mi comunichi i risultati, che saro' lieto di aggiungere a questo papiro - mailto: hovogliadisbattermi@sikurezza.org). E' possibile generare i certificati da autenticare direttamente (per i vostri utenti "lamah") oppure (maggior privacy) ricevere la richiesta di certificato da parte dei vari utenti (e/o sysadm), possibilmente VERIFICANDO che la richiesta ed i dati contenuti siano reali (quindi fatevi mandare le richieste cifrate e "firmate" con qualche sistema) e reinviare il certificato "autenticato". Ovviamente nel primo caso la CA sara' in possesso della chiave privata dell'utente; poiche' comunque non e' il caso di utilizzare i certificati generati per stunnel (sia client che server) per altri scopi (firmare la posta, etc.) perche' NON sono cifrati (normalmente le chiavi private vengono sempre protette tramite una password, ma non e' possibile utilizzare chiavi cifrate con stunnel), questa soluzione e' piu' che accettabile se firmate certificati di utenti che devono accedere ai vostri servizi (visto che comunque sarebbe possibile per voi accedere ai dati che vengono protetti tramite stunnel). Se invece utilizzate una CA di terze parti, e' decisamente consigliabile generare "in proprio" le chiavi private di cui poi chiedere la certificazione. Generazione di una chiave privata e conseguente richiesta di certificato da inviare alla CA: ---> shell kppc:~$ CA.sh -newreq ---< OPPURE ---> kppc:~$ openssl req -new -keyout newreq.pem -out newreq.pem -days 365 Using configuration from /usr/local/ssl/openssl.cnf Generating a 1024 bit RSA private key ....+++++ ............+++++ writing new private key to 'newreq.pem' Enter PEM pass phrase: Verifying password - Enter PEM pass phrase: ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- STATO (codice 2 lettere) [IT]: Nome stato (nome intero) [ITALY]: S0ftpjlandia []: Nome organizzazione (p. es: ditta) [s0ftpj]: Nome dipartimento (p. es: sezione) []:Stunnel client Nome (p. es: il VOSTRO nome) []:Kobaiashi Indirizzo di posta []:koba@s0ftpj.org Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: ---< Come potete notare, ho lasciato invariati il nome dell'organizzazione ed i nomi delle localita' e degli stati, mentre ho cambiato il nome del dipartimento ed il nome/indirizzo email "personale". Ovviamente non e' obbligatorio cambiarli o valorizzarli con dati "reali", e' da notare pero' che questi campi sono gli unici che ci permettono di distinguere "facilmente" tra un certificato e l'altro (sempre che non vogliate ricordarvi il numero seriale o la chiave pubblica/privata di ogni certificato a memoria :). Personalmente valorizzo il parametro "nome dipartimento" (organizationalUnitName) per "identificare" l'utilizzo che faro' del certificato (p. es: Stunnel client, Stunnel server, Telnet client, Telnetd server, Certification Authority, etc.). Gli ultimi due parametri sono opzionali e assolutamente inutili ai fini del nostro esempio. Li lasceremo quindi NON valorizzati (vuoti). Ad essere sincero, non ho un'idea precisa del loro utilizzo reale. _Dovrebbero_ poter essere utili nella revoca dei certificati, ma non sono utilizzati da openssl e sono mantenuti solamente per compatibilita' con gli standard (in particolare con Netscape Client). ---> ssleat.txt (linea 4694 -> 4701) - The Navigator supports a new HTML tag "KEYGEN" which will cause the browser to generate an RSA key pair when you submit a form containing the tag. The public key, along with an optional challenge (supposedly provided for use in certificate revocation but I don't use it) is signed, DER-encoded, base-64 encoded and sent to the web server as the value of the variable whose NAME is provided in the KEYGEN tag. The private key is stored by the browser in a local key database. ---< Vengono inseriti solamente nella richiesta di certificato, ma non vengono poi riportati nei certificati finali o in nessun'altro file utile ai fini della gestione CA in openssl. ---> newreq.pem (parte) - esempio di valorizzazione dei parametri Attributes: unstructuredName :dato_inserito challengePassword :dato_inserito <--- Il file creato contiene SIA la chiave privata, che la richiesta di certificato: ---> shell kppc:~$ cat newreq.pem -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: DES-EDE3-CBC,C088C4ACD6EF66CA TwIdD/qQkr8c3bZEMbce+vEt6wFsu6QoEOgtHln5H7XSNO+MXyvNhrXa9bIKKMM+ yG0x4BR2Fw1Ecs3wvGtxGHTM220bxJH4gn8iOvf16SzxxFN09+N6hPjxKgAMQdci 7+pg4pTNN2P8CQbn+YeeeHZxzolbZHsZm4TW4TqCfOiDOEqAR36SbZ9HUQESDPaj AT/lC9Q5Br3h2uFYCcDFFnQmNnRpldHt3h/pakbFFHaUVj8wtVYUvuQvZ4hTQgaO +oEXkQIg54MDQ11lf7KBu1kxIemDgxD/padp9bL7mfQLBIGemTJMsfSrp7ZO9mGi m7Rqwc5AnYGhdLzg5eE6E2M3RDg3pQnl7XwbBwDb3HYLqYyxaJg7BeKb8JunxH6W 47Ad50dWZEd+jVZFI8LVOnEaMy8TzjITBNcEC0hT1oRvMD4obdROGeMkBj98/cro Iih4eN9+sJ42AT9zaJtW3JvJsHWjCwSFj0qa6ICGR5egYP9HA/HN/bkcsT/FQ1+u HO0PqoyBSLNNq2EbHzrZsm7Ajc7aInqTczP8zLVWc1wzP1p02QJpyr1FqiluARSX 1lNFANda+kqHbWpOmR/Oa7NgocftFlOlIH23ZF+SDEjO2a64uQQ3/CKf9IJBVlI1 epVWl3NqIqTYNCrCneyNm7adjN9NMjxM2roGIDiCgNFc/39gU1HkmEyL7kF/eGEd 7n7ObWrWvJmRE7g1VsgkXwJSoumv+/KJRQFCq6dZSQ1yL3AWdi2wfprftse9vF3/ cbzyu5IsgVVj8HhIm3VjDV8mzNWXiY5nNocLwoSF+T+TP39whz7u5A== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE REQUEST----- MIIBuzCCASQCAQAwezELMAkGA1UEBhMCSVQxDjAMBgNVBAgTBUlUQUxZMQ8wDQYD VQQKEwZzMGZ0cGoxFzAVBgNVBAsTDlN0dW5uZWwgY2xpZW50MRIwEAYDVQQDEwlL b2JhaWFzaGkxHjAcBgkqhkiG9w0BCQEWD2tvYmFAczBmdHBqLm9yZzCBnzANBgkq hkiG9w0BAQEFAAOBjQAwgYkCgYEApUF9foVcyAIkgc76ABIenr+iAZtUnPnZaplB +veGYjH5dlJ/9y5ZuAcPP0mhVVtUxfEPX+oixDeBF+ZGTMmJS0shrm3t0Mdd93HN v6pIf7DxTg9q4YQlpWrb5FLTA9CZNXT99Aj5bZbtNibBxTJ7fhzLrEZdglCO1Izu yBimXMMCAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GBAC39jdoexKcCph0NLOFugQpU mKWcpn9Y2rlwcVPffsSLHazSTJNqdrAzpd3ME9pn5u8fApoZmmhOk3ObQd2GBFc1 HPHWPgXLPvGBG3agIhHtG/onUN1NucpeJZEjK10Us3RzZS0ptLC2Xbd/VBfUmfoS zPaF2O9S9tbOMnhVe1++ -----END CERTIFICATE REQUEST----- ---< NOTA: e' anche possibile (se non si utilizza CA.sh, quindi, tipicamente, se la richiesta viene generata direttamente dall'utente e non da chi gestisce la CA) separare direttamente l'output della chiave privata in un file (-keyout koba_private.pem) e quello della richiesta di certificato in un altro (-out koba_req.pem), evitando questo "doppio" passaggio. Se la chiave e' da utilizzarsi per stunnel (o altri programmi che richiedano chiavi private in chiaro) possiamo aggiungere l'opzione -nodes per generare una chiave privata NON CIFRATA (normalmente, come negli esempi, ogni chiave privata e' protetta da una pasword. In seguito genereremo da questa chiave una copia non protetta, quindi non e' comunque necessario utilizzare quest'opzione, evita solo di dover inserire - e ricordarsi - una password). Poiche' invieremo alla CA da cui dobbiamo essere autenticati SOLAMENTE la richiesta di certificato, generiamo da newreq.pem un file contente la richiesta, che chiameremo koba_req.pem . ---> shell kppc:~$ openssl req -in newreq.pem -out koba_req.pem Using configuration from /usr/local/ssl/openssl.cnf kppc:~$ cat koba_req.pem -----BEGIN CERTIFICATE REQUEST----- MIIBuzCCASQCAQAwezELMAkGA1UEBhMCSVQxDjAMBgNVBAgTBUlUQUxZMQ8wDQYD VQQKEwZzMGZ0cGoxFzAVBgNVBAsTDlN0dW5uZWwgY2xpZW50MRIwEAYDVQQDEwlL b2JhaWFzaGkxHjAcBgkqhkiG9w0BCQEWD2tvYmFAczBmdHBqLm9yZzCBnzANBgkq hkiG9w0BAQEFAAOBjQAwgYkCgYEApUF9foVcyAIkgc76ABIenr+iAZtUnPnZaplB +veGYjH5dlJ/9y5ZuAcPP0mhVVtUxfEPX+oixDeBF+ZGTMmJS0shrm3t0Mdd93HN v6pIf7DxTg9q4YQlpWrb5FLTA9CZNXT99Aj5bZbtNibBxTJ7fhzLrEZdglCO1Izu yBimXMMCAwEAAaAAMA0GCSqGSIb3DQEBBAUAA4GBAC39jdoexKcCph0NLOFugQpU mKWcpn9Y2rlwcVPffsSLHazSTJNqdrAzpd3ME9pn5u8fApoZmmhOk3ObQd2GBFc1 HPHWPgXLPvGBG3agIhHtG/onUN1NucpeJZEjK10Us3RzZS0ptLC2Xbd/VBfUmfoS zPaF2O9S9tbOMnhVe1++ -----END CERTIFICATE REQUEST----- ---< E' possibile visualizzare l'output "text" (ASN.1) della richiesta di certificato che stiamo per inviare: ---> shell kppc:~$ openssl req -text -noout -in koba_req.pem Using configuration from /usr/local/ssl/openssl.cnf Certificate Request: Data: Version: 0 (0x0) Subject: C=IT, ST=ITALY, O=s0ftpj, OU=Stunnel client, CN=Kobaiashi/Emai l=koba@s0ftpj.org Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:a5:41:7d:7e:85:5c:c8:02:24:81:ce:fa:00:12: 1e:9e:bf:a2:01:9b:54:9c:f9:d9:6a:99:41:fa:f7: 86:62:31:f9:76:52:7f:f7:2e:59:b8:07:0f:3f:49: a1:55:5b:54:c5:f1:0f:5f:ea:22:c4:37:81:17:e6: 46:4c:c9:89:4b:4b:21:ae:6d:ed:d0:c7:5d:f7:71: cd:bf:aa:48:7f:b0:f1:4e:0f:6a:e1:84:25:a5:6a: db:e4:52:d3:03:d0:99:35:74:fd:f4:08:f9:6d:96: ed:36:26:c1:c5:32:7b:7e:1c:cb:ac:46:5d:82:50: 8e:d4:8c:ee:c8:18:a6:5c:c3 Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: md5WithRSAEncryption 2d:fd:8d:da:1e:c4:a7:02:a6:1d:0d:2c:e1:6e:81:0a:54:98: a5:9c:a6:7f:58:da:b9:70:71:53:df:7e:c4:8b:1d:ac:d2:4c: 93:6a:76:b0:33:a5:dd:cc:13:da:67:e6:ef:1f:02:9a:19:9a: 68:4e:93:73:9b:41:dd:86:04:57:35:1c:f1:d6:3e:05:cb:3e: f1:81:1b:76:a0:22:11:ed:1b:fa:27:50:dd:4d:b9:ca:5e:25: 91:23:2b:5d:14:b3:74:73:65:2d:29:b4:b0:b6:5d:b7:7f:54: 17:d4:99:fa:12:cc:f6:85:d8:ef:52:f6:d6:ce:32:78:55:7b: 5f:be ---< E' sufficente inviare la richiesta di certificazione (koba_req.pem - ATTENZIONE A NON INVIARE LA CHIAVE PRIVATA!) alla CA. Come "firmare" un certificato: Qualora siate voi stessi una CA, supponendo che abbiate gia' seguito le istruzioni riportate precedentemente per il setup "base" (struttura delle directory, chiavi pubbliche/privata della CA stessa, etc.), le procedure per la "firma" dei certificati degli utenti sono molto semplici: Copiamo (eventualmente sovrascrivendo il vecchio file) la richiesta di certificazione ricevuta (o generata da noi stessi per un nostro utente o server) nel file /usr/local/ssl/CA/newreq.pem . Ovviamente sara' opportuno, prima di firmare il certificato, CONTROLLARE la validita' dei dati contenuti nella richiesta (con openssl req -text -in newreq.pem); VERIFICARE che la richiesta sia stata generata REALMENTE dall'utente di cui risulta il nome; ASSICURARSI che non ci siano state "manipolazioni" durante l'invio del file, etc. . E' quindi fondamentale utilizzare strumenti di crittografia quali PGP (http://www.pgpi.org), oppure le funzionalita' S/MIME dei client di posta, oppure ricorrere al buon vecchio sistema del telefono/fax, etc., per verificare l'identita' dell'utente e l'integrita' della richiesta di certificato spedita. Puo' essere utile in questo caso il comando digest di openssl o il comando md5sum presente su molti sistemi unix (anche con nome leggermente differente). ---> shell (utente) kppc:~$ wc koba_req.pem 12 16 676 koba_req.pem kppc:~$ md5sum koba_req.pem daa5de3a1d0b159da0de4e90cb2665cb koba_req.pem kppc:~$ openssl dgst -md5 < koba_req.pem daa5de3a1d0b159da0de4e90cb2665cb kppc:~$ openssl dgst -sha1 < koba_req.pem 4aff5dac01408a0be0f8f85ebf1db3bd61414fd4 kppc:~$ openssl dgst -ripemd160 < koba_req.pem dc7d80016f608a2ba28c3488a4f72f51394f9b35 ---< ---> shell (CA) kppc:/usr/local/ssl/CA# md5sum newreq.pem daa5de3a1d0b159da0de4e90cb2665cb newreq.pem kppc:/usr/local/ssl/CA# openssl dgst -md5 < newreq.pem daa5de3a1d0b159da0de4e90cb2665cb kppc:/usr/local/ssl/CA# openssl dgst -sha1 < newreq.pem 4aff5dac01408a0be0f8f85ebf1db3bd61414fd4 kppc:/usr/local/ssl/CA# openssl dgst -ripemd160 < newreq.pem dc7d80016f608a2ba28c3488a4f72f51394f9b35 ---< Questi sono tre diversi digest (sha1, md5 e ripemd160) della richiesta di certificato che abbiamo generato. Utilizzando uno di questi comandi (md5 e' considerato il "meno sicuro") e' possibile ottenere una breve stringa UNIVOCA (in pratica: ad ogni file corrisponde una stringa digest diversa che non puo' venire generata con nessun altro file, a meno che non sia esattamente uguale), comunicabile facilmente via telefono o fax e tramite la quale la CA e l'utente possono confrontare la copia della richiesta di certificato per verificare che siano eguali (ovviamente i file devono essere esattamente uguali, spazi e a capo compresi - il comando wc conta linee, parole e caratteri di un file - se questi numeri differiscono, non avete speranza che il digest dia lo stesso risultato!) Possiamo finalmente procedere e "firmare" il certificato: ---> shell kppc:/usr/local/ssl/CA# CA.sh -sign ---< OPPURE ---> kppc:/usr/local/ssl/CA# openssl ca -policy policy_anything -out newcert.pem -infiles newreq.pem Using configuration from /usr/local/ssl/openssl.cnf Enter PEM pass phrase: Check that the request matches the signature Signature ok The Subjects Distinguished Name is as follows countryName :PRINTABLE:'IT' stateOrProvinceName :PRINTABLE:'ITALY' organizationName :PRINTABLE:'s0ftpj' organizationalUnitName:PRINTABLE:'Stunnel client' commonName :PRINTABLE:'Kobaiashi' emailAddress :IA5STRING:'koba@s0ftpj.org' Certificate is to be certified until Oct 31 21:48:14 2000 GMT (365 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated ---< Utilizzando CA.sh viene anche visualizzato a video il certificato firmato appena generato. "ca" e' il sottocomando di openssl destinato alla gestione delle funzionalita' di CA (openssl ca -help per un sommario dei comandi). L'opzione -policy specifica alcune regole aggiuntive che openssl controllera' prima di permettere la firma del certificato (che va comunque confermata "manualmente" per ben due volte). "policy_anything" di default richiede solamente che sia valorizzato ("supplied") il campo "commonName", mentre gli altri sono opzionali ("optional"). E' anche possibile modificare la policy in maniera che permetta di firmare certificati solamenta se alcuni dei campi sono valorizzati in maniera eguale agli omonimi campi del certificato della CA ("match"). ---> /usr/local/ssl/openssl.cnf (parte) # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional ---< E' da notare che queste opzioni agiscono PRIMA della fase di firma vera e propria, cioe' specificando un certificato NON valido per la policy che si intende utilizzare, non sara' possibile firmarlo. Queste opzioni non influenzano il comportamento di openssl e stunnel con i certificati gia' firmati! Dopo il "commit", openssl aggiorna sia il file serial che il file index.txt, e copia newcert.pem (il certificato firmato) nella directory newcerts/, chiamandolo xx.pem (dove xx e' il numero seriale del certificato, nel nostro esempio 01.pem): ---> shell kppc:/usr/local/ssl/CA# cat serial 02 kppc:/usr/local/ssl/CA# cat index.txt V 001031214814Z 01 unknown /C=IT/ST=ITALY/O=s0ftpj/OU=Stun nel client/CN=Kobaiashi/Email=koba@s0ftpj.org kppc:/usr/local/ssl/CA# cat newcert.pem issuer :/C=IT/ST=ITALY/O=s0ftpj/OU=Certification Authority/CN=Admin/Email=admin @s0ftpj.org subject:/C=IT/ST=ITALY/O=s0ftpj/OU=Stunnel client/CN=Kobaiashi/Email=koba@s0ftp j.org serial :01 Certificate: Data: Version: 3 (0x2) Serial Number: 1 (0x1) Signature Algorithm: md5WithRSAEncryption Issuer: C=IT, ST=ITALY, O=s0ftpj, OU=Certification Authority, CN=Admin/ Email=admin@s0ftpj.org Validity Not Before: Nov 1 21:48:14 1999 GMT Not After : Oct 31 21:48:14 2000 GMT Subject: C=IT, ST=ITALY, O=s0ftpj, OU=Stunnel client, CN=Kobaiashi/Emai l=koba@s0ftpj.org Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (1024 bit) Modulus (1024 bit): 00:a5:41:7d:7e:85:5c:c8:02:24:81:ce:fa:00:12: 1e:9e:bf:a2:01:9b:54:9c:f9:d9:6a:99:41:fa:f7: 86:62:31:f9:76:52:7f:f7:2e:59:b8:07:0f:3f:49: a1:55:5b:54:c5:f1:0f:5f:ea:22:c4:37:81:17:e6: 46:4c:c9:89:4b:4b:21:ae:6d:ed:d0:c7:5d:f7:71: cd:bf:aa:48:7f:b0:f1:4e:0f:6a:e1:84:25:a5:6a: db:e4:52:d3:03:d0:99:35:74:fd:f4:08:f9:6d:96: ed:36:26:c1:c5:32:7b:7e:1c:cb:ac:46:5d:82:50: 8e:d4:8c:ee:c8:18:a6:5c:c3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Comment: OpenSSL Generated Certificate X509v3 Subject Key Identifier: 85:8D:0E:12:94:51:BD:1C:20:F7:65:52:B1:9D:89:B6:B2:67:7F:FB X509v3 Authority Key Identifier: keyid:54:02:32:70:F4:C4:65:67:DB:B8:B4:8E:BE:9A:74:17:D8:29:CA: 8B DirName:/C=IT/ST=ITALY/O=s0ftpj/OU=Certification Authority/CN=A dmin/Email=admin@s0ftpj.org serial:00 Signature Algorithm: md5WithRSAEncryption 59:b0:40:03:b9:5f:84:c0:fb:1d:e6:94:03:80:31:e8:ce:78: 10:59:6f:6f:85:da:0b:73:cf:8e:cf:af:83:aa:72:58:2a:e2: 65:6b:42:9c:3e:00:63:7f:64:cc:8b:70:8b:82:74:f5:a5:8c: 82:9e:56:51:f6:9d:37:c1:26:54:4d:6d:35:30:fe:d6:b4:fe: 51:09:e6:86:87:60:73:99:3e:b8:44:af:b6:9f:01:26:07:7a: a0:d9:17:95:65:9f:28:86:7b:39:e3:2f:dc:71:9e:2c:44:ce: 50:ca:8f:6d:5c:63:26:b6:aa:d6:d1:03:b1:9d:7f:34:b5:94: 03:91 -----BEGIN CERTIFICATE----- MIIDgjCCAuugAwIBAgIBATANBgkqhkiG9w0BAQQFADCBgTELMAkGA1UEBhMCSVQx DjAMBgNVBAgTBUlUQUxZMQ8wDQYDVQQKEwZzMGZ0cGoxIDAeBgNVBAsTF0NlcnRp ZmljYXRpb24gQXV0aG9yaXR5MQ4wDAYDVQQDEwVBZG1pbjEfMB0GCSqGSIb3DQEJ ARYQYWRtaW5AczBmdHBqLm9yZzAeFw05OTExMDEyMTQ4MTRaFw0wMDEwMzEyMTQ4 MTRaMHsxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJVEFMWTEPMA0GA1UEChMGczBm dHBqMRcwFQYDVQQLEw5TdHVubmVsIGNsaWVudDESMBAGA1UEAxMJS29iYWlhc2hp MR4wHAYJKoZIhvcNAQkBFg9rb2JhQHMwZnRwai5vcmcwgZ8wDQYJKoZIhvcNAQEB BQADgY0AMIGJAoGBAKVBfX6FXMgCJIHO+gASHp6/ogGbVJz52WqZQfr3hmIx+XZS f/cuWbgHDz9JoVVbVMXxD1/qIsQ3gRfmRkzJiUtLIa5t7dDHXfdxzb+qSH+w8U4P auGEJaVq2+RS0wPQmTV0/fQI+W2W7TYmwcUye34cy6xGXYJQjtSM7sgYplzDAgMB AAGjggENMIIBCTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUhY0OEpRRvRwg92VSsZ2JtrJn f/swga4GA1UdIwSBpjCBo4AUVAIycPTEZWfbuLSOvpp0F9gpyouhgYekgYQwgYEx CzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJVEFMWTEPMA0GA1UEChMGczBmdHBqMSAw HgYDVQQLExdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEOMAwGA1UEAxMFQWRtaW4x HzAdBgkqhkiG9w0BCQEWEGFkbWluQHMwZnRwai5vcmeCAQAwDQYJKoZIhvcNAQEE BQADgYEAWbBAA7lfhMD7HeaUA4Ax6M54EFlvb4XaC3PPjs+vg6pyWCriZWtCnD4A Y39kzItwi4J09aWMgp5WUfadN8EmVE1tNTD+1rT+UQnmhodgc5k+uESvtp8BJgd6 oNkXlWWfKIZ7OeMv3HGeLETOUMqPbVxjJraq1tEDsZ1/NLWUA5E= -----END CERTIFICATE----- ---< Possiamo ora rispedire il certificato "firmato" all'utente. ---> shell kppc:/usr/local/ssl/CA# openssl x509 -in newcert.pem -out koba_signed.pem ---< Se abbiamo generato anche la chiave privata dell'utente, oppure una chiave da usare su un nostro server, sara' necessario inserire anche questa all'interno del file (in seguito e' spiegato come creare un certificato utilizzabile come "stunnel.pem". In questo caso, e' consigliabile spedire all'utente o al sysadm il certificato "fatto e finito"). Ovviamente, se spedite anche la chiave privata, E' ASSOLUTAMENTE NECESSARIO CHE QUESTA COMUNICAZIONE AVVENGA IN MANIERA PROTETTA! Personalmente trovo utile rinominare new_cert.pem in qualcosa tipo kobaiashi_signed.pem e newreq.pem in qualcosa tipo kobaiashi_req.pem e spostarli in una directory qualsiasi (tipo /certs) come "history", visto che i certificati firmati da openssl sono posizionati in /newcerts e identificabili solamente tramite il serial (01.pem, 02.pem, etc. - l'indice e' contenuto in index.txt). Se avete generato direttamente il certificato per l'utente, consiglio di spostare la chiave privata dell'utente nella directory /private, rinominandola koba_private.req o qualcosa di simile. Sara' vostra cura controllare i permessi delle directory e dei file, in maniera che i file contenenti le chiavi private (anche quelle generate nei vari passaggi) NON siano leggibili da chiunque non ne abbia diritto (generalmente, nessuno all'infuori di voi :) o vengano cancellate (possibilmente sovrascritte o "wipeate"). Let's go! Vediamo ora come, da un file contenente la chiave privata (newreq.pem) e da un file contenente il certificato firmato (koba_signed.pem), generare uno "stunnel.pem" valido per essere utilizzato con stunnel. Se abbiamo ricevuto il certificato da una CA, sara' opportuno verificare l'effettiva validita' della firma. ---> shell kppc:~$ openssl verify koba_signed.pem koba_signed.pem: /C=IT/ST=ITALY/O=s0ftpj/OU=Stunnel client/CN=Kobaiashi/Email=koba@s0ftpj.org error 20 at 0 depth lookup:unable to get local issuer certificate ---< In questo esempio, la verifica e' "fallita", perche' la chiave pubblica della CA non e' presente nella directory usr/local/ssl/certs o questa directory non e' correttamente "hashata" (vedere la sezione "Come funziona tecnicamente"). Possiamo ovviare (temporaneamente) passando direttamente la chiave pubblica della CA con l'opzione -CAfile: ---> shell kppc:~$ openssl verify -CAfile s0ftpj_CA.pem koba_signed.pem koba_signed.pem: OK ---< oppure copiare la chiave pubblica nella corretta posizione e ricreare le hash necessarie ad openssl per ritrovare le chiavi (probabilmente sono necessari i permessi root per eseguire queste operazioni) ---> shell kppc:~# cp s0ftpj_CA.pem /usr/local/ssl/certs/ kppc:~# cd /usr/local/ssl/certs kppc:/usr/local/ssl/certs# ls -l total 2 -rw-r--r-- 1 root root 1224 Nov 1 23:52 s0ftpj_CA.pem kppc:/usr/local/ssl/certs# /usr/local/ssl/bin/c_rehash Doing /usr/local/ssl/certs s0ftpj_CA.pem => 901428a0.0 kppc:/usr/local/ssl/certs# ls -l total 2 lrwxrwxrwx 1 root root 13 Nov 2 00:17 901428a0.0 -> s0ftpj_CA.pem -rw-r--r-- 1 root root 1224 Nov 1 23:52 s0ftpj_CA.pem ---< Estraiamo quindi la chiave privata ed il certificato firmato e generiamo un unico file, che chiameremo koba_stunnel.pem (se ci servira per stunnel_client) o stunnel.pem (per il server). ---> shell kppc:~$ openssl rsa -in newreq.pem -out koba_stunnel.pem read RSA private key Enter PEM pass phrase: writing RSA private key kppc:~$ openssl x509 -in koba_signed.pem >> koba_stunnel.pem kppc:~$ cat koba_stunnel.pem ----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQClQX1+hVzIAiSBzvoAEh6ev6IBm1Sc+dlqmUH694ZiMfl2Un/3 Llm4Bw8/SaFVW1TF8Q9f6iLEN4EX5kZMyYlLSyGube3Qx133cc2/qkh/sPFOD2rh hCWlatvkUtMD0Jk1dP30CPltlu02JsHFMnt+HMusRl2CUI7UjO7IGKZcwwIDAQAB AoGBAJ2Dvd1Ruqz9tdRw90QIAV2pJP9JEi6Jy51atVREiLeiELiiTEzLxkKtn+/f +8JDSptdeR0gK8FBcm/YUtuwIYa1pnauzJ/vyBHT3F/Tl7Rv+TO8XPWwzdZTe1JK PtV6hbu/4qM4dgv8GBQevudt9cXWXHPk8nCmBNfXB6eWUopRAkEA1JX2sH51IU8T 1X3sH1SSWA+TN6XL/JNjBsfaekLjzhpdlqYlmeGbOXELm2J2wvoz9p3z2ZSB9uvV Os8VT2PDGQJBAMcBGqsn6nGD/M98GZ8cCjMYFLWMHpEmkkRV2QOVwtpZWAtUv6wG AVRdyR6XLQpJqoVgtGHsdMwutmgjGwPOVjsCQQDDlQD0GjQbJAzEY2jE3mMRn6q7 DM+indsClwZba4T4zusBufRoIddUvruGBs3qzpTWNTXvHSGBEjIIPBOICempAkBc oQXxzwWQSvhc943RgrK4r6fMDWmY9JQ2nKMDySzGh7m0pIEHKFBsHa9kvsdnN3zY 0neD8RU4iTG8bULA1cVLAkEAn9UGPYgK/tPv1WD6MP3X768yVpP3JFIhaA/fD/Xe 091VewNkm09BLOTY0xQl7rjOTcfGQqNDV3NFi0h4xYSoLQ== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIDgjCCAuugAwIBAgIBATANBgkqhkiG9w0BAQQFADCBgTELMAkGA1UEBhMCSVQx DjAMBgNVBAgTBUlUQUxZMQ8wDQYDVQQKEwZzMGZ0cGoxIDAeBgNVBAsTF0NlcnRp ZmljYXRpb24gQXV0aG9yaXR5MQ4wDAYDVQQDEwVBZG1pbjEfMB0GCSqGSIb3DQEJ ARYQYWRtaW5AczBmdHBqLm9yZzAeFw05OTExMDEyMTQ4MTRaFw0wMDEwMzEyMTQ4 MTRaMHsxCzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJVEFMWTEPMA0GA1UEChMGczBm dHBqMRcwFQYDVQQLEw5TdHVubmVsIGNsaWVudDESMBAGA1UEAxMJS29iYWlhc2hp MR4wHAYJKoZIhvcNAQkBFg9rb2JhQHMwZnRwai5vcmcwgZ8wDQYJKoZIhvcNAQEB BQADgY0AMIGJAoGBAKVBfX6FXMgCJIHO+gASHp6/ogGbVJz52WqZQfr3hmIx+XZS f/cuWbgHDz9JoVVbVMXxD1/qIsQ3gRfmRkzJiUtLIa5t7dDHXfdxzb+qSH+w8U4P auGEJaVq2+RS0wPQmTV0/fQI+W2W7TYmwcUye34cy6xGXYJQjtSM7sgYplzDAgMB AAGjggENMIIBCTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUhY0OEpRRvRwg92VSsZ2JtrJn f/swga4GA1UdIwSBpjCBo4AUVAIycPTEZWfbuLSOvpp0F9gpyouhgYekgYQwgYEx CzAJBgNVBAYTAklUMQ4wDAYDVQQIEwVJVEFMWTEPMA0GA1UEChMGczBmdHBqMSAw HgYDVQQLExdDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEOMAwGA1UEAxMFQWRtaW4x HzAdBgkqhkiG9w0BCQEWEGFkbWluQHMwZnRwai5vcmeCAQAwDQYJKoZIhvcNAQEE BQADgYEAWbBAA7lfhMD7HeaUA4Ax6M54EFlvb4XaC3PPjs+vg6pyWCriZWtCnD4A Y39kzItwi4J09aWMgp5WUfadN8EmVE1tNTD+1rT+UQnmhodgc5k+uESvtp8BJgd6 oNkXlWWfKIZ7OeMv3HGeLETOUMqPbVxjJraq1tEDsZ1/NLWUA5E= -----END CERTIFICATE----- ---< Se intendiamo poter utilizzare con stunnel la negoziazione DH, dobbiamo anche aggiungere a stunnel.pem (sia sul client che sul server) uno "strong prime" DH (altrimenti la negoziazione SSL avverra' sempre utilizzando RSA e verra' visualizzato un "warning" nel syslog). ---> shell kppc:~$ openssl gendh -rand /dev/random >> koba_stunnel.pem 89 semi-random bytes loaded Generating DH parameters, 512 bit long strong prime, generator of 2 This is going to take a long time ............................+.................................................. ..................................................................+............ .....+.+.....................+...................+.......................+.+..+ .............................+.....+.................+.....................+... ............................................................................+.. ...........................+..................................................+ +*++*++*++*++* ---< verranno aggiunte al file le seguente righe: ---> koba_stunnel.pem (parte) -----BEGIN DH PARAMETERS----- MEYCQQDIWCaS+HpRSmsoB6AhgM8qcdnfIgJ1vfFUkQljsiu5vEyBLfQt0/hDnim8 9KZyv/FAcevvh4zOEvG9VNZOEwKLAgEC -----END DH PARAMETERS----- ---< Nell'esempio abbiamo generato un file che puo' essere utilizzato sia per un client, che per un server. In questo secondo caso, per comodita', e' consigliabile rinominare il file in stunnel.pem e spostarlo in /usr/local/certs, PROTEGGENDOLO DA LETTURA con i permessi appropriati (ricordo, per l'ennesima volta, che questo file contiene anche la chiave RSA privata NON CIFRATA e chiunque abbia accesso a questo file potra' fingere di essere il vostro stunnel_server). Utilizzo di stunnel_client con verifica: La sintassi di stunnel_client non cambia rispetto a quanto specificato precedentemente.. aggiungeremo il parametro -p certificato e -v 2 stunnel -c -d 127.0.0.1:1110 -r mail.s0ftpj.org 995 -p koba_stunnel.pem -v 2 Se il parametro -p non viene fornito, il client utilizzera' /usr/local/ssl/certs/stunne.pem (se presente e leggibile). (ricordo che nella directory /usr/local/ssl/certs deve essere presente il certificato pubblico della CA che ha firmato il certificato del server a cui vogliamo collegarci, opportunamente "hashato" e leggibile dall'utente con cui lanciamo stunnel_client) Utilizzo di stunnel_server con verifica: Anche la sintassi del server non cambia molto... Assumiamo che la chiave privata ed il certificato siano contenuti nel file /usr/local/ssl/certs/stunnel.pem (e' comunque possibile specificare un file diverso tramite il parametro -p). 995 stream tcp nowait stunnel /usr/local/sbin/stunnel stunnel -r 110 -v 3 Il parametro -v 3 FORZA il server a verificare il certificato fornito dal client, oltre che per una firma valida della CA anche con una copia dello stesso presente IN LOCALE (nella directory /usr/local/ssl/certs/mytrusted, modificabile con -a). Ovviamente sara' necessario inserire in questa directory TUTTI i certificati pubblici degli utenti che sono autorizzati ad accedere alle risorse protette con stunnel, e procedere a "hashare" la directory (e' possibile utilizzare c_rehash /usr/local/ssl/certs/mystrusted per automatizzare questa operazione). Qualora un utente precedentemente "valido" non debba piu' essere autorizzato ad accedere alle risorse, sara' sufficente cancellare la copia del certificato presente in mytrusted. Questo e', in stunnel, l'unico sistema per negare l'accesso ad un client in possesso di un certificato firmato da una CA valida (salvo che non sia scaduto), POICHE' NON E' POSSIBILE utilizzare CRL. Utilizzando il parametro -v 2 anche nel server, TUTTI gli utenti in possesso di un certificato regolarmente firmato da una CA di quelle "autorizzate" (cioe' tutte quelle di cui sono presenti i certificati in /usr/local/ss/certs) potranno accedere alle risorse. Revoca certificati/CRL/etc. Devo ammettere che non ho utilizzato molto le funzionalita' di crl di openssl se non per qualche prova necessarie alla stesura di questo articolo, quindi le trattero' in maniera piuttosto superficiale. E' da notare che questo capitolo e' stato incluso piu' per "completezza" che per una reale esigenza. Ne stunnel, ne nessun'altra applicazione che utilizzi le funzioni standard di openssl per la verifica dei certificati (da /usr/local/ssl/certs) tengono infatti conto di un eventuale CRL, anche se posizionata in questa directory. Sebbene siano presenti in openssl delle funzioni di lettura e gestione CRL, il software deve ESPLICITAMENTE richiamare queste funzioni. Per revocare un certificato la sintassi e' la seguente: ---> shell kppc:/usr/local/ssl/CA# openssl ca -revoke newcerts/01.pem Using configuration from /usr/local/ssl/openssl.cnf Enter PEM pass phrase: Revoking Certificate 01. Data Base Updated kppc:/usr/local/ssl/CA# cat index.txt R 001031214814Z 991102003217Z 01 unknown /C=IT/ST=ITALY/O=s0ftpj /OU=Stunnel client/CN=Kobaiashi/Email=koba@s0ftpj.org ---< con -revoke viene passato il file contenente il certificato da revocare. In questo caso ho passato come parametro il file newcerts/01.pem, dopo aver verificato in index.txt quale fosse il nome del file corrispondente al certificato che intendevo revocare. In questo stesso file possiamo notare i cambiamenti apportati da openssl dopo la revoca. Il primo carattere della riga che descrive il certificato interessato, e' stato sostituito con "R" (valori possibili "V" - valido, "R" - revocato, "E" - scaduto). Dopo ogni revoca di certificato (e ad intervalli regolari, tipo una volta al giorno, etc.) e' opportuno emettere una CRL da rendere pubblica, in modo che sia possibile per i vari client e server aggiornare l'elenco dei certificati non piu' validi. ---> shell kppc:/usr/local/ssl/CA# openssl ca -gencrl -crldays 1 -out s0ftpj-crl.pem Using configuration from /usr/local/ssl/openssl.cnf Enter PEM pass phrase: kppc:/usr/local/ssl/CA# cat s0ftpj_CA.crl -----BEGIN X509 CRL----- MIIBRzCBsTANBgkqhkiG9w0BAQQFADCBgTELMAkGA1UEBhMCSVQxDjAMBgNVBAgT BUlUQUxZMQ8wDQYDVQQKEwZzMGZ0cGoxIDAeBgNVBAsTF0NlcnRpZmljYXRpb24g QXV0aG9yaXR5MQ4wDAYDVQQDEwVBZG1pbjEfMB0GCSqGSIb3DQEJARYQYWRtaW5A czBmdHBqLm9yZxcNOTkxMTAyMDAyNzUwWhcNOTkxMjAyMDAyNzUwWjANBgkqhkiG 9w0BAQQFAAOBgQA5i/d0fuCAcjpZ9GNZmwuLdeXdAvkA2Ss1akhuYd7hTBPwg565 157GMzRkaNCz1PH91Aw5ZTdnAveDHWezvgOmrVfkJdSyqjvAJkMqTX+yyAhcumbV 0efru22k17Zw54S0Gc/kSDUlITx9wxB2ybpOMqoINuYMD6X+3ytJCbwTfA== -----END X509 CRL----- kppc:/usr/local/ssl/CA# openssl crl -text -noout -in s0ftpj-crl.pem Certificate Revocation List (CRL): Version 1 (0x0) Signature Algorithm: md5WithRSAEncryption Issuer: /C=IT/ST=ITALY/O=s0ftpj/OU=Certification Authority/CN=Admin/Ema il=admin@s0ftpj.org Last Update: Nov 2 00:41:16 1999 GMT Next Update: Nov 3 00:41:16 1999 GMT Revoked Certificates: Serial Number: 01 Revocation Date: Nov 2 00:32:17 1999 GMT Signature Algorithm: md5WithRSAEncryption 81:65:d7:66:a9:58:f6:82:33:96:98:a1:78:03:13:c7:49:3a: 84:1e:4c:f2:f7:14:d2:7d:59:49:c6:a9:f3:78:c0:fa:1d:01: 9e:fc:8b:c7:98:ac:07:c0:a5:43:c5:54:b4:23:82:d7:51:2e: a6:0a:2f:49:1a:4b:f8:ca:f3:b9:50:e8:28:0b:6c:c8:7b:c9: ec:d5:16:2b:9f:19:59:ca:ad:79:14:29:ce:db:2a:64:7a:de: 1c:d2:4c:f1:2a:45:f6:3d:d9:3f:44:18:ca:be:73:23:db:09: 22:b9:d0:c7:d7:7f:c4:d0:3e:4a:b8:30:b9:5b:23:e1:7c:5f: 85:a6 ---< Con il primo comando abbiamo generato una CRL. Il parametro -crldays 1 specifica che la prossima CRL sara' emessa tra un giorno esatto (ovviamente dovra' essere generata "a mano" o tramite uno script, questa e' solo un'informazione che i vari utenti possono ricavare analizzando la CRL emessa, NON un comando tramite il quale rilanciare automaticamente openssl tra 24 ore). Il secondo comando visualizza la CRL cosi' come e' stata generata. Il terzo ne visualizza il contenuto in forma testuale. E' da notare che ogni CRL generata con openssl conterra' comunque l'elenco di tutti i certificati revocati, anche se nel frattempo fossero scaduti. Sara' cura della CA mettere a disposizione degli utenti e dei server la CRL in maniera che sia possibile per loro aggiornare periodicamente la copia locale con quella nuova (p. es. via web: www.s0ftpj.org/crl.pem). Ovviamente sara' cura dei server o dei client effettuare realmente questo aggiornamento! Note e consigli vari: - Lavorate IN LOCALE o utilizzando ssh per generare i certificati, altrimenti un eventuale attaccante potrebbe "carpire" la password che utilizzate per il certificato (o peggio, quella della CA) e tutto questo documento risulterebbe inutile! - La chiave privata di stunnel (sia utilizzato come client che come server) NON E' CRITTOGRAFATA su disco, quindi tenetela sempre con mask r-------- (600) o rw-r----- (640) se utilizzate il sistema del doppio id e, in caso di compromissione della sicurezza del sistema, CAMBIATELA (ma in questo caso avete problemi ben piu gravi :). - Non utilizzate come chiave di stunnel la stessa chiave che utilizzate per altre cose, come firmare la posta o accedere a server web via ssl. - Non utilizzate SOLAMENTE la certificazione di stunnel come autentificazione. Se il servizio a cui vi connettete prevede un'autenticazione (password, etc.), utilizzatela! - Non utilizzate la chiave di stunnel per certificare le chiavi dei client e viceversa. Utilizzate una chiave apposita (preferibilmente a 1024 o 2048 bit) solo per la CA, con cui certificare sia i server che i client. NON tenete la chiave della CA su un sistema accessibile e comunque PROTEGGETELA SEMPRE CON PASSWORD. - Ricordate che se utilizzate stunnel su una macchina di cui non siete (o non siete gli unici) root, e' possibile COMUNQUE per il sysadm (o qualcuno con privilegi simili) "intercettare" le vostre comunicazioni (con uno sniffer sull'interfaccia lo se usate un redirect, con un po' di sbattimento se usate -l) e fare _qualsiasi_ altra cosa (modificare openssl per rubarvi le password, etc.). - Ricordate che i generatori di numeri "casuali" su computer non sono poi COSI' causali. Configurate /usr/local/ssl/openssl.cnf per usare dati realmente random (/dev/random sotto Linux recenti e /dev/srandom sotto OpenBSD dovrebbero fornire sufficente sicurezza per un utilizzo "casalingo"). La configurazione di default di openssl utilizza un file di nome .rnd nella home dell'utente - al primo utilizzo questo file e' VUOTO; quindi copiateci sopra un file qualsiasi (tipo l'mp3 del vostro gatto che miagola) - ogni volta che openssl utilizza .rnd lo modifica, ma sicuramente e' consigliabile sostituirlo prima dell'utilizzo con dati casuali - il piu' casuali possibile; senza copiare .rnd ogni volta, e' possibile usare in openssl il parametro -rand file:file:file :) - Ricordate che quello che cancellate da un disco, non viene distrutto, ma e' possibile per chiunque (root) con un disk-editor e, anche se sovrascritto, da specialisti con attrezzature apposite, ritrovarne il contenuto. Non generate le chiavi su sitemi accessibili pubblicamente e utilizzate wipe o un software analogo [http://users.erols.com/thomassr/zero/download/wipe/ oppure http://gsu.linux.org.tr/wipe/] per _provare_ a cancellare "seriamente" i file. - Non fate girare stunnel sul server (neanche sui client sarebbe il caso :) con privilegi di root. Se intendete bindare stunnel su una porta privilegiata (<=1024) utilizzatelo da inetd oppure utilizzate un ambiente chroot (stunnel da solo non lo fa, vi servono software tipo authbind o simili) - In modalita' client, SPECIFICATE come ip da cui accettare le connessioni SEMPRE E SOLO 127.0.0.1 (localhost), altrimenti sara' possibile per chiunque possa raggiungere l'indirizzo ip pubblico della vostra macchina utilizzarla come "bouncer" per accedere al servizio protetto. Se ci sono altri utenti che utilizzano la vostra macchina, utilizzate l'identd (opzione -u di stunnel) oppure hosts.deny e/o hosts.allow. - Se sul server intendete lasciare accessibile un servizio SOLAMENTE tramite stunnel e lo utilizzate per accettare connessioni da remoto e "rigirarle" verso una porta locale, RICORDATEVI di chiudere la porta "reale" a chiunque non sia 127.0.0.1 tramite firewall o tcp_wrappers (o tutti e due :) - se avete utenti con accesso locale e volete comunque impedirgli di utilizzare quella risorse, "allora sono cavoli tuoi sorella"(*) - ehm, provate con l'identd (sui client reali, NON su stunnel, altrimenti autentichera' l'utente utilizzando l'identd remoto, che un eventuale assalitore puo' tranquillamente "falsificare") oppure con i parametri in hosts.deny e/o hosts.allow. Ovviamente se e' possibile spoofare dall'esterno come "127.0.0.1" queste precauzioni sono inutili (e i vostri problemi sono ben maggiori), ma per questo vi rimando al mio prossimo articolo sui firewall :) - Se avete paura che il Mossad o l'NSA possano intercettare le vostre comunicazioni, specificate nel server il parametro -C EDH-RSA-DES-CBC3-SHA (triple-des) o altre CipherSuite considerate "sicure". Questo parametro costringe il server a permettere la connessione solamente ai client che "accettino" questo grado di sicurezza e mette al riparo contro attacchi portati con client che forzino l'utilizzo di algoritmi meno solidi. Aumentate il valore di KEYLENGTH a 1024 o 2048 alla riga 29 si ssl.c e ricompilate/reinstallate stunnel - ovviamente e' anche il caso di rigenerare stunnel.pem con keylength RSA e DH maggiori di quelle di default (1024 e 512 bit rispettivamente). L'utlizzo di chiavi a 2048 bit provoca un aumento esponenziale delle risorse CPU utilizzate durante l'handshaking SSL e durante la generazione delle chiavi. Generare una chiave temporanea RSA a 2048 bit puo' richiedere piu' di un minuto anche su un PII 350 o macchina di eguale potenza; chiavi a 1024 bit vengono invece generate anche da un P100 in tempi accettabili (qualche secondo). Le chiavi a 512 bit sono generate praticamente istantaneamente. Generare uno "strong-prime" DH >512 bit puo' essere un processo che impegna PER ORE anche un server molto potente - "openssl speed" se volete generare qualche benchmark fuffa e vantarvi con gli amici al bar)... Ricordate comunque che se qualcuno intendesse realmente intercettare le vostre comunicazioni (anche disponendo delle risorse necessarie a "rompere" algoritmi di cifratura con chiavi giudicate oramai "insicure" - RSA 512 bit, p. es.) potrebbe probabilmente trovare sistemi MOLTO piu' semplici per penetrare nel vostro sistema (per esempio, studiare stunnel o openssl e trovare un exploit; exploitare altri servizi disponibili non protetti da accesso con certificati; corrompere vostra sorella, etc.). Trovo stunnel un ottimo sistema per proteggere comunicazioni che richiedano un basso livello di sicurezza, ma ritengo che non sia adatto nell'utilizzo in sistemi commerciali o in transazioni finanziare, etc. - Casco ben allacciato in testa, luci accese anche di giorno, e prudenza, sempre. - Non pensate comunque di farla in barba all'NSA. Lo chef consiglia: Personalmente utilizzo stunnel con il parametro KEYLENGTH modificato da 512 a 1024 alla riga 29 di ssl.c, e senza i commenti a #define NO_DH alla riga 25 dello stesso source. Come e' facile intuire, queste modifiche aumentano la lunghezza in bit della chiave RSA TEMPORANEA e disabilitano la possibilita' di usare il protocollo Diffie-Hellman per lo scambio delle chiavi. Inoltre utilizzo sempre l'autentificazone sia dai client (-v 2) che dei server (-v 3), con certificati a 2048 bit e forzo sempre l'utilizzo di CipherSuite "sicure" (-C DES-CBC3-SHA) in stunnel_server (che gira non-root, su porte <=1024, da inetd e con limitazione delle risorse CPU disponibili a stunnel tramite "quota", per evitare che un attacco portato con un numero molto elevato di connessioni sulla porta SSL provochi un sovraccarico eccessivo della CPU). Ovviamente sono preferenze dovute a paranoie personali... consiglio di effettuare qualche test per trovare i parametri migliori per le proprie necessita'. Qualche idea.. se proprio non sapete cosa tunnelare... Le possibilita' sono infinite.. cosi' a braccio me ne vengono in mente alcune: bnc, vnc, pop3, imap, smtp, sql, telnet, etc. Attivando un tunnel ssl con verifica dei certificati e chiudendo queste porte dall'esterno (escluso l'smtp), potete annullare la possibilita' per un eventuale malintenzionato di attaccare uno dei servizi (magari con privilegi root, tipo pop3d). Ovviamente e' sempre possibile ovviamente attaccare stunnel (hehe, Fusys ha promesso che fara' un auditing di sicurezza del source di stunnel per il prossimo numero.. stiamo a vedere :). Interessante e' anche la possibilita' di aprire una seconda porta per l'smtp (oltre a quella in chiaro, necessaria se il vostro server e' MX per qualche domain) a cui accedere solamente tramite certificati, ed utilizzarla per spedire posta ovunque (per esempio, se gradite utilizzare il vostro mail server anche da connessioni in dial-up, etc.) abilitando nell'stmpd il relay verso qualsiasi indirizzo dalle connessioni provenienti da 127.0.0.1 (mentre OVVIAMENTE dalle connessioni provenienti da indirizzi esterni accettera' posta SOLAMENTE verso i domain per cui e' MX). Contest: (*) - Chi indovina la citazione vince una bambolina.. (**) - Ja, e' proprio una citazione dallo stesso film... un aiutino.. John Candy (RIP, Sic!) mailto: vogliolabambolina@sikurezza.org Risorse: Altri tunnel ssl (sincerely - non ne ho provato nessuno): http://www.rickk.com/sslwrap/ - supporta ssleay e openssl (0.9.4 compresa) http://www.hitachi-ms.co.jp/bjorb/en/ - supporta ssleay http://www.multimania.com/jonama/ - supporta ssleay e openssl; funzioni di chroot per il daemon mode http://www.skygate.co.uk/safegossip/ - openssl - supporta PAM, ftp, telnet, smtp, etc. Altra documentazione interessante sull'argomento: http://www.openssl.org/related/ - partite da qui, e' una lista utilissima di risorse (sia link che software) http://www.psy.uq.oz.au/~ftp/Crypto/ - FAQ di ssleay.. purtroppo openssl non ha praticamente nessuna documentazione.. pero' e' basata su ssleay e qui potete trovare MOLTE cose interessanti, link compresi http://www.ietf.org: - Internet Engineering Task Force, cercate SSL o TLS come keyword per i titoli degli RFC e/o degli internet drafts.. Alcuni (ma sono tantissimi): RFC1421 - Privacy Enhancement for Internet Electronic Mail / Part I RFC1422 - Privacy Enhancement for Internet Electronic Mail / Part II RFC1423 - Privacy Enhancement for Internet Electronic Mail / Part III RFC2246 - The TLS Protocol Version 1.0 RFC2459 - Internet X.509 Public Key Infrastructure / Certificate and CRL Profile http://www.consensus.com/ietf-tls/ - IETF Transport Layer Security Working Group http://www.imc.org/ietf-pkix/ - IETF PKIX Working Group http://www.netscape.com/eng/ssl3/ - documentazione Netscape SSLv3 http://www.netscape.com/eng/security/SSL_2.html - documentazione Netscape SSLv2: http://www.consensus.com/security/ssl-talk-faq.html - SSL Talk FAQ http://www.ssh.fi/tech/crypto/ - Cryptography A-2-Z, dagli autori di ssh http://www.ssh.fi/tech/crypto/algorithms.html - breve introduzione alle tecniche di crittografia piu' utilizzate con descrizione dei vari algoritmi (per i frettolosi) http://www.rsasecurity.com/ - la compagnia fontada da Rivest, Shamir e Adleman, inventori dell'omonimo algoritmo (e numerosi altri) http://www.rsasecurity.com/rsalabs/faq/index.html RSA Laboratories Frequently Asked Questions About Today's Cryptography (ottima introduzione sulla crittografia e sui suoi utilizzi pratici) http://www.counterpane.com - homepage della Counterpane Systems, compania presieduta da Bruce Schneier, guru della crittografia e inventore dell'algorito Blowfish; contiene numerosissimi link "crypto-related" http://www.counterpane.com/applied.html - libro "Applied Cryptography" dello stesso Schneier, per quelli che vogliono sapere TUTTO sull'argomento :) http://www.openca.org - progetto per implementare (utilizzando openssl) un software avanzato di gestione CA. Attualmente ancora agli albori.. Nota. Il progetto e' sviluppato da italiani e ospitato presso il server del Comune di Modena http://www.progressive-comp.com/Lists/?l=stunnel-users&r=1&w=2#stunnel-users mirror della mailing list stunnel-users Disclaimer: Questo documento e' composto di pure allucinazioni e fantasia.. blah blah qualsiasi dato riportato e' assolutamente casuale e frutto di perversione intellettuale blah blah. NON MI RITENGO ASSOLUTAMENTE RESPONSABILE ne' di quanto scritto ne' dell'utilizzo che ne farete blah blah blah... (se vi bucano perche' avete usato stunnel, non venite a rinfacciarmelo - se vi bucano perche' NON avete usato stunnel, ibidem). Se avete trovato il tono utilizzato troppo "gigionesco" e/o "ciarliero" ed avete trovato i termini utilizzati offensivi per qualcuno o qualcosa... beh, mi dispiace, sono tuttavia convinto che si possano scrivere documenti, how-to et altro anche utilizzando una terminologia et una sintassi leggermente meno pallosa di quella contenuta tradizionalmente in questo tipo di documenti, senza comunque sminuirne il contenuto. La riproduzione di questo documento o sua parte blah blah e' ASSOLUTAMENTE PERMESSA su qualsiasi mezzo o intero blah blah - SEMPRE CHE SIANO SEMPRE CITATI SEMPRE L'AUTORE (Kobaiashi) e SEMPRE LA FONTE (BFi, http://www.s0ftpj.org) blah blah blah... SEMPRE Tutti i registri marchiati [ehm] tutti i citi registrati si insomma tutti i mostri nominati sono proprieta' dei legittimi registrati [ehm] si insomma blah blah. Siete liberi (ed invitati) comunque ad indicarmi eventuali inesattezze e schifezze ivi contenute e le vostre particolari paranoie e problematiche di utilizzo di stunnel ad uno dei miei molteplici indirizzi di posta: koba@s0ftpj.org koba@sikurezza.org koba@microsoft.com (uno di questi 3 indirizzi e' palesemente falso - indovinate quale ;) Baci e abbraci. Koba ============================================================================== --------------------------------[ EOF 15/22 ]--------------------------------- ============================================================================== ---------------------[ previous ]---[ index ]---[ next ]----------------------