Build docker image and push to registry.bitdeals.org / main-build-job (push) Successful in 30s
certbot's own -d already takes a comma-separated list and puts every name
in the certificate's Subject Alternative Names, so `-d "$CERTBOT_DOMAIN"`
needed no change at all. What assumed a single domain was everything that
treated the variable as a *file name*: --cert-name, and the two scripts
that address the lineage under /etc/letsencrypt/live. Certbot names a
lineage after the first domain of the list, so all three now take
${CERTBOT_DOMAIN%%,*} instead of the whole string -- otherwise a two-domain
value asks for a lineage literally called "a.org,b.org" and the renewal
pass looks for a directory nobody made.
One certificate with several names rather than several lineages: HAProxy
binds a single site.pem, and a second lineage would have nowhere to go.
Adding a domain to CERTBOT_DOMAIN on a machine that already holds a
certificate still needs one manual issuance -- `certbot renew` reads the
names off the certificate it has and never looks at the variable. The
README says so, and gives the command.
65 lines
2.3 KiB
Bash
65 lines
2.3 KiB
Bash
#!/bin/sh
|
|
|
|
set -e
|
|
|
|
if [ ! -f /etc/certificates/site.pem ]; then
|
|
# Self-signed placeholder, so HAProxy can bind :443 before a real certificate
|
|
# exists. Built inside a subshell: this script is sourced, so a bare cd or
|
|
# umask would change the caller's shell too. Relative paths used to resolve
|
|
# against the working directory (/opt/certbot) and left the private key there
|
|
# for good; here they resolve against the volume the key belongs on, and the
|
|
# intermediates are removed before site.pem appears.
|
|
(
|
|
umask 077
|
|
cd /etc/certificates
|
|
openssl req -x509 -newkey rsa:2048 -nodes -days 365 -batch \
|
|
-subj "/CN=${CERTBOT_DOMAIN:-localhost}" \
|
|
-keyout site.key.tmp -out site.crt.tmp
|
|
cat site.key.tmp site.crt.tmp > site.pem.tmp
|
|
rm -f site.key.tmp site.crt.tmp
|
|
# Last and atomic: HAProxy reads site.pem at start-up and must never find
|
|
# it half-written.
|
|
mv site.pem.tmp site.pem
|
|
)
|
|
fi
|
|
|
|
# Wait for haproxy: Let's Encrypt reaches this container's challenge server only
|
|
# through it, so asking for a certificate first would just fail validation. The
|
|
# runtime API socket appearing is the signal — HAProxy creates it once the
|
|
# configuration has parsed and the binds have succeeded. Waiting on the socket
|
|
# rather than a TCP probe also means there is no port left to probe.
|
|
HAPROXY_SOCKET=/var/lib/haproxy/admin.sock
|
|
while [ ! -S "$HAPROXY_SOCKET" ]; do
|
|
echo "Waiting for $HAPROXY_SOCKET..."
|
|
sleep 7
|
|
done
|
|
|
|
if [ -n "$CERTBOT_DOMAIN" ]; then
|
|
|
|
# E-mail for Let's Encrypt expiry notices. Built with set -- so that the flag
|
|
# and its value stay two separate arguments: a single "$CERTBOT_OPTS" word
|
|
# reached certbot as one token ("--email you@example.org") and was rejected
|
|
# as an unknown argument, which failed every issuance with an address set.
|
|
# The entrypoint passes no positional parameters, so there are none to lose.
|
|
if [ -n "$CERTBOT_EMAIL" ]; then
|
|
set -- --email "$CERTBOT_EMAIL"
|
|
else
|
|
set -- --register-unsafely-without-email
|
|
fi
|
|
|
|
# Request certificate
|
|
certbot certonly --standalone \
|
|
--non-interactive --agree-tos --http-01-port=380 \
|
|
"$@" \
|
|
--cert-name "${CERTBOT_DOMAIN%%,*}" \
|
|
-d "$CERTBOT_DOMAIN"
|
|
|
|
# Concatenate certificates
|
|
. $(dirname $0)/2-concatenate-cert.sh
|
|
|
|
fi
|
|
|
|
# Update certificates in HAProxy
|
|
. $(dirname $0)/3-update-haproxy-cert.sh
|
|
|