giovedì 3 dicembre 2009

Certification authority? Certo, sulla Linux Box

Benissimo, se siete qui a leggere vuole dire che vi servivano informazioni su questo argomento, oppure vi sono piaciuti i post precedenti... io spero la seconda, logicamente per soddisfare un po' il mio ego.
Ora veniamo a noi ed alla breve spiegazione teorica... quando si parla di garantire trasmissioni sicure, si vuole ottenere un sistema che sia in grado di realizzare uno o più dei seguenti requisiti:
  • riservatezza/confidenzialità;
  • integrità;
  • autenticità;
  • non ripudio.
Lo scopo viene ottenuto grazie all'utilizzo della crittografia con il sistema delle chiavi pubblica/privata. Questo sistema viene realizzato attraverso i certificati X.509, che realizzano una struttura gerarchica, con sviluppo ad albero, i cui elementi sono legati tramite un rapporto di fiducia, ovvero il "padre" garantisce che i suoi "figli" sono coloro che dicono di essere (autenticità), mentre le parti di integrità, riservatezza e non ripudio sono garantite dalla crittografia legata all'utilizzo delle due chiavi. Logicamente, come dicono i nomi, la chiave pubblica può e deve essere distribuita per poter stabilire se un determinato messaggio è firmato dalla relativa chiave privata o, nel caso di utilizzo della crittografia, per poter crittografare il messaggio che verrà poi decifrato attraverso l'uso della chiave privata. Dietro a tutto questo ci sono molti concetti matematici, che se volete potete cercare e studiare, ma questo esula sicuramente da quello che voglio dirvi.
La parte pratica viene gestita nella seguente maniera:
  1. Il figlio genera la richiesta di certificato.
  2. Il padre firma la richiesta di certificato del figlio, tramite un certificato valido.
  3. La richiesta di certificato firmata diventa certificato e viene assegnato al figlio.
  4. Chiunque riconosce l'autorità del padre, automaticamente riconosce anche quella del figlio.
Chi ha spirito pratico, in tutto questo si sarà accorto di una cosa, e si chiederà: "e chi ha firmato il certificato del padre? il nonno? e chi quello del nonno?" e così via. Logicamente qui ci troviamo al discorso del "è nato prima l'uovo o la gallina?", ma la risposta è molto più semplice: il primo certificato si chiama self-signed, ovvero è un certificato autofirmato in cui il firmatario garantisce di essere chi dice di essere. Da un certificato di questo tipo possiamo far nascere la nostra CA, ovvero una certification authority, i cui "figli" saranno riconosciuti da chi ha considerato autorevole il certificato del padre, ovvero quello originario della nostra CA.
La gestione dei certificati all'interno di una linux box ricopre una parte vastissima perchè riguarda tutte le comunicazioni che si vogliono rendere sicure, e pensando alla sicurezza, sono aspetti imprescindibili e molto profondi, quindi conviene impararla velocemente, mettendo i puntini sulle "i" fin dall'inizio ed apprendendo tutto quello che serve. Il mio scopo è darvi delle brevi e semplici informazioni e molti dei comandi utili sotto forma di script, questo al fine di aiutarvi ad addentrarvi in openssl da subito... logicamente, come il solito, dove non arrivano le mie spiegazioni ci arriveranno quelle di qualcun altro che ha scritto un help, un howto o della documentazione varia resa disponibile attraverso internet.
Passando alla configurazione pratica, prima di tutto ci serve installare l'ambiente ed i comandi che ci serviranno per la nostra CA, quindi:
  • aptitude install openssl;
A questo punto a livello di comandi e configurazione avremo tutto quello che ci serve, ora dobbiamo solamente personalizzarlo modificando il file openssl.cnf (normalmente in /etc/ssl o /etc/pki/tls per le distribuzioni basate su RedHat) affinchè rispecchi i propri bisogni... io utilizzo i seguenti parametri (in Debian):
  • dir = /etc/ssl/YOUR_CA
  • private_key = $dir/private/cakey.unsec.pem # se la chiave non ha password
  • private_key = $dir/private/cakey.pem # se la chiave ha password
  • countryName_default = IT
  • stateOrProvinceName_default = Turin
  • localityName_default = Turin
  • 0.organizationName_default = YOUR organization
  • organizationalUnitName_default = host.domain from YOUR_CA
  • commonName = Common Name (eg, YOUR name as host or IP)
  • emailAddress_default = YOUR email address
  • challengePassword_default = longpasswordyouwant
Questi parametri presuppongono alcune strutture che io do per scontate nelle mie configurazioni e sono:
  • i percorsi a cui si fa riferimento in /etc/*/openssl.cnf sono di tipo assoluto;
  • la struttura della CA è locata all'interno di una directory del tipo /etc/*/CA;
  • il file openssl.cnf è nella stessa directory in cui vi è la CA;
  • il nome della CA viene utilizzato anche per il nome del certificato;
  • gli hash del certificato della CA vengono messi in /etc/*/certs.
A questo punto dobbiamo creare una struttura che ci permetta di svolgere i ruoli di una CA, ovvero coppia di chiavi pubblica/privata, un percorso in cui andare a salvare le richieste di certificato per elaborarle e trasformarle in certificato ed alcuni file necessari per la gestione "logica" della CA, compresa la CRL (Certificate Revocation List).
Il seguente script, da mettere in /etc/*/makeCA.sh, attingendo dai parametri immessi in openssl.cnf, prepara la struttura necessaria ad ospitare la CA.

#!/bin/bash

# Script per creazione della CA
opensslConf=$(find /etc -iname openssl.cnf|sort|head -1);
dir=$(grep "^[[:space:]]*dir[[:space:]]*=" ${opensslConf} | sed "s/[[:space:]]*dir[[:space:]]*=[[:space:]]*\([^[:space:]]*\)[[:space:]]*.*/\1/");
certificate=$(grep "^[[:space:]]*certificate[[:space:]]*=" ${opensslConf} | sed -e "s/[[:space:]]*certificate[[:space:]]*=[[:space:]]*\([^[:space:]]*\)[[:space:]]*.*/\1/" -e "s|\$dir|$dir|");
private_key=$(grep "^[[:space:]]*private_key[[:space:]]*=" ${opensslConf} | sed -e "s/[[:space:]]*private_key[[:space:]]*=[[:space:]]*\([^[:space:]]*\)[[:space:]]*.*/\1/" -e "s|\$dir|$dir|");
mkdir -pm 755 ${dir};
mkdir -pm 755 ${dir}/{certs,crl,newcerts};
mkdir -pm 700 ${dir}/private;
touch ${dir}/index.txt;
touch ${dir}/private/.rand;
echo 01 > ${dir}/serial;
echo -n "Vuoi generare una chiave privata senza password? (s/N) ";
read ANS;
case ${ANS} in
"S"|"s"|"Y"|"y") echo "Attenzione, la chiave privata sara' leggibile da chiunque!";
openssl genrsa -out ${private_key} 2048;
;;
"N"|"n"|"") echo "Attenzione, ad ogni accesso alla chiave privata si dovra' fornire la password!";
openssl genrsa -des3 -out ${private_key} 2048;
echo "Per la rimozione della password usare il seguente comando: openssl rsa -in ${private_key} -out ${private_key}.unsec";
;;
esac
openssl req -config ${opensslConf} -new -x509 -key ${private_key} -out ${certificate} -text -days 2922;
hash=$(openssl x509 -noout -in ${certificate} -hash);
ln -sf ${certificate} $(dirname ${dir})/$(basename ${dir}).crt;
ln -sf ${certificate} $(dirname ${dir})/certs/${hash}.0;

Ora la nostra CA è pronta a fare il suo dovere e mancano solamente più i certificati "figli".
Per scoprire come creare e gestire i certificati continuate a seguirmi, e vi fornirò le informazioni necessarie ad essere operativi... alla prossima!

Nessun commento:

Posta un commento