Autorità di certificazione locale
Introduzione
L'utilizzo di un'autorità di certificazione locale (self signed CA) trova applicazione in tutti quei casi in cui non sia necessario che una root CA esterna firmi i nostri certificati.
Uno scenario tipico è quello in cui si voglia realizzare un sistema di autenticazione web basato su certificati: per autenticarsi i client devono presentare il certificato richiesto.
Illustrerò come generare una CA locale, come usarla per creare certificati lato server e lato client, infine mostrerò come revocare un certificato.
Installazione e Configurazione di Openssl
Per installare la libreria SSL e gli applicativi necessari alla creazione di chiavi e certificati dare il comando:
# apt-get install openssl
Per minimizzare la quantità di informazioni richieste durante la creazione di chiavi e certificati, può
essere utile modificare il file /etc/ssl/openssl.cnf
per esempio alla seguente sezione:
[ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = IT ... stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Italy ... 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Azienda SpA ...
Generazione di una CA locale
Per mezzo di questa autorità di certificazione saranno creati tutti gli altri certificati: quello del server e quelli dei client.
Creazione della chiave (root CA)
Prima del certificato è necessario creare una chiave. Il seguente comando genera nella directory /etc/openssl/private
la chiave privata ca.key
di 1024 bit criptata con algoritmo triple DES:
# openssl genrsa -des3 -out private/ca.key 1024 Enter pass phrase for private/ca.key: Verifying - Enter pass phrase for private/ca.key:
La chiave sarà generata dopo aver immesso la pass phrase.
ATTENZIONE vista l'importanza della chiave privata a livello sicurezza, dare gli opportuni permessi alla directory /etc/openssl/private e a ca.key .
|
Generazione del certificato (root CA)
Prima di procedere assicurarsi che /etc/ssl/index.txt
sia vuoto e che /etc/ssl/serial
contenga il valore 01.
Utilizziamo la chiave creata nella sezione Creazione della chiave (root CA), per generare un certificato root CA ca.crt
con validità di un anno:
# openssl req -config /etc/ssl/openssl.cnf -new -x509 -key private/ca.key -out ca.crt -days 365 Enter pass phrase for private/ca.key:
Il certificato appena creato sarà utilizzato esclusivamente per firmare tutti gli altri certificati generati in seguito.
Affinché i browser possano riconoscere come valida la root CA appena creata, gli utenti finali dovranno installare il certificato ca.crt
nei loro browser. Riferirsi alla sezione Certificazione lato client per ottenere maggiori informazioni.
Aggiungendo l'opzione -batch
al precedente comando potremmo automatizzare l'operazione utilizzando i valori predefiniti impostati nel file /etc/ssl/openssl.cnf
. Utile quando il comando è utilizzato in uno script.
Certificato lato server
Questo è il certificato che il server utilizza per cifrare i dati scambiati con i vari client. Un tipico esempio è un server https.
Creazione della chiave (server)
Il modo in cui creare la chiave e le osservazioni da fare sono le stesse viste nella sezione Creazione della chiave (root CA):
# openssl genrsa -des3 -out private/server.key 1024 Enter pass phrase for private/server.key: Verifying - Enter pass phrase for private/server.key:
È molto probabile che la chiave generata sia poi utilizzata insieme al relativo certificato nella configurazione di apache; in tal caso apache attenderà ad ogni avvio che venga inserita la pass phrase relativa alla chiave utilizzata. Vista la scomodità di tale soluzione, si può togliere la pass phrase dalla chiave:
# openssl rsa -in private/server.key -out private/server.key.unsecure Enter pass phrase for private/server.key: writing RSA key
ATTENZIONE la chiave priva di pass phrase non è protetta, quindi assicurarsi che abbia i permessi opportuni. |
Generazione di una Certificate Signing Request (CSR)
Con la chiave creata nella sezione Creazione della chiave (server) generiamo una richiesta di firma per il certificato lato server che stiamo creando:
# openssl req -config /etc/ssl/openssl.cnf -new -key private/server.key -out server.csr Enter pass phrase for private/server.key:
Impartito il comando, è richiesta in input una serie di informazioni tra cui la più importante è quella relativa all'opzione commonName
in cui va specificato l'FQDN
del server che utilizzerà il certificato, al fine di evitare problemi di "fiducia" coi client.
Firma della CSR
Quando disponiamo di una CSR è necessario spedirla alla CA scelta affinché la firmi, tuttavia se abbiamo provveduto, come spiegato nella sezione Generazione di una CA locale, alla creazione di una nostra CA , possiamo firmare noi la CSR ottenuta alla sezione Generazione di una Certificate Signing Request:
# openssl ca -config /etc/ssl/openssl.cnf -policy policy_anything -keyfile private/ca.key \ > -cert ca.crt -in server.csr -out certs/server.crt Enter pass phrase for private/ca.key:
Il risultato del precedente comando è il file /etc/ssl/certs/server.crt
, l'aggiornamento di /etc/ssl/index.txt
e di /etc/ssl/serial
. A questo punto il file server.csr
non è più necessario.
Il risultato dell'operazione è il certificato per mezzo del quale il server https cifrerà i dati scambiati con i client.
Configurazione Web Server
Prendo in considerazione solo la configurazione relativa ad apache , in particolare ad apache-ssl. Utilizzando apache con mod-ssl si dovrebbero ottenere risultati analoghi.
Direttive apache-ssl
Importanti sono le seguenti direttive:
- SSLCACertificatePath
- indica la directory dove sono contenuti certificati e CRL (Certificate Revocation List)
Esempio: SSLCACertificatePath /etc/ssl
- SSLCertificateFile
- indica il certificato lato server per mezzo del quale i dati vengono cifrati. Secondo quanto riportato in questa guida esso corrisponde al file
/etc/ssl/certs/server.crt
.
Esempio: SSLCertificateFile server.crt
- SSLCertificateKeyFile
- indica la chiave privata del certificato lato server. Secondo quanto qui riportato essa corrisponde al file
/etc/ssl/private/server.key
. Per maggiori informazioni vedere l'osservazione sulle chiavi private fatta nella sezione Certificato lato server.
Esempio: SSLCertificateKeyFile server.key
- SSLVerifyClient
- definisce la certificazione di cui i client necessitano per autenticarsi.
Esempio: SSLVerifyClient 2 #The client must present a valid certificate.
- SSLVerifyDepth
- nel nostro caso va impostata a 1 in quanto ci fidiamo solo di certificati firmati dalla nostra CA locale.
Esempio: SSLVerifyDepth 1
- SSLUseCRL
- i certificati client sono controllati basandosi sull'appropriata CRL. La CRL deve essere in formato PEM. è necessario un link simbolico alla CRL posto all'interno del percorso indicato dalla direttiva SSLCACerificatePath. Non prende argomenti. Il percorso della CRL è specificato da SSLCACertificatePath. I link simbolici alle CRL hanno la forma
<hash>.r<number>, dove <hash>
è l'hash del file contenente la CRL. La sezione Apache e CRL spiega come creare link simbolici di tale tipo.
Esempio: SSLUseCRL
- SSLOnRevocationSetEnv
- se il client presenta un certificato revocato, la sessione SSL è stabilita e la variabile indicata è impostata. L'idea è di gestire con uno script questo tipo d'errore. Per la descrizione delle altre direttive del tipo SSLOn*SetEnv riferirsi alla documentazione di apache.
Esempio: SSLOnRevocationSetEnv SSL_REVOKED
Apache e CRL
Questa sezione tratta della configurazione di apache-ssl per l'uso di CRL. Riferirsi a Revoca di un certificato e in particolare a Creazione e aggiornamento di una CRL.
Affinché apache-ssl sia informato sulla validità dei certificati, è necessario l'utilizzo delle direttive SSLCACertificatePath e SSLUseCRL. La prima indica il percorso in cui cercare la CRL, la seconda istruisce il demone a fare uso della CRL.
La CRL deve essere puntata da un link simbolico della forma <hash>.r<number>
presente all'interno del percorso indicato dalla direttiva SSLCACertificatePath (p.e. /etc/ssl
):
# cd /etc/ssl # hash=`openssl crl -hash -in crl/crl.pem -noout` # ln -sf crl/crl.pem $hash.r0 # ls -l $hash.r0 lrwxr-xr-x 1 root root 11 2004-09-24 10:41 bb6e3a6b.r0 -> crl/crl.pem
CA, certificati e CRL per virtual host
Tutte le direttive elencate nella sezione Direttive apache-ssl possono essere utilizzate nei contesti server config e virtual host.
La prima conseguenza è che si possono specificare CA, CRL e certificati distinti per ogni singolo host virtuale. La seconda conseguenza è che si può creare confusione tra le direttive nei contesti server config e virtual host. Si consideri una configurazione del tipo seguente:
[...] SSLOnRevocationSetEnv SSL_REVOKED [...] <VirtualHost x.y.z.w:443> SSLCACertificateFile /etc/ssl/virtual1/ca.crt SSLCertificateFile /etc/ssl/virtual1/certs/server.crt SSLCertificateKeyFile /etc/ssl/virtual1/private/server.key SSLCACertificatePath /etc/ssl/virtual1 SSLUseCRL [...] </VirtualHost>
Quando è revocato un certificato client relativo al virtual host x.y.z.w
, il risultato potrebbe non corrispondere a quanto voluto. Se si visitasse l'URL https://x.y.z.w
con il browser in cui è installato il certificato revocato, si noterebbe che l'accesso non verrebbe impedito. Questo accade perché SSLOnRevocationSetEnv SSL_REVOKED non nega l'accesso ai certificati revocati, ma imposta la variabile SSL_REVOKED a "YES" e la direttiva posta nel contesto server config ha valore anche per gli host virtuali.
La soluzione è quella di commentare la direttiva nel contesto server config e attivarla, se serve, per ogni singolo host virtuale.
Certificato lato client
I passi da seguire per la creazione dei certificati lato client sono essenzialmente analoghi a quelli illustrati nella sezione Certificato lato server.
Creazione chiave (client)
Prima di tutto generiamo la chiave. La pass phrase utilizzata servirà all'utente finale per autenticarsi nelle zone protette del server web.
# openssl genrsa -des3 -out private/client1.key 1024 Enter pass phrase for private/client1.key:
Generazione di una CSR per il client
# openssl req -config /etc/ssl/openssl.cnf -new -key private/client1.key -out client1.csr Enter pass phrase for private/client1.key:
Firma della CSR per il client
La CSR va firmata dalla nostra CA locale:
# openssl ca -config /etc/ssl/openssl.cnf -policy policy_anything -keyfile private/ca.key \ > -cert ca.crt -in client1.csr -out certs/client1.crt Enter pass phrase for private/ca.key:
a questo punto il file client1.csr
non è più necessario. Infine client1.crt
e client1.key
vanno messi in un unico file:
# cat private/client1.key > private/client1.pem # cat certs/client1.crt >> private/client1.pem
quindi generare il file PKCS da importare nel browser dell'utente finale:
# openssl pkcs12 -export -in private/client1.pem -out pkcs/client1.p12 -name "Certificato Client 1" Enter pass phrase for private/client1.pem: Enter Export Password: Verifying - Enter Export Password:
Ovviamente la pass phrase per /etc/ssl/private/client1.pem
è la stessa di /etc/ssl/private/client1.key
. La Export Password viene richiesta al momento dell'importazione del file PKCS nel client browser.
Importazione dei certificati
I certificati da importare nel browser secondo quanto fin qui descritto sono:
ca.crt
- certificato della CA locale, da importare nella sezione "Autorità". Serve per dare "fiducia" al sito web della LAN.client1.p12
- certificato dell'utente finale da importare nel browser.
Revoca di un certificato
Un certificato può essere revocato per vari motivi, tra cui i seguenti:
- unspecified motivazione non specificata.
- keyCompromise la chiave relativa al certificato è stata compromessa (p.e. è giunta nelle mani sbagliate).
- superseded il certificato è stato rimpiazzato.
Per un elenco esaustivo consultare la pagina del manuale openssl CA(1).
il seguente comando revoca il certificato certs/client1.crt:
# openssl ca -config openssl.cnf -revoke certs/client1.crt -crl_reason superseded Enter pass phrase for private/ca.key:
Il rudimentale database /etc/ssl/index.txt
è aggiornato marcando il certificato come revocato. Risultano revocati tutti quei certificati che in /etc/ssl/index.txt
presentano una lettera R come primo campo.
Creazione e aggiornamento di una CRL
Per conoscere quali certificati sono stati revocati, è necessario generare una CRL (Certificate Revocation List). Una CRL è una lista che dichiara quali certificati sono stati revocati e la motivazione della revoca.
# openssl ca -config openssl.cnf -gencrl -out crl/crl.pem
Il comando precedente crea una CRL in base alle informazioni contenute in /etc/ssl/index.txt
e deve essere impartito ogni volta che uno o più certificati sono revocati.
Dopo aver aggiornato una CRL, è sempre necessario riavviare apache-ssl per rendere effettivi i cambiamenti.
Per la configurazione di apache-ssl relativa all'uso delle CRL vedere la sezione Configurazione Web Server.
Autore: ~ Nicsar 05:00, 1 Nov 2006 (CST) (Nicola Sarobba)