I'm working on the deployment of our LetsEncrypt SSL certificates. I have cron jobs that run daily and renew the certificatse if needed using certbot. I also have a script that will deploy the certificate to the load balancer.
Certbot has a deploy callback when a cert is renewed. Certbot will call my script immediately after renewing a certificate. That seems to work fine -- mostly. However, if the deployment fails for any reason, I'd like it to try again the next day. It doesn't look like there is any functionality built into certbot for this.
How do I implement a script that has the following logic:
if [ /etc/letsencrypt/live/example.com/cert.pem != certfrom https://example.com/ ]
then
example.com-cert-deploy.sh
fi
Вы можете использовать что-то вроде:
$ openssl s_client -showcerts -servername example.com -connect example.com:443 </dev/null
... который, помимо прочего, будет выводить сертификат сервера. Вы можете проанализировать его, сохранить, а затем сравнить с другим сертификатом на диске.
Достаточно сравнить «отпечаток пальца» локального сертификата с действующим сертификатом.
Два отпечатка пальца можно получить с помощью следующих двух команд:
openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -fingerprint -noout
echo | openssl s_client -showcerts -connect example.com:443 -servername example.com 2> & 1 | openssl x509 -fingerprint -noout
Чтобы упростить сравнение, я поместил их в скрипт с проверкой ошибок. Он принимает доменное имя в качестве аргумента и завершает работу со статусом сбоя, если они отличаются. Его можно использовать как:
if ! ./lets-encrypt-installed-test.sh --quiet example.com
then
./example.com-cert-deploy.sh
fi
Вот полное содержание скрипта:
#!/bin/sh
set -e
quiet=0
for var in "$@"
do
case "$var" in
-q)
quiet=1
;;
--quiet)
quiet=1
;;
-*)
echo "Unexpected argument $var" >&2
exit 1
;;
*.*)
domain="$var"
;;
*)
echo "Expected argument $var" >&2
exit 1
;;
esac
done
if [ "z$domain" == "z" ]
then
echo "Expected domain as parameter to $0" >&2
exit 1
fi
lefile="/etc/letsencrypt/live/$domain/cert.pem"
if [ ! -e $lefile ]
then
echo "Lets Encrypt file does not exist: $lefile" >&2
exit 1
fi
leprint=`openssl x509 -in $lefile -fingerprint -noout`
case "$leprint" in
*Fingerprint*)
;;
*)
echo "No fingerprint from $lefile" >&2
exit 1
;;
esac
liveprint=`echo | openssl s_client -showcerts -connect "$domain":443 -servername "$domain" 2>&1 | openssl x509 -fingerprint | grep -i fingerprint`
case "$liveprint" in
*Fingerprint*)
;;
*)
echo "No fingerprint from SSL cert of https://$domain/" >&2
exit 1
;;
esac
if [ "$leprint" != "$liveprint" ]
then
if [ "$quiet" == "0" ]
then
echo "Fingerprints for local and remote SSL certificates differ:" >&2
echo "$lefile: $leprint" >&2
echo "https://$domain/: $liveprint" >&2
fi
exit 1
fi
exit 0