Eigen ca

Al een tijdje loop ik met het idee om een eigen ca te gaan gebruiken. Voor mijn eigen sites vind ik het zonde van het geld om een duur certificaat van een officiele provider aan te schaffen. Mijn eigen ca zit weliswaar niet in elke browser, maar elke bezoeker kan wat mij betreft prima voor zichzelf uitmaken of hij mij vertrouwt ja of nee. Enige dat ik nodig heb is standaard aanwezig op bijna elke unix c.q. linux machine, namelijk Openssl.

Opzetten basisstructuur

Allereerst de opzet van de directory structuur en het aanmaken van de benodigde bestanden. Op zich maakt het niet uit waar het staat. Ik heb er voor nu voor gekozen om het in een subdirectory van de home van root te doen.

# mkdir /root/ssl/ca
# mkdir /root/ssl/ca/certs
# mkdir /root/ssl/ca/private
# mkdir /root/ssl/ca/requests
# touch certindex.txt
# echo '100001' > /root/ssl/ca/serial
# cp /etc/ssl/openssl.cnf /root/ssl/ca/openssl.cnf
# chmod -R 0700 /root/ssl/ca/

Wijzig hierin in ieder geval de volgende variabelen naar de voor u correcte waarden:

dir = /root/ssl/ca
database = $dir/certindex.txt
new_certs_dir = $dir/certs
certificate = $dir/certs/ca.crt
serial = $dir/serial
private_key = $dir/private/ca.key
default_days = 730
default_bits = 2048

Bij [ req_distinguished_name ] Vul de gewenste standaardwaarden in

Aanmaken ca private key en ca root certificaat

Nu we de basis hebben opgezet, kunnen we ons eigen root certificaat aanmaken.

/root/ssl/ca# openssl req -new -x509 -extensions v3_ca \
-keyout private/ca.key -out certs/ca.crt -days 3650 -config ./openssl.cnf

Belangrijk is om bij de common name een herkenbare tekst in te vullen, bijvoorbeeld de eigen naam. Het hoeft geen url te zijn. De naam die we hier invullen, is zichtbaar in de browser als we de lijst met gecertificeerde organisaties bekijken.

Daarnaast is het van belang om een goede passphrase te kiezen als beveiliging voor de private key.

We hebben nu twee bestanden:

  • /root/ssl/ca/private/ca.key: de private key van het root certificaat dat niet in verkeerde handen mag vallen
  • /root/ssl/ca/certs/ca.crt: het root certificaat dat aan de browser wordt aangeboden

Aanmaken certificate request en private key

We hebben nu ons eigen root certificaat dat we kunnen gebruiken om de requests te ondertekenen. Dat doen we met de volgende opdracht:

/root/ssl/ca# openssl req -new -nodes -out requests/www.zomaarr.nl.csr \
-keyout private/www.zomaarr.nl.key -config ./openssl.cnf

Als alles goed gaat, hebben we twee bestanden:

  • /root/ssl/ca/requests/www.zomaarr.nl.csr: het request voor onze site
  • /root/ssl/ca/private/www.zomaarr.nl/key: de private key voor onze site

Ondertekenen certificate request

Nu zijn we zover dat we het request kunnen gaan ondertekenen:

/root/ssl/ca# openssl ca -out certs/www.zomaarr.nl.crt -config ./openssl.cnf \
-infiles requests/www.zomaarr.nl.csr

Omdat we nu de private key van ons root certificaat benaderen, wordt gevraagd om de passphrase die we hebben ingevuld.

We hebben nu een aantal nieuwe bestanden:

  • /root/ssl/ca/certs/www.zomaarr.nl.crt: het certificaat dat op de webserver geplaatst kan worden
  • /root/ssl/ca/certindex.txt: overzicht van de ondertekende requests
  • /root/ssl/ca/serial: dit bestand bevat het serienummer dat de eerstvolgende keer gebruikt gaat worden
  • /root/ssl/ca/100001.pem: voor elk ondertekende request wordt naast het bestand in de -out parameter, ook een certificaat aangemaakt met het serienummer in de naam

Al met al niet heel ingewikkeld, maar het is wel zaak om helder te hebben welk bestand waarvoor dient en een naamgeving te gebruiken die precies aangeeft waar elk bestand voor gebruikt wordt.

Natuurlijk kan het verder uitgebreid worden door een shell scriptje te maken dat als parameter de domeinnaam nodig heeft, zodat via een paar simpele Openssl opdrachten alles automatisch verloopt. Maar dat is voor een volgende keer.