Aktualizácia SSL certifikátov

Aktualizácia SSL certifikátu metódou copy&paste

Aktualizácia SSL certifikátu metódou copy&paste

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.

 

Aktualizácia SSL certifikátu metódou copy&paste

Aktualizácia SSL certifikátu metódou 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"