Autoritat certificadora (openssl)

Objectiu:

Aquest tutorial explica com configurar una autoritat certificadora molt simple utilitzant openssl. El que cerquem és la possibilitat de crear la nostra Autoritat Certificadora i a la vegada generar certificats X.509 per utilitzar en els diferents serveis que anem incorporant al nostre servidor i que requereixin de xifratge SSL/TLS.

Què és una autoritat certificadora (CA)?

Sempre que s’estableix una connexió segura entre dues parts d’un sistema informàtic, utilitzant certificats X.509 es produeix una verificació de les dades d’aquests certificats. En el fons (gens rigorós, ho sé!) un certificat conte la clau pública d’un usuari. Aquesta clau pública s’utilitza per xifrar converses entre serveis o programes. Ens interessa poder crear una jerarquia de certificats per l’empresa. Una mica dient que existeix un certificat arrel del que la resta en depenen. D’aquesta manera es pot verificar la ruta de certificació d’un certificat i comprovar qui la emès, a quina empresa pertany, l’usuari o servei que l’utilitza, etcètera.

Obtenció del software necessari:

Partim de la base que disposem d’un servidor amb Ubuntu 7.04 Server. És molt probable que aquest tutorial funcioni sobre d’altres distribucions, però ha estat provat principalment sobre Ubuntu.

Utilitzarem l’eina apt per aconseguir el software necessari. S’ha entrat al sistema utilitzant l’usuari root.

Per començar actualitzem les nostres fonts de apt.

$ apt-get update

Per instal·lar el paquet de l’OpenSSL executarem la següent comanda:

$ apt-get install openssl

Amb aquest paquet n’hi ha prou. Per defecte els arxius de configuració d’OpenSSL s’instal·len a la carpeta /etc/ssl. El que volem configurar és /etc/ssl/openssl.cnf.

Aquests arxiu conté tota la informació de com es generaran els certificats, tant els auto-signats com els que depenen de la CA.

Configuració:

A continuació mostro el contingut del fitxer openssl.conf que ens interessa tenir. Podem fer una copia de l’original abans de sobreescriure’l.

$ cp -v /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.orig

El contingut modificat del nostre és:

HOME = .
RANDFILE = $ENV::HOME/.rnd

[ ca ]
default_ca = CA_default

[ CA_default ]
dir = ./CA
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts

certificate = $dir/ca.crt
serial = $dir/serial
crlnumber = $dir/crlnumber
private_key = $dir/private/ca.key
RANDFILE = $dir/private/.rand

x509_extensions = usr_cert

default_days = 365
default_crl_days= 30
default_md = sha256
preserve = no

policy = policy_match

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ req ]
default_bits = 2048
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca

string_mask = nombstr

req_extensions = v3_req

[ req_distinguished_name ]
countryName = Nom del país (codi de 2 lletres)
countryName_default = AD
countryName_min = 2
countryName_max = 2

stateOrProvinceName = Estat o província
stateOrProvinceName_default = Una província
localityName = Localitat

0.organizationName = Organització
0.organizationName_default = Una organització

organizationalUnitName = Secció

commonName = Nom comú
commonName_max = 64

emailAddress = Correu electrònic
emailAddress_max = 64

[ req_attributes ]
challengePassword = Una contrasenya
challengePassword_min = 4
challengePassword_max = 20

unstructuredName = Un nom de companyia opcional

[ usr_cert ]
basicConstraints = CA:FALSE
nsCertType = server
# nsCertType = objsign
# nsCertType = client, email
# nsCertType = client, email, objsign
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
nsComment = "Certificat generat amb OpenSSL"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
subjectAltName=${ENV::SAN}

[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName=${ENV::SAN}

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer:always
basicConstraints = CA:true

Tot i semblar molt llarg i complex, la veritat és que no l’haurem de tocar massa més, només potser, per adaptar les cadenes al català.

Ja podem crear el nostre primer certificat, el de l’arrel.

Creació de certificats auto-signats. L’arrel.

Molt sovint els certificats arrel són auto-signats ja que no tenim ningú per sobre que ens el pugui signar, d’aquí que es diguin arrel.

OpenSSL conté moltes opcions i funcionalitats que no són de l’estudi d’aquest tutorial, si necessiteu més informació al respecte d’alguna funció en concret sempre podeu consultar el manual:

$ man openssl

Dels moduls que incorpora OpenSSL utilitzarem el req de la següent manera:

$ openssl req -x509 -days 3650 -newkey rsa:2048 -keyout ca.key -out ca.crt

Amb això, i després de respondre a les dades que ens anirà demanant, tindrem un certificat arrel anomenat ca.crt i una clau secreta ca.key.

Per verificar la informació continguda en el certificat podem fer:

$ openssl x509 -in ca.crt -text -noout

La informació que ens mostra inclou tot el que s’ha demanat. És important l’atribut CA:TRUE, on indica que és una autoritat certificadora. Ara, amb aquest certificat i la clau secreta ja podem signar els certificats que utilitzarem en d’altres serveis.

Entorn de treball:

Per generar i signar aquests fills crearem primer un entorn de treball:

$ cd /etc/ssl
$ mkdir -p CA/{certs,private,newcerts}
$ cd CA
$ chmod g-rwx,o-rwx private
$ echo '01' > serial
$ touch index.txt

Amb aquestes comandes hem creat una estructura de directoris on es guardaran tots els certificats que creem a partir d’ara. A continuació copiem la CA arrel que hem generat abans a la nova estructura de directoris:

$ cd /etc/ssl
$ mv ca.crt CA/
$ mv ca.key CA/private/

Petició de certificats. Request.

IMPORTANT: Abans de fer una petició de certificats s’ha d’executar el següent per configurar el subjectAltName (requeriments de Chrome 58+):

$ export SAN=DNS:server.domain.com

Anem ja doncs a generar la primera petició de certificat per a que la signi la nostra CA. Això ho podem fer amb la següent comanda:

$ openssl req -newkey rsa:2048 -keyout cert.key -out cert.req -utf8 -config openssl.cnf -sha256 -nodes

Durant la creació de les claus ens demanarà una contrasenya dues vegades. Hem sel·leccionat secret. De totes les dades que se’ns demanaran la més important és el nom comú (o Common Name). Aquest nom és el que identifica a la persona del certificat (p.ex: nom d’usuari) o bé al servidor (p.ex: www.domini.local). S’ha de triar en consonància a la funció que realitzarà el certificat.

Aquesta darrera comanda ha generat dos arxius, la clau cert.key i la petició cert.req.

Signar certificats.

Ja només queda que la CA accepti la petició i tindrem el nostre certificat per utilitzar-lo on ens faci falta. La comanda per signar la petició és:

$ openssl ca -in cert.req -out cert.crt -utf8 -config openssl.cnf

Se’ns demanarà si estem segurs de signar el certificat. Respondrem que sí. Un cop acceptat ja tenim el nostre certificat, que s’anomena cert.crt. Els dos arxius que ens faran falta per a configurar serveis són cert.key i cert.crt, s’han de guardar bé. L’arxiu cert.req no el farem servir més, es pot eliminar.

Per acabar podem verificar el nou certificat a veure si és correcte:

$ cd /etc/ssl
$ openssl verify -CAfile CA/ca.crt cert.crt
cert.crt: OK

Crear arxius pkcs12.

Aquest tipus d’arxius són com contenidors de claus, certificats i demés i son útils per què només tenim un fitxer amb una contrasenya i la resta es gestiona sol.

Per crear un arxiu pkcs12 de nou que contingui els arxius de la CA, la clau i el certificat d’usuari podem fer:

$ openssl pkcs12 -export -in cert.crt -inkey cert.key -certfile CA/ca.crt -out cert.p12

Renovar certificats.

Amb el temps els certificats que acabem de crear caducaran. A continuació es mostra com renovar els certificats signats per l’autoritat.

En l’arxiu index.txt es guarda la informació dels certificats emesos, i en la carpeta certs/ es guarda una còpia d’aquests certificats en format XX.pem on XX és el número de sèrie del certificat.

Per renovar un certificat, doncs, el primer que s’ha de fer és revocar el vell si aquest no ha caducat, és clar:

$ openssl ca -revoke certs/XX.pem -config openssl.cnf

El número de sèrie el trobarem en l’arxiu index.txt. Un cop revocat ja podem crear una nova petició, com s’ha explicat abans i signar-la amb la CA.