Skip to content
Snippets Groups Projects
Unverified Commit 7f27d042 authored by Roma's avatar Roma Committed by Rémy Huet
Browse files

Ajout de pica-mail-certbot

parent 3a95850c
No related branches found
No related tags found
1 merge request!20pica-mailnt
MIT License
Copyright (c) 2016 Henri Dwyer
Copyright (c) 2017 Elliot Saba
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Pris depuis https://github.com/staticfloat/docker-nginx-certbot et modifié pour les besoins de Picasoft.
Modifié dans le cadre de la licence MIT.
# docker-nginx-certbot
Create and automatically renew website SSL certificates using the letsencrypt free certificate authority, and its client *certbot*, built on top of the nginx server.
# More information
Find out more about letsencrypt: https://letsencrypt.org
Certbot github: https://github.com/certbot/certbot
This repository was originally forked from `@henridwyer`, many thanks to him for the good idea. I've rewritten about 90% of this repository, so it bears almost no resemblance to the original. This repository is _much_ more opinionated about the structure of your webservers/containers, however it is easier to use as long as all of your webservers follow that pattern.
# Usage
Use this image with a `Dockerfile` such as:
```Dockerfile
FROM staticfloat/nginx-certbot
COPY *.conf /etc/nginx/conf.d/
```
And a `.conf` file such as:
```nginx
server {
listen 443 ssl;
server_name server.company.com;
ssl_certificate /etc/letsencrypt/live/server.company.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/server.company.com/privkey.pem;
location / {
...
}
}
```
Wrap this all up with a `docker-compose.yml` file:
```yml
version: '3'
services:
frontend:
restart: unless-stopped
build: frontend
ports:
- 80:80/tcp
- 443:443/tcp
environment:
- CERTBOT_EMAIL=owner@company.com
...
```
# Changelog
### 0.8
- Ditch cron, it never liked me anway. Just use `sleep` and a `while` loop instead.
### 0.7
- Complete rewrite, build this image on top of the `nginx` image, and run `cron`/`certbot` alongside `nginx` so that we can have nginx configs dynamically enabled as we get SSL certificates.
### 0.6
- Add `nginx_auto_enable.sh` script to `/etc/letsencrypt/` so that users can bring nginx up before SSL certs are actually available.
### 0.5
- Change the name to `docker-certbot-cron`, update documentation, strip out even more stuff I don't care about.
### 0.4
- Rip out a bunch of stuff because `@staticfloat` is a monster, and likes to do things his way
### 0.3
- Add support for webroot mode.
- Run certbot once with all domains.
### 0.2
- Upgraded to use certbot client
- Changed image to use alpine linux
### 0.1
- Initial release
File added
FROM nginx
LABEL maintainer="Elliot Saba <staticfloat@gmail.com>, Valder Gallo <valergallo@gmail.com>, Bruno Zell <bruno.zzell@gmail.com>"
VOLUME /etc/letsencrypt
EXPOSE 80
EXPOSE 443
# Do this apt/pip stuff all in one RUN command to avoid creating large
# intermediate layers on non-squashable docker installs
RUN apt update && \
apt install -y python python-dev libffi6 libffi-dev libssl-dev curl build-essential && \
curl -L 'https://bootstrap.pypa.io/get-pip.py' | python && \
pip install -U cffi certbot && \
apt remove --purge -y python-dev build-essential libffi-dev libssl-dev curl && \
apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Copy in scripts for certbot
COPY ./scripts/ /scripts
RUN chmod +x /scripts/*.sh
# Add /scripts/startup directory to source more startup scripts
RUN mkdir -p /scripts/startup
# Copy in default nginx configuration (which just forwards ACME requests to
# certbot, or redirects to HTTPS, but has no HTTPS configurations by default).
RUN rm -f /etc/nginx/conf.d/*
COPY nginx_conf.d/ /etc/nginx/conf.d/
ENTRYPOINT []
CMD ["/bin/bash", "/scripts/entrypoint.sh"]
server {
# Listen on plain old HTTP
listen 80 default_server;
# Pass this particular URL off to certbot, to authenticate HTTPS certificates
location '/.well-known/acme-challenge' {
default_type "text/plain";
proxy_pass http://localhost:1337;
}
# Everything else gets shunted over to HTTPS
location / {
return 301 https://$http_host$request_uri;
}
}
#!/bin/sh
cat <<EOF >> /etc/nginx/conf.d/.conf
server {
listen 443 ssl;
server_name ${FQDN-HOSTNAME};
ssl_certificate /etc/letsencrypt/live/${FQDN-HOSTNAME}/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/${FQDN-HOSTNAME}/privkey.pem;
location / {
}
}
EOF
#!/bin/sh
# When we get killed, kill all our children
trap "exit" INT TERM
trap "kill 0" EXIT
# Source in util.sh so we can have our nice tools
. $(cd $(dirname $0); pwd)/util.sh
# Immediately run auto_enable_configs so that nginx is in a runnable state
auto_enable_configs
# Start up nginx, save PID so we can reload config inside of run_certbot.sh
nginx -g "daemon off;" &
export NGINX_PID=$!
# Lastly, run startup scripts
for f in /scripts/startup/*.sh; do
if [ -x "$f" ]; then
echo "Running startup script $f"
$f
fi
done
echo "Done with startup"
# Instead of trying to run `cron` or something like that, just sleep and run `certbot`.
while [ true ]; do
echo "Run certbot"
/scripts/run_certbot.sh
# Sleep for 1 week
sleep 604810 &
SLEEP_PID=$!
# Wait on sleep so that when we get ctrl-c'ed it kills everything due to our trap
wait "$SLEEP_PID"
done
#!/bin/sh
# Source in util.sh so we can have our nice tools
. $(cd $(dirname $0); pwd)/util.sh
# We require an email to register the ssl certificate for
if [ -z "$CERTBOT_EMAIL" ]; then
error "CERTBOT_EMAIL environment variable undefined; certbot will do nothing"
exit 1
fi
exit_code=0
set -x
# Loop over every domain we can find
for domain in $(parse_domains); do
if is_renewal_required $domain; then
# Renewal required for this doman.
# Last one happened over a week ago (or never)
if ! get_certificate $domain $CERTBOT_EMAIL; then
error "Cerbot failed for $domain. Check the logs for details."
exit_code=1
fi
else
echo "Not run certbot for $domain; last renewal happened just recently."
fi
done
# After trying to get all our certificates, auto enable any configs that we
# did indeed get certificates for
auto_enable_configs
# Finally, tell nginx to reload the configs
kill -HUP $NGINX_PID
set +x
exit $exit_code
#!/bin/sh
# Helper function to output error messages to STDERR, with red text
error() {
(set +x; tput -Tscreen bold
tput -Tscreen setaf 1
echo $*
tput -Tscreen sgr0) >&2
}
# Helper function that sifts through /etc/nginx/conf.d/, looking for lines that
# contain ssl_certificate_key, and try to find domain names in them. We accept
# a very restricted set of keys: Each key must map to a set of concrete domains
# (no wildcards) and each keyfile will be stored at the default location of
# /etc/letsencrypt/live/<primary_domain_name>/privkey.pem
parse_domains() {
# For each configuration file in /etc/nginx/conf.d/*.conf*
for conf_file in /etc/nginx/conf.d/*.conf*; do
sed -n -e 's&^\s*ssl_certificate_key\s*\/etc/letsencrypt/live/\(.*\)/privkey.pem;&\1&p' $conf_file | xargs echo
done
}
# Given a config file path, spit out all the ssl_certificate_key file paths
parse_keyfiles() {
sed -n -e 's&^\s*ssl_certificate_key\s*\(.*\);&\1&p' "$1"
}
# Given a config file path, return 0 if all keyfiles exist (or there are no
# keyfiles), return 1 otherwise
keyfiles_exist() {
for keyfile in $(parse_keyfiles $1); do
if [ ! -f $keyfile ]; then
echo "Couldn't find keyfile $keyfile for $1"
return 1
fi
done
return 0
}
# Helper function that sifts through /etc/nginx/conf.d/, looking for configs
# that don't have their keyfiles yet, and disabling them through renaming
auto_enable_configs() {
for conf_file in /etc/nginx/conf.d/*.conf*; do
if keyfiles_exist $conf_file; then
if [ ${conf_file##*.} = nokey ]; then
echo "Found all the keyfiles for $conf_file, enabling..."
mv $conf_file ${conf_file%.*}
fi
else
if [ ${conf_file##*.} = conf ]; then
echo "Keyfile(s) missing for $conf_file, disabling..."
mv $conf_file $conf_file.nokey
fi
fi
done
}
# Helper function to ask certbot for the given domain(s). Must have defined the
# EMAIL environment variable, to register the proper support email address.
get_certificate() {
echo "Getting certificate for domain $1 on behalf of user $2"
PRODUCTION_URL='https://acme-v01.api.letsencrypt.org/directory'
STAGING_URL='https://acme-staging.api.letsencrypt.org/directory'
if [ "${IS_STAGING}" = "1" ]; then
letsencrypt_url=$STAGING_URL
echo "Staging ..."
else
letsencrypt_url=$PRODUCTION_URL
echo "Production ..."
fi
echo "running certbot ... $letsencrypt_url $1 $2"
certbot certonly --agree-tos --keep -n --text --email $2 --server \
$letsencrypt_url -d $1 --http-01-port 1337 \
--standalone --preferred-challenges http-01 --debug
}
# Given a domain name, return true if a renewal is required (last renewal
# ran over a week ago or never happened yet), otherwise return false.
is_renewal_required() {
# If the file does not exist assume a renewal is required
last_renewal_file="/etc/letsencrypt/live/$1/privkey.pem"
[ ! -e "$last_renewal_file" ] && return;
# If the file exists, check if the last renewal was more than a week ago
one_week_sec=604800
now_sec=$(date -d now +%s)
last_renewal_sec=$(stat -c %Y "$last_renewal_file")
last_renewal_delta_sec=$(( ($now_sec - $last_renewal_sec) ))
is_finshed_week_sec=$(( ($one_week_sec - $last_renewal_delta_sec) ))
[ $is_finshed_week_sec -lt 0 ]
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment