-
-
Save killbus/4f856dab1ba8b553be6ddbdaba2334d0 to your computer and use it in GitHub Desktop.
Let's Encrypt certificate management using Certbot and Vault
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# Perform certificate updates in Vault. | |
set -eo pipefail | |
if ! vault token lookup > /dev/null; then | |
echo "Login to Vault first." | |
exit 1 | |
fi | |
# Certificate renewal might take some time, | |
# so renew the token if possible | |
vault token renew > /dev/null | |
for domain in $RENEWED_DOMAINS; do | |
# Wildcard certificates lead to domains like *.example.com | |
# which should become example.com | |
target=$domain | |
case $target in \*\.*) | |
target=${target#*.} | |
esac | |
vault kv put \ | |
"secret/lets-encrypt/certificates/$target" \ | |
"cert=@$RENEWED_LINEAGE/cert.pem" \ | |
"chain=@$RENEWED_LINEAGE/chain.pem" \ | |
"privkey=@$RENEWED_LINEAGE/privkey.pem" | |
# In case of a multiple-domain certificate, there is no need to re-run this for next domains | |
exit 0 | |
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM certbot/dns-dnsimple:v0.33.1 | |
ARG VAULT_VERSION=1.1.3 | |
RUN set -eux; \ | |
apk add --no-cache curl gnupg jq tzdata && \ | |
apkArch="$(apk --print-arch)"; \ | |
case "$apkArch" in \ | |
armhf) ARCH='arm' ;; \ | |
aarch64) ARCH='arm64' ;; \ | |
x86_64) ARCH='amd64' ;; \ | |
x86) ARCH='386' ;; \ | |
*) echo >&2 "error: unsupported architecture: $apkArch"; exit 1 ;; \ | |
esac && \ | |
VAULT_GPGKEY=91A6E7F85D05C65630BEF18951852D87348FFC4C; \ | |
found=''; \ | |
for server in \ | |
hkp://p80.pool.sks-keyservers.net:80 \ | |
hkp://keyserver.ubuntu.com:80 \ | |
hkp://pgp.mit.edu:80 \ | |
; do \ | |
echo "Fetching GPG key $VAULT_GPGKEY from $server"; \ | |
gpg --batch --keyserver "$server" --recv-keys "$VAULT_GPGKEY" && found=yes && break; \ | |
done; \ | |
test -z "$found" && echo >&2 "error: failed to fetch GPG key $VAULT_GPGKEY" && exit 1; \ | |
mkdir -p /tmp/vault && \ | |
cd /tmp/vault && \ | |
wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_linux_${ARCH}.zip && \ | |
wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS && \ | |
wget https://releases.hashicorp.com/vault/${VAULT_VERSION}/vault_${VAULT_VERSION}_SHA256SUMS.sig && \ | |
gpg --batch --verify vault_${VAULT_VERSION}_SHA256SUMS.sig vault_${VAULT_VERSION}_SHA256SUMS && \ | |
grep vault_${VAULT_VERSION}_linux_${ARCH}.zip vault_${VAULT_VERSION}_SHA256SUMS | sha256sum -c && \ | |
unzip -d /bin vault_${VAULT_VERSION}_linux_amd64.zip && \ | |
cd /tmp && \ | |
rm -rf /tmp/vault && \ | |
gpgconf --kill dirmngr && \ | |
gpgconf --kill gpg-agent && \ | |
apk del gnupg && \ | |
rm -rf /root/.gnupg | |
COPY entrypoint.sh /usr/local/bin/ | |
COPY initialize.sh /usr/local/bin/ | |
COPY 00-update-vault.sh /etc/letsencrypt/renewal-hooks/deploy/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
set -e | |
if [ "$1" = 'renew' ]; then | |
initialize.sh | |
certbot renew | |
else | |
exec "$@" | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Initialize the environment for certbot | |
# Requires vault and jq | |
set -eo pipefail | |
if ! vault token lookup > /dev/null; then | |
echo "Login to Vault first." | |
exit 1 | |
fi | |
# Get account path | |
ACCOUNT_PARENT_PATH=/etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory | |
ACCOUNT_ID=$(vault kv get --format=json secret/lets-encrypt/account/extra_details | jq -r '.data.data.account_id') | |
ACCOUNT_PATH="$ACCOUNT_PARENT_PATH/$ACCOUNT_ID" | |
mkdir -p "$ACCOUNT_PATH" | |
for i in meta private_key regr; do | |
vault kv get --format=json "secret/lets-encrypt/account/$i" | \ | |
jq -c '.data.data' \ | |
> "$ACCOUNT_PATH/$i.json" | |
done | |
echo "dns_dnsimple_token = $(vault kv get --format=json secret/dnsimple | jq -r '.data.data.token')" > /etc/letsencrypt/dnsimple.ini | |
chmod 600 /etc/letsencrypt/dnsimple.ini | |
CERTIFICATES_TO_CHECK=$(vault kv list --format=json secret/lets-encrypt/certificates | jq -r '.[]') | |
mkdir -p /etc/letsencrypt/renewal | |
for certificate in $CERTIFICATES_TO_CHECK; do | |
CERTIFICATE_DATA=$(vault kv get --format=json "secret/beyond/lets-encrypt-certificates/certificates/${certificate}") | |
mkdir -p "/etc/letsencrypt/archive/${certificate}" | |
mkdir -p "/etc/letsencrypt/live/${certificate}" | |
for field in cert chain privkey; do | |
cat > "/etc/letsencrypt/archive/${certificate}/${field}1.pem" <<EOF | |
$(echo "${CERTIFICATE_DATA}" | jq -r ".data.data.${field}") | |
EOF | |
ln \ | |
-s "../../archive/${certificate}/${field}1.pem" \ | |
"/etc/letsencrypt/live/${certificate}/${field}.pem" | |
done | |
cat \ | |
"/etc/letsencrypt/archive/${certificate}/cert1.pem" \ | |
"/etc/letsencrypt/archive/${certificate}/chain1.pem" \ | |
> "/etc/letsencrypt/archive/${certificate}/fullchain1.pem" | |
ln \ | |
-s "../../archive/${certificate}/fullchain1.pem" \ | |
"/etc/letsencrypt/live/${certificate}/fullchain.pem" | |
cat > "/etc/letsencrypt/renewal/$certificate.conf" <<EOF | |
version = 0.33.1 | |
archive_dir = /etc/letsencrypt/archive/$certificate | |
cert = /etc/letsencrypt/live/$certificate/cert.pem | |
privkey = /etc/letsencrypt/live/$certificate/privkey.pem | |
chain = /etc/letsencrypt/live/$certificate/chain.pem | |
fullchain = /etc/letsencrypt/live/$certificate/fullchain.pem | |
# Options used in the renewal process | |
[renewalparams] | |
authenticator = dns-dnsimple | |
account = $ACCOUNT_ID | |
dns_dnsimple_credentials = /etc/letsencrypt/dnsimple.ini | |
server = https://acme-v02.api.letsencrypt.org/directory | |
EOF | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment