-
Notifications
You must be signed in to change notification settings - Fork 88
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
168 additions
and
67 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,10 +11,17 @@ ENV CERTBOT_VERSION 0.19.0 | |
# Let's Encrypt configuration | ||
ENV LETSENCRYPT_STAGING false | ||
ENV LETSENCRYPT_USER_MAIL [email protected] | ||
|
||
# Lexicon configuration | ||
ENV LEXICON_PROVIDER cloudflare | ||
|
||
# Container specific configuration | ||
ENV PFX_EXPORT false | ||
ENV PFX_EXPORT_PASSPHRASE "" | ||
ENV CERTS_DIRS_MODE 0750 | ||
ENV CERTS_FILES_MODE 0640 | ||
ENV CERTS_USER_OWNER root | ||
ENV CERTS_GROUP_OWNER root | ||
|
||
# Install dependencies, certbot, lexicon, prepare for first start and clean | ||
RUN apk --no-cache --update add rsyslog git openssl libffi supervisor docker \ | ||
|
@@ -29,11 +36,12 @@ RUN apk --no-cache --update add rsyslog git openssl libffi supervisor docker \ | |
COPY files/run.sh /scripts/run.sh | ||
COPY files/watch-domains.sh /scripts/watch-domains.sh | ||
COPY files/autorestart-containers.sh /scripts/autorestart-containers.sh | ||
COPY files/autocmd-containers.sh /scripts/autocmd-containers.sh | ||
COPY files/crontab /etc/crontab | ||
COPY files/supervisord.conf /etc/supervisord.conf | ||
COPY files/authenticator.sh /var/lib/letsencrypt/hooks/authenticator.sh | ||
COPY files/cleanup.sh /var/lib/letsencrypt/hooks/cleanup.sh | ||
COPY files/pfx-export-hook.sh /scripts/pfx-export-hook.sh | ||
COPY files/deploy-hook.sh /scripts/deploy-hook.sh | ||
COPY files/renew.sh /scripts/renew.sh | ||
|
||
RUN chmod +x /scripts/* | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,8 +11,11 @@ | |
* [Data persistency](#data-persistency) | ||
* [Share certificates with the host](#share-certificates-with-the-host) | ||
* [Share certificates with other containers](#share-certificates-with-other-containers) | ||
* [Reconfiguration on a running container](#reconfiguration-on-a-running-container) | ||
* [Restart containers when a certificate is renewed](#restart-containers-when-a-certificate-is-renewed) | ||
* [Certificates files permissions](#certificates-files-permissions) | ||
* [Runtime operations](#runtime-operations) | ||
* [Certificates reconfiguration at runtime](#certificates-reconfiguration-at-runtime) | ||
* [Restart containers when a certificate is renewed](#restart-containers-when-a-certificate-is-renewed) | ||
* [Call a reload command on containers when a certificate is renewed](#call-a-reload-command-on-containers-when-a-certificate-is-renewed) | ||
* [Miscellaneous and testing](#miscellaneous-and-testing) | ||
* [Activate staging ACME servers](#activating-staging-acme-servers) | ||
* [Auto-export certificates in PFX format](#auto-export-certificates-in-pfx-format) | ||
|
@@ -168,15 +171,27 @@ docker run \ | |
|
||
The volume `/etc/letsencrypt` will be available for the SMTP container, which can use a generated certificate for its own concern (here, securing the SMTP protocol). | ||
|
||
## Reconfiguration on a running container | ||
### Certificates files permissions | ||
|
||
By default certificates files (`cert.pem`, `privkey.pem`, _etc._) are accessible only to the user/group owning `/etc/letsencrypt`, which is **root** by default. It means that generated certificates cannot be used by non-root processes (in other containers or on the host). | ||
|
||
You can modify file mode of `/etc/letsencrypt/archive` and `/etc/letsencrypt/live` folders and their content to allow non-root processes to access the certificates. Set environment variables `CERTS_DIRS_MODE (default: 0750)` and `CERTS_FILES_MODE (default: 0640)` to modify directories and files mode respectivly. For example, a file mode of `0644` and directory mode of `0755` will open access to everyone. | ||
|
||
Alternatively or cumulatively you may need to change the owner user/group of `/etc/letsencrypt/archive` and `/etc/letsencrypt/live` folders and their content. To do so, specify user/group name or uid/gid in the relevant environment variables: `CERTS_USER_OWNER (default: root)` and `CERTS_GROUP_OWNER (default: root)`. | ||
|
||
_(Warning) Certificates files permissions, introduced in container version `1.4`, will modify default permissions for certificates. Previously, `/etc/letsencrypt/live` and `/etc/letsencrypt/archive` were `0750`, their sub-folders where `0755` and contained files were `0644`. Now theses folders and their sub-folders are `0750` while contained files are `0640`: this should not lead to any regression, as the parent folders were of a more restrictive permission than their content, leading certs files to be unaccessible to non-root processes. However for pathological cases you will need to set environment variable `CERTS_DIRS_MODE` and `CERTS_FILES_MODE` appropriately._ | ||
|
||
## Runtime operations | ||
|
||
### Certificates reconfiguration at runtime | ||
|
||
If you want to add a new certificate, remove one, or extend existing one to other domains, you just need to modify the `domains.conf` file from the host. Once saved, the container will automatically mirror the modifications in `/etc/letsencrypt` volume. If new certificates need to be generated, please note that approximately 30 seconds are required for each generation before modifications are visible. | ||
|
||
Please check the container logs to follow the operations. | ||
|
||
## Restart containers when a certificate is renewed | ||
### Restart containers when a certificate is renewed | ||
|
||
As said in introduction, most of the non-Web services require a restart when the certificate is changed. And this will occur at least once each two months. To ensure correct propagation of the new certificates in your Docker services, one special entry can be added at the end of a line for the concerned certificate in `domains.conf`. | ||
As said in introduction, most of the non-Web services require a restart when the certificate is changed. And this will occur at least once each two months. To ensure correct propagation of the new certificates in your Docker services, one special entry can be added at the **end** of a line for the concerned certificate in `domains.conf`. | ||
|
||
This entry takes the form of `autorestart-containers=container1,container2,container3` where `containerX` is the name of a container running on the same Docker instance than `letsencrypt-dns`. | ||
|
||
|
@@ -191,14 +206,15 @@ smtp.example.com imap.example.com autorestart-containers=smtp | |
auth.example.com | ||
``` | ||
|
||
Then execute following commands | ||
Then execute following commands: | ||
|
||
```bash | ||
docker run \ | ||
--name letsencrypt-dns \ | ||
--volume /etc/letsencrypt/domains.conf:/etc/letsencrypt/domains.conf \ | ||
--volume /etc/letsencrypt/domains.conf:/etc/letsencrypt/domains.conf \ | ||
--volume /var/docker-data/letsencrypt:/etc/letsencrypt \ | ||
--env '[email protected]' \ | ||
--volume /var/run/docker.sock:/var/run/docker.sock \ | ||
--env '[email protected]' \ | ||
--env 'LEXICON_PROVIDER=cloudflare' \ | ||
--env 'LEXICON_CLOUDFLARE_USERNAME=my_user' \ | ||
--env 'LEXICON_CLOUDFLARE_TOKEN=my_secret_token' \ | ||
|
@@ -214,6 +230,24 @@ docker run \ | |
|
||
If the certificate `smtp.example.com` is renewed, the container named `smtp` will be restarted. Renewal of `auth.example.com` will not restart anything. | ||
|
||
### Call a reload command on containers when a certificate is renewed | ||
|
||
Restarting a container when a certificate is renewed is sufficient for all cases. However one drawback is that the target processes will stop during a little time, and consequently the services provided are not continuous. This may be ok for non critical services, but problematic for things like authentication services or database servers. | ||
|
||
If a target process allows it, the letsencrypt-dns container can call a reload configuration command on the target container when a certificate is renewed. In this case, service is not stopped and immediatly takes into account the new config, including the new certificate. Apache2 for example (example only, as an http challenge will be a better option here) can see its configuration to be hot-reloaded by invoking the command `apachectl graceful` in the target container. | ||
|
||
To specify which command to launch on which container when a certificate is renewed, one will put at the **end** of the relevant line of `domains.conf` a special entry which takes the form of `autocmd-containers=container1:command1,container2:command2 arg2a arg2b,container3:command3 arg3a`. Comma `,` separates each container/command configuration, colon `:` separates the container name from the command to launch. Commands must be executable files, located in the $PATH of the target container, or accessed by their full path. | ||
|
||
In the case of an Apache2 server embedded in a container named `my-apache` to be reloaded when certificate `web.example.com` is renewed, put following entry in `domains.conf`: | ||
|
||
``` | ||
web.example.com autocmd-containers=my-apache:apachectl graceful | ||
``` | ||
|
||
If the certificate `web.example.com` is renewed, command `apachectl graceful` will be invoked on container `my-apache`, and the apache2 service will use the new certificate without killing any HTTP session. | ||
|
||
_(Limitations on invokable commands) The option `autocmd-container` is intended to call a simple executable file with few potential arguments. It is not made to call some advanced bash script, and would likely fail if you do so. In fact, the command is not executed in a shell on the target, and variables will be resolved against the lets-encrypt container environment. If you want to operate advanced scripting, put an executable script in the target container, and use its path in `autocmd-container` option._ | ||
|
||
## Miscellaneous and testing | ||
|
||
### Activating staging ACME servers | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#!/bin/sh | ||
|
||
domain=$1 | ||
containers_and_cmd=$2 | ||
|
||
if [ ! -S /var/run/docker.sock ]; then | ||
echo "ERROR: /var/run/docker.sock socket is missing." | ||
exit 1 | ||
fi | ||
|
||
if [ ! -d /etc/letsencrypt/archive/$domain ]; then | ||
echo "ERROR: /etc/letsencrypt/archive/$domain directory is missing." | ||
fi | ||
|
||
# Load hash of the certificate | ||
current_hash=`md5sum /etc/letsencrypt/live/$domain/cert.pem | awk '{ print $1 }'` | ||
while true; do | ||
new_hash=`md5sum /etc/letsencrypt/live/$domain/cert.pem | awk '{ print $1 }'` | ||
|
||
if [ "$current_hash" != "$new_hash" ]; then | ||
# Extract container name and its command | ||
IFS=','; for container_and_cmd in $containers_and_cmd; do | ||
# Extract container name and its command | ||
container_name="" | ||
command="" | ||
IFS=':'; for entry in $container_and_cmd; do | ||
if [ -z $container_name ]; then | ||
container_name="$entry" | ||
else | ||
command="$entry" | ||
fi | ||
done; unset IFS | ||
echo ">>> Executing command '$command' for container $container_name because certificate for $domain has been modified." | ||
# Execute it | ||
docker exec $container_name $command | ||
done; unset IFS | ||
|
||
# Keep new hash version | ||
current_hash="$new_hash" | ||
fi | ||
|
||
# Wait 1s for next iteration | ||
sleep 1 | ||
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/bin/sh | ||
|
||
# Construct PFX file for new cert if needed | ||
if [ "$PFX_EXPORT" = "true" ]; then | ||
openssl pkcs12 -export \ | ||
-out $RENEWED_LINEAGE/cert.pfx \ | ||
-inkey $RENEWED_LINEAGE/privkey.pem \ | ||
-in $RENEWED_LINEAGE/cert.pem \ | ||
-certfile $RENEWED_LINEAGE/chain.pem \ | ||
-password pass:$PFX_EXPORT_PASSPHRASE | ||
fi | ||
|
||
# Synchronize mode and user/group for new certificate files | ||
chmod $CERTS_DIRS_MODE $(find $RENEWED_LINEAGE ${RENEWED_LINEAGE/live/archive} -type d) | ||
chmod $CERTS_FILES_MODE $(find $RENEWED_LINEAGE ${RENEWED_LINEAGE/live/archive} -type f) | ||
chown -R $CERTS_USER_OWNER:$CERTS_GROUP_OWNER $RENEWED_LINEAGE ${RENEWED_LINEAGE/live/archive} |
This file was deleted.
Oops, something went wrong.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,4 @@ | ||
#!/bin/sh | ||
|
||
echo "Launch renew test" | ||
|
||
hooks="" | ||
if [ "$PFX_EXPORT" = "true" ]; then | ||
hooks="$hooks --deploy-hook pfx-export-hook.sh" | ||
fi | ||
|
||
certbot renew -n $hooks | ||
certbot renew -n --deploy-hook deploy-hook.sh |
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
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