From 31edfa970a1a8ecb0b2c5bedd1f3b442416d9358 Mon Sep 17 00:00:00 2001 From: Adrien Ferrand Date: Fri, 18 Aug 2017 22:34:55 +0200 Subject: [PATCH] Update certbot. Rely on a hash file computation instead of inotify, which may be broken in virtualized environments. --- Dockerfile | 4 +- README.md | 2 +- VERSION | 2 +- files/autorestart-containers.sh | 19 +++-- files/watch-domains.sh | 127 +++++++++++++++++--------------- 5 files changed, 86 insertions(+), 68 deletions(-) diff --git a/Dockerfile b/Dockerfile index 775ecd2c..953949f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,14 +2,14 @@ FROM python:alpine3.6 MAINTAINER Adrien Ferrand 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 noreply@example.com 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" \ diff --git a/README.md b/README.md index a68e42cc..ea012bb3 100644 --- a/README.md +++ b/README.md @@ -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-) diff --git a/VERSION b/VERSION index 9084fa2f..26aaba0e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.1.0 +1.2.0 diff --git a/files/autorestart-containers.sh b/files/autorestart-containers.sh index 50c32f52..f9080e85 100755 --- a/files/autorestart-containers.sh +++ b/files/autorestart-containers.sh @@ -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 \ No newline at end of file diff --git a/files/watch-domains.sh b/files/watch-domains.sh index 5971c6fc..c6e0b340 100755 --- a/files/watch-domains.sh +++ b/files/watch-domains.sh @@ -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 \ No newline at end of file