Thanks @dbu. I’ve been using this strategy with certbot for a while now, but it stopped working recently. The issue, it turns out, is twofold.
-
The “chain.pem” file–which is included for convenience in “fullchain.pem”–issued by Let’s Encrypt now has an empty line. That blank line will need to be stripped out; otherwise, HAProxy will try to interpret part of the payload as a command and spit out “Unknown command…” errors.
-
DOMAINS=$(ls ${LE_DIR})
doesn’t quite work anymore since/etc/letsencrypt/live/
has aREADME
file in it.
Lastly, I’d be hesitant to use tee
since that may cause the private key to show up in logs. It may be more secure to use simple redirection (>
).
I use the following, where “$CERT_NAME” holds the name of the certificate (e.g. $DOMAIN
in the original script), as issued to certbot
's --cert-name
option.
LE_LIVE_DIR="/etc/letsencrypt/live/${CERT_NAME}"
LE_FULL_CERT_DIR=/etc/letsencrypt/full
FULL_CERT="${LE_FULL_CERT_DIR}/${CERT_NAME}.pem"
mkdir -p "${LE_FULL_CERT_DIR}"
# Create a single-file certificate with both the full CA chain and the
# private key. Empty lines are removed.
cat ${LE_LIVE_DIR}/fullchain.pem ${LE_LIVE_DIR}/privkey.pem | sed '/^$/d' > ${FULL_CERT}
Note the sed
part, which removes the empty lines from fullchain.pem
. Also note that I place the concatenated certificate in a new directory. Permissions and ownership should be set on the directory and file (e.g. owned by root with 600 permissions on the file).