V predchádzajúcom príspevku sme úspešne vygenerovali SSL certifikát. Ten sme úspešne nasadili na server a ani sme sa nenazdali, platnosť certifikátu vypršala. O blížiacom sa okamihu nás certifikačná autorita CAcert.org pekne upozorňovala, ale nebol čas certifikát aktualizovať.
Prax ukázala, že je dobré mať na každý certifikát samostatný adresár, ktorý ma jednoznačný názov. Aby sme sa vyhli zmenám v konfiguračnom súbore pri zmene certifikátov, zvyknem mať v konfiguračnom súbore nastavenú takú cestu, ktorá je iba symbolickým odkazom. Symbolický odkaz ukazuje vždy na to správne miesto a tak nemusím konfiguračný súbor meniť. Aby to bolo jasnejšie, pre nginx mám SSL certifikáty v takejto štruktúre:
mkdir -p /etc/nginx/ssl/uptime.sk-cacert-0DAFF1/ cd /etc/nginx/ssl ln -s uptime.sk-cacert-0DAFF1/uptime.sk.key ln -s uptime.sk-cacert-0DAFF1/uptime.sk.pem
Ešte si udržiavam certifikáty certifikačnej autority CAcert priamo na disku:
cd /etc/nginx/ssl for cert in root.crt class3.crt; do wget -O "cacert.org-$cert" "https://www.cacert.org/certs/$cert"; done
Mať takto uložené certifikáty je síce pekné, ale udržiavať to manuálne by bola strata času. Ale ako som zistil, za pomoci nástrojov OpenSSL to ide krásne automatizovať. Takže vznikol skript, ktorý uvádzam na konci článku.
Skript si sám zistí parametre priamo z vygenerovaného SSL certifikátu a uloží ho v požadovanom tvare. Jediné, čo je potrebné spraviť je copy&paste.
Zistenie sériového čísla SSL certifikátu, subjektu, fingerprintu atď je jednoduché:
NIECO=uptime.sk openssl x509 -in "$NIECO.pem" -noout -serial | \ awk -v FS='=' '{ print $2 }' openssl x509 -in "$NIECO.pem" -noout -subject | \ awk -v FS='=' '{ sub("*.", "", $3); print $3; }'
A na koniec uvádzam kompletný skript na aktualizáciu SSL certifikátov. Ten si uložte napríklad ako ja do súboru /etc/nginx/ssl/update-cacert-certificate.sh
Update: aktuálnu verziu skriptu nájdete na github.com.
#!/bin/sh # # update-cacert-certificate.sh # # Developed by Lubomir Host <lubomir.host@gmail.com> # Licensed under terms of GNU General Public License. # All rights reserved. # # Changelog: # 2013-08-19 - created # for cakey in class3.crt root.crt; do echo "Checking 'cacert.org-$cakey'" if [ ! -f "cacert.org-$cakey" ] || [ ! -s "cacert.org-$cakey" ]; then echo "\t'cacert.org-$cakey' is missing, downloading" wget -O "cacert.org-$cakey" "https://www.cacert.org/certs/$cakey" && \ openssl x509 -in "cacert.org-$cakey" -fingerprint -text -out - | head -n 9 fi done echo "Go to https://www.cacert.org/account.php?id=12 (MyAccount --> Server Certificates --> View) and click 'Renew' for your certificates" echo "Then wait for the output from web and copy&paste output here:" TEMP=`mktemp` #@echo tmp=$TEMP trap "rm -f '$TEMP'" 1 2 3 15 cat > $TEMP echo ----------------------------- echo "Your NEW certificate is" openssl x509 -in "$TEMP" -noout -subject -serial -fingerprint || exit 3 echo ----------------------------- fingerprint=`openssl x509 -in "$TEMP" -noout -fingerprint | awk -v FS='=' '{ print $2 }'` serial=`openssl x509 -in "$TEMP" -noout -serial | awk -v FS='=' '{ print $2 }'` subject=`openssl x509 -in "$TEMP" -noout -subject | awk -v FS='=' '{ sub("*.", "", $3); print $3; }'` pem_file="$subject.pem" key_file="$subject.key" if [ ! -f "$pem_file" ] || [ ! -f "$key_file" ]; then echo "Files '$pem_file' and '$key_file' doesn't exists ==> nothing to update"; exit 2 fi echo ----------------------------- echo "Your PREVIUS certificate is:" openssl x509 -in "$pem_file" -noout -subject -serial -fingerprint || exit 4 echo ----------------------------- echo -n "Update this certificate? [y/N] " read answer case $answer in [yY]) echo "OK, updating key for '$subject'" ;; *) echo "Nothing to do, exiting..." exit 5; esac outdir="$subject-cacert-$serial" mkdir "$outdir" || exit 6 openssl x509 -in "$TEMP" -out "$outdir/$subject.pem" || exit 7 #cat cacert.org-root.crt cacert.org-class3.crt >> "$outdir/$subject.pem" || exit 8 cat cacert.org-root.crt >> "$outdir/$subject.pem" || exit 8 # keep and duplicate keyfile cp -p `readlink "$subject.key"` "$outdir/$subject.key" || exit 11 for certfile in "$subject.pem" "$subject.key"; do if [ -L "$certfile" ]; then echo "Creating symlink to '$outdir/$certfile'" ln -s -f "$outdir/$certfile" || exit 10 fi done rm -f "$TEMP"