Skip to content

Commit

Permalink
Update certbot. Rely on a hash file computation instead of inotify, w…
Browse files Browse the repository at this point in the history
…hich may be broken in virtualized environments.
  • Loading branch information
Adrien Ferrand committed Aug 18, 2017
1 parent ce39714 commit 31edfa9
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 68 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ FROM python:alpine3.6
MAINTAINER Adrien Ferrand <[email protected]>

ENV LEXICON_VERSION 2.1.10
ENV CERTBOT_VERSION 0.16.0
ENV CERTBOT_VERSION 0.17.0

ENV LETSENCRYPT_STAGING false
ENV LETSENCRYPT_USER_MAIL [email protected]
ENV LEXICON_PROVIDER cloudflare

# Install dependencies
RUN apk --no-cache --update add rsyslog git openssl libffi inotify-tools supervisor docker \
RUN apk --no-cache --update add rsyslog git openssl libffi supervisor docker \
&& apk --no-cache --update --virtual build-dependencies add libffi-dev openssl-dev python-dev build-base \
# Install certbot
&& pip install "certbot==$CERTBOT_VERSION" \
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# adferrand/letsencrypt-dns
![](https://img.shields.io/badge/tags-latest-lightgrey.svg) [![](https://images.microbadger.com/badges/version/adferrand/letsencrypt-dns:1.1.0.svg) ![](https://images.microbadger.com/badges/image/adferrand/letsencrypt-dns:1.1.0.svg)](https://microbadger.com/images/adferrand/letsencrypt-dns:1.1.0)
![](https://img.shields.io/badge/tags-latest-lightgrey.svg) [![](https://images.microbadger.com/badges/version/adferrand/letsencrypt-dns:1.2.0.svg) ![](https://images.microbadger.com/badges/image/adferrand/letsencrypt-dns:1.2.0.svg)](https://microbadger.com/images/adferrand/letsencrypt-dns:1.2.0)

* [Container functionalities](#container-functionalities)
* [Why use this Docker](#why-use-this-docker-)
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.0
1.2.0
19 changes: 14 additions & 5 deletions files/autorestart-containers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@ if [ ! -d /etc/letsencrypt/archive/$domain ]; then
exit 1
fi

# Load hash of the certificate
current_hash=`md5sum /etc/letsencrypt/live/$domain/cert.pem | awk '{ print $1 }'`
while true; do
inotifywait -e modify -e create /etc/letsencrypt/archive/$domain
new_hash=`md5sum /etc/letsencrypt/live/$domain/cert.pem | awk '{ print $1 }'`

if [ "$current_hash" != "$new_hash" ]; then
echo ">>> Restarting dockers $containers because certificate for $domain has been modified."
for container in $containers; do
docker restart $container
done

# Keep new hash version
current_hash="$new_hash"
fi

# Wait 1s for next iteration
sleep 1
echo ">>> Restarting dockers $containers because certificate for $domain has been modified."
for container in $containers; do
docker restart $container
done
done
127 changes: 68 additions & 59 deletions files/watch-domains.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,73 +7,82 @@ if [ "$LETSENCRYPT_STAGING" = true ]; then
staging_cmd="--staging"
fi

current_hash=
while true; do
# Clean all autorestart containers instances
rm -f /etc/supervisord.d/*_autorestart-containers
# Calculate the new domains.conf file hash
new_hash=`md5sum /etc/letsencrypt/domains.conf | awk '{ print $1 }'`
if [ "$current_hash" != "$new_hash" ]; then
# Clean all autorestart containers instances
rm -f /etc/supervisord.d/*_autorestart-containers

echo "#### Registering Let's Encrypt account if needed ####"
certbot register -n --agree-tos -m $LETSENCRYPT_USER_MAIL $staging_cmd
echo "#### Registering Let's Encrypt account if needed ####"
certbot register -n --agree-tos -m $LETSENCRYPT_USER_MAIL $staging_cmd

echo "#### Creating missing certificates if needed (~1min for each) ####"
while read entry; do
domains_cmd=""
main_domain=""
containers=""

for domain in $entry; do
if [ "${domain#*$autorestart_pattern}" != "$domain" ]; then
containers=${domain/autorestart-containers=/}
elif [ -z $main_domain ]; then
main_domain=$domain
domains_cmd="$domains_cmd -d $domain"
else
domains_cmd="$domains_cmd -d $domain"
fi
done

echo ">>> Creating a certificate for domain(s):$domains_cmd"
certbot certonly \
-n \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /var/lib/letsencrypt/hooks/authenticator.sh \
--manual-cleanup-hook /var/lib/letsencrypt/hooks/cleanup.sh \
--manual-public-ip-logging-ok \
--expand \
$staging_cmd \
$domains_cmd

if [ "$containers" != "" ]; then
echo ">>> Watching certificate for main domain $main_domain: containers $containers autorestarted when certificate is changed."
echo "[program:${main_domain}_autorestart-containers]" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "command = /scripts/autorestart-containers.sh $main_domain $containers" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "redirect_stderr = true" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "stdout_logfile = /dev/stdout" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "stdout_logfile_maxbytes = 0" >> /etc/supervisord.d/${main_domain}_autorestart_containers
fi
done < /etc/letsencrypt/domains.conf

echo "### Revoke and delete certificates if needed ####"
for domain in `ls /etc/letsencrypt/live`; do
remove_domain=true
echo "#### Creating missing certificates if needed (~1min for each) ####"
while read entry; do
for comp_domain in $entry; do
if [ "$domain" = "$comp_domain" ]; then
remove_domain=false
break;
domains_cmd=""
main_domain=""
containers=""

for domain in $entry; do
if [ "${domain#*$autorestart_pattern}" != "$domain" ]; then
containers=${domain/autorestart-containers=/}
elif [ -z $main_domain ]; then
main_domain=$domain
domains_cmd="$domains_cmd -d $domain"
else
domains_cmd="$domains_cmd -d $domain"
fi
done

echo ">>> Creating a certificate for domain(s):$domains_cmd"
certbot certonly \
-n \
--manual \
--preferred-challenges=dns \
--manual-auth-hook /var/lib/letsencrypt/hooks/authenticator.sh \
--manual-cleanup-hook /var/lib/letsencrypt/hooks/cleanup.sh \
--manual-public-ip-logging-ok \
--expand \
$staging_cmd \
$domains_cmd

if [ "$containers" != "" ]; then
echo ">>> Watching certificate for main domain $main_domain: containers $containers autorestarted when certificate is changed."
echo "[program:${main_domain}_autorestart-containers]" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "command = /scripts/autorestart-containers.sh $main_domain $containers" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "redirect_stderr = true" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "stdout_logfile = /dev/stdout" >> /etc/supervisord.d/${main_domain}_autorestart_containers
echo "stdout_logfile_maxbytes = 0" >> /etc/supervisord.d/${main_domain}_autorestart_containers
fi
done < /etc/letsencrypt/domains.conf

if [ "$remove_domain" = true ]; then
echo ">>> Removing the certificate $domain"
certbot revoke $staging_cmd --cert-path /etc/letsencrypt/live/$domain/cert.pem
certbot delete $staging_cmd --cert-name $domain
fi
done
echo "### Revoke and delete certificates if needed ####"
for domain in `ls /etc/letsencrypt/live`; do
remove_domain=true
while read entry; do
for comp_domain in $entry; do
if [ "$domain" = "$comp_domain" ]; then
remove_domain=false
break;
fi
done
done < /etc/letsencrypt/domains.conf

if [ "$remove_domain" = true ]; then
echo ">>> Removing the certificate $domain"
certbot revoke $staging_cmd --cert-path /etc/letsencrypt/live/$domain/cert.pem
certbot delete $staging_cmd --cert-name $domain
fi
done

echo "### Reloading supervisord configuration ###"
supervisorctl update

echo "### Reloading supervisord configuration ###"
supervisorctl update
# Keep new hash version
current_hash="$new_hash"
fi

inotifywait -e modify /etc/letsencrypt/domains.conf
# Wait 1s for next iteration
sleep 1
done

0 comments on commit 31edfa9

Please sign in to comment.