script_refresh-proxied-certs: support multi-algo RSA/ECDSA
This commit is contained in:
parent
266b15b535
commit
d5bc036d26
1 changed files with 42 additions and 9 deletions
|
@ -6,6 +6,12 @@
|
|||
# Typical arborescence is :
|
||||
# /etc/ssl/proxy-certs/www.foobar.com.crt
|
||||
# /etc/ssl/proxy-certs/www.foobar.com.key
|
||||
#
|
||||
# It supports RSA/ECDSA duo :
|
||||
# /etc/ssl/proxy-certs/www.foobar.com.sigalg-rsa.crt
|
||||
# /etc/ssl/proxy-certs/www.foobar.com.sigalg-rsa.key
|
||||
# /etc/ssl/proxy-certs/www.foobar.com.sigalg-ecc.crt
|
||||
# /etc/ssl/proxy-certs/www.foobar.com.sigalg-ecc.key
|
||||
#
|
||||
# note : don't forget to make the webserver reload the new certificates.
|
||||
|
||||
|
@ -15,37 +21,64 @@ set -e
|
|||
EXIT_STATUS=0
|
||||
TMPFILE="$( mktemp )"
|
||||
|
||||
for i in *.crt; do
|
||||
FQDN_HOSTNAME="$( echo $i | sed 's/\.crt$//' )"
|
||||
for i in *.key; do
|
||||
# Filename may be in the form :
|
||||
# - www.foobar.com.key
|
||||
# - www.foobar.com.sigalg-rsa.key
|
||||
# - www.foobar.com.sigalg-ecc.key
|
||||
BASENAME="$( echo "$i" | sed 's/\.key$//' )"
|
||||
FQDN_HOSTNAME="$( echo "$BASENAME" | sed 's/\.sigalg-.*$//' )"
|
||||
SIGALG="$( echo "$BASENAME" | sed -n 's/.*sigalg-\(.*\)$/\1/p' )" # 'rsa', 'ecc' or ''
|
||||
|
||||
# We don't refresh when there is a certificate request:
|
||||
# those are locally served websites
|
||||
if [ ! -f "$FQDN_HOSTNAME.csr" ] && [ "$FQDN_HOSTNAME.key" ]; then
|
||||
if [ ! -f "$BASENAME.csr" ] && [ ! -f "$BASENAME.req" ]; then
|
||||
# Prepare sigalg/ciphers options
|
||||
case "$SIGALG" in
|
||||
'ecc')
|
||||
SIGALG_OPTIONS="-tls1_2 -cipher ECDSA"
|
||||
;;
|
||||
'rsa')
|
||||
SIGALG_OPTIONS="-tls1_2 -cipher RSA"
|
||||
;;
|
||||
'')
|
||||
SIGALG_OPTIONS=""
|
||||
;;
|
||||
?)
|
||||
echo "ERROR: unknown sigalg." >&2
|
||||
EXIT_STATUS=1
|
||||
# This may not be critical. We continue, hoping for the best...
|
||||
SIGALG_OPTIONS=""
|
||||
;;
|
||||
esac
|
||||
|
||||
# Fetch the certificate from the origin server and store
|
||||
# in a temporary file.
|
||||
openssl s_client \
|
||||
-showcerts \
|
||||
-servername "$FQDN_HOSTNAME" \
|
||||
-connect "$FQDN_HOSTNAME:443" < /dev/null 2>/dev/null | \
|
||||
-connect "$FQDN_HOSTNAME:443" $SIGALG_OPTIONS < /dev/null 2>/dev/null | \
|
||||
sed -n '/^-----BEGIN CERTIFICATE-----$/,/^-----END CERTIFICATE-----$/p' > "$TMPFILE"
|
||||
|
||||
# Check that the new cert still match the local key
|
||||
# (it should also fail safely when the host wasn't reachable)
|
||||
if [ "$( ( openssl x509 -noout -modulus -in "$TMPFILE"; openssl rsa -noout -modulus -in "$FQDN_HOSTNAME.key" ) | uniq | wc -l )" -ne 1 ]; then
|
||||
if [ "$( openssl x509 -in "$TMPFILE" -pubkey -noout )" != "$( openssl pkey -in "$BASENAME.key" -pubout )" ]; then
|
||||
# Mismatch : raise an alert
|
||||
echo "WARNING: retrieved certificate does not match '$FQDN_HOSTNAME.key'" >&2
|
||||
echo "WARNING: retrieved certificate does not match '$BASENAME.key'" >&2
|
||||
EXIT_STATUS=1
|
||||
else
|
||||
# Note: we try not to uselessly write and update the files' mtime,
|
||||
# but do it anyway if 'diff' is not available.
|
||||
if ! which diff >/dev/null || ! diff -q "$FQDN_HOSTNAME.crt" "$TMPFILE" >/dev/null ; then
|
||||
if [ ! -f "$BASENAME.crt" ] || ! which diff >/dev/null || ! diff -q "$BASENAME.crt" "$TMPFILE" >/dev/null ; then
|
||||
# Update the local certificate without changing ACL
|
||||
cat "$TMPFILE" > "$FQDN_HOSTNAME.crt"
|
||||
cat "$TMPFILE" > "$BASENAME.crt"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# While we are at it, let's check the expiry dates
|
||||
# While we are at it, let's check the expiry dates
|
||||
for i in *.crt; do
|
||||
if [ "$( date --date="$( openssl x509 -noout -dates -in "$i" | sed -n '/^notAfter/s/^notAfter=//p' )" +%s )" -lt "$(( $( date +%s ) + 86400 ))" ]; then
|
||||
echo "WARNING: certificate '$i' near or already expired." >&2
|
||||
EXIT_STATUS=1
|
||||
|
|
Loading…
Reference in a new issue