mirror of
https://github.com/nginx-proxy/docker-letsencrypt-nginx-proxy-companion
synced 2024-09-27 10:40:48 +02:00
Merge pull request #485 from Greek64/PR
Add LETSENCRYPT_MIN_VALIDITY variable
This commit is contained in:
commit
7dd2cd67e5
@ -166,7 +166,10 @@ If you want to create multi-domain ([SAN](https://www.digicert.com/subject-alter
|
||||
If you want to create test certificates that don't have the 5 certs/week/domain limits define the `LETSENCRYPT_TEST` environment variable with a value of `true` (in the containers where you request certificates with `LETSENCRYPT_HOST`). If you want to do this globally for all containers, set `ACME_CA_URI` as described below.
|
||||
|
||||
##### Automatic certificate renewal
|
||||
Every hour (3600 seconds) the certificates are checked and every certificate that will expire in the next [30 days](https://github.com/kuba/simp_le/blob/ecf4290c4f7863bb5427b50cdd78bc3a5df79176/simp_le.py#L72) (90 days / 3) are renewed.
|
||||
Every hour (3600 seconds) the certificates are checked and per default every certificate that will expire in the next [30 days](https://github.com/zenhack/simp_le/blob/a8a8013c097910f8f3cce046f1077b41b745673b/simp_le.py#L73) (90 days / 3) is renewed.
|
||||
|
||||
If you want to manually set a different minimum validity for certificates, you can set the `LETSENCRYPT_MIN_VALIDIDTY` environment variable (in each container that defines the `LETSENCRYPT_HOST` variable) to the desired period in seconds.
|
||||
Note that the possible values are internally capped at an upper bound of 7603200 (88 days) and a lower bound of 7200 (2 hours) as a security margin, considering that the Let's Encrypt CA does only issues certificates with a lifetime of [90 days](https://letsencrypt.org/2015/11/09/why-90-days.html) (upper bound), the rate limits imposed on certificate renewals are [5 per week](https://letsencrypt.org/docs/rate-limits/) (upper bound), and the fact that the certificates are checked and renewed accordingly every hour (lower bound).
|
||||
|
||||
##### Force certificates renewal
|
||||
If needed, you can force a running letsencrypt-nginx-proxy-companion container to renew all certificates that are currently in use. Replace `nginx-letsencrypt` with the name of your letsencrypt-nginx-proxy-companion container in the following command:
|
||||
|
@ -8,6 +8,8 @@ ACME_CA_URI="${ACME_CA_URI:-https://acme-v01.api.letsencrypt.org/directory}"
|
||||
DEFAULT_KEY_SIZE=4096
|
||||
REUSE_ACCOUNT_KEYS="$(lc ${REUSE_ACCOUNT_KEYS:-true})"
|
||||
REUSE_PRIVATE_KEYS="$(lc ${REUSE_PRIVATE_KEYS:-false})"
|
||||
MIN_VALIDITY_CAP=7603200
|
||||
DEFAULT_MIN_VALIDITY=2592000
|
||||
|
||||
function create_link {
|
||||
local -r source=${1?missing source argument}
|
||||
@ -174,7 +176,28 @@ function update_certs {
|
||||
|
||||
[[ "$(lc $DEBUG)" == true ]] && params_d_str+=" -v"
|
||||
[[ $REUSE_PRIVATE_KEYS == true ]] && params_d_str+=" --reuse_key"
|
||||
[[ "${1}" == "--force-renew" ]] && params_d_str+=" --valid_min 7776000"
|
||||
|
||||
min_validity="LETSENCRYPT_${cid}_MIN_VALIDITY"
|
||||
min_validity="${!min_validity}"
|
||||
if [[ "$min_validity" == "<no value>" ]]; then
|
||||
min_validity=$DEFAULT_MIN_VALIDITY
|
||||
fi
|
||||
# Sanity Check
|
||||
# Upper Bound
|
||||
if [[ $min_validity -gt $MIN_VALIDITY_CAP ]]; then
|
||||
min_validity=$MIN_VALIDITY_CAP
|
||||
fi
|
||||
# Lower Bound
|
||||
if [[ $min_validity -lt $(($seconds_to_wait * 2)) ]]; then
|
||||
min_validity=$(($seconds_to_wait * 2))
|
||||
fi
|
||||
|
||||
if [[ "${1}" == "--force-renew" ]]; then
|
||||
# Manually set to highest certificate lifetime given by LE CA
|
||||
params_d_str+=" --valid_min 7776000"
|
||||
else
|
||||
params_d_str+=" --valid_min $min_validity"
|
||||
fi
|
||||
|
||||
# Create directory for the first domain,
|
||||
# make it root readable only and make it the cwd
|
||||
|
@ -11,6 +11,7 @@ LETSENCRYPT_{{ $cid }}_KEYSIZE="{{ $container.Env.LETSENCRYPT_KEYSIZE }}"
|
||||
LETSENCRYPT_{{ $cid }}_TEST="{{ $container.Env.LETSENCRYPT_TEST }}"
|
||||
LETSENCRYPT_{{ $cid }}_ACCOUNT_ALIAS="{{ $container.Env.LETSENCRYPT_ACCOUNT_ALIAS }}"
|
||||
LETSENCRYPT_{{ $cid }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
|
||||
LETSENCRYPT_{{ $cid }}_MIN_VALIDITY="{{ $container.Env.LETSENCRYPT_MIN_VALIDITY }}"
|
||||
{{ end }}
|
||||
|
||||
{{ end }}
|
||||
|
@ -12,6 +12,7 @@ imageTests+=(
|
||||
certs_single
|
||||
certs_san
|
||||
force_renew
|
||||
certs_validity
|
||||
container_restart
|
||||
permissions_default
|
||||
permissions_custom
|
||||
|
@ -11,12 +11,22 @@ setup_boulder() {
|
||||
$GOPATH/src/github.com/letsencrypt/boulder
|
||||
pushd $GOPATH/src/github.com/letsencrypt/boulder
|
||||
if [[ "$(uname)" == 'Darwin' ]]; then
|
||||
# Set Standard Ports
|
||||
sed -i '' 's/ 5002/ 80/g' test/config/va.json
|
||||
sed -i '' 's/ 5001/ 443/g' test/config/va.json
|
||||
# Set certificate lifetime to 88 days
|
||||
sed -i '' 's/2160h/2112h/g' test/config/ca-a.json
|
||||
sed -i '' 's/2160h/2112h/g' test/config/ca-b.json
|
||||
# Modify custom rate limit
|
||||
sed -i '' 's/le.wtf,le1.wtf/le1.wtf,le2.wtf,le3.wtf/g' test/rate-limit-policies.yml
|
||||
else
|
||||
# Set Standard Ports
|
||||
sed --in-place 's/ 5002/ 80/g' test/config/va.json
|
||||
sed --in-place 's/ 5001/ 443/g' test/config/va.json
|
||||
# Set certificate lifetime to 88 days
|
||||
sed --in-place 's/2160h/2112h/g' test/config/ca-a.json
|
||||
sed --in-place 's/2160h/2112h/g' test/config/ca-b.json
|
||||
# Modify custom rate limit
|
||||
sed --in-place 's/le.wtf,le1.wtf/le1.wtf,le2.wtf,le3.wtf/g' test/rate-limit-policies.yml
|
||||
fi
|
||||
docker-compose build --pull
|
||||
|
13
test/tests/certs_validity/expected-std-out.txt
Normal file
13
test/tests/certs_validity/expected-std-out.txt
Normal file
@ -0,0 +1,13 @@
|
||||
Started letsencrypt container for test certs_validity
|
||||
Started test web server for le1.wtf
|
||||
Started test web server for le2.wtf
|
||||
Started test web server for le3.wtf
|
||||
Symlink to le1.wtf certificate has been generated.
|
||||
The link is pointing to the file ./le1.wtf/fullchain.pem
|
||||
Symlink to le2.wtf certificate has been generated.
|
||||
The link is pointing to the file ./le2.wtf/fullchain.pem
|
||||
Symlink to le3.wtf certificate has been generated.
|
||||
The link is pointing to the file ./le3.wtf/fullchain.pem
|
||||
Certificate for le1.wtf was not renewed.
|
||||
Certificate for le2.wtf was not renewed.
|
||||
Certificate for le3.wtf was renewed.
|
93
test/tests/certs_validity/run.sh
Executable file
93
test/tests/certs_validity/run.sh
Executable file
@ -0,0 +1,93 @@
|
||||
#!/bin/bash
|
||||
|
||||
## Test for the LETSENCRYPT_MIN_VALIDITY environment variable.
|
||||
|
||||
if [[ -z $TRAVIS_CI ]]; then
|
||||
le_container_name="$(basename ${0%/*})_$(date "+%Y-%m-%d_%H.%M.%S")"
|
||||
else
|
||||
le_container_name="$(basename ${0%/*})"
|
||||
fi
|
||||
run_le_container ${1:?} "$le_container_name"
|
||||
|
||||
# Create the $domains array from comma separated domains in TEST_DOMAINS.
|
||||
IFS=',' read -r -a domains <<< "$TEST_DOMAINS"
|
||||
|
||||
# Cleanup function with EXIT trap
|
||||
function cleanup {
|
||||
# Remove any remaining Nginx container(s) silently.
|
||||
for domain in "${domains[@]}"; do
|
||||
docker rm --force "$domain" > /dev/null 2>&1
|
||||
done
|
||||
# Cleanup the files created by this run of the test to avoid foiling following test(s).
|
||||
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf*'
|
||||
# Stop the LE container
|
||||
docker stop "$le_container_name" > /dev/null
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Run a separate nginx container for each domain in the $domains array.
|
||||
# Default validity
|
||||
docker run --rm -d \
|
||||
--name "${domains[0]}" \
|
||||
-e "VIRTUAL_HOST=${domains[0]}" \
|
||||
-e "LETSENCRYPT_HOST=${domains[0]}" \
|
||||
--network boulder_bluenet \
|
||||
nginx:alpine > /dev/null && echo "Started test web server for ${domains[0]}"
|
||||
# Manual validity (same as default)
|
||||
docker run --rm -d \
|
||||
--name "${domains[1]}" \
|
||||
-e "VIRTUAL_HOST=${domains[1]}" \
|
||||
-e "LETSENCRYPT_HOST=${domains[1]}" \
|
||||
-e "LETSENCRYPT_MIN_VALIDITY=2592000" \
|
||||
--network boulder_bluenet \
|
||||
nginx:alpine > /dev/null && echo "Started test web server for ${domains[1]}"
|
||||
# Manual validity (few seconds shy of MIN_VALIDITY_CAP=7603200)
|
||||
docker run --rm -d \
|
||||
--name "${domains[2]}" \
|
||||
-e "VIRTUAL_HOST=${domains[2]}" \
|
||||
-e "LETSENCRYPT_HOST=${domains[2]}" \
|
||||
-e "LETSENCRYPT_MIN_VALIDITY=7603190" \
|
||||
--network boulder_bluenet \
|
||||
nginx:alpine > /dev/null && echo "Started test web server for ${domains[2]}"
|
||||
|
||||
# Wait for a symlinks
|
||||
wait_for_symlink "${domains[0]}" "$le_container_name"
|
||||
wait_for_symlink "${domains[1]}" "$le_container_name"
|
||||
wait_for_symlink "${domains[2]}" "$le_container_name"
|
||||
# Grab the expiration times of the certificates
|
||||
first_cert_expire_1="$(get_cert_expiration_epoch "${domains[0]}" "$le_container_name")"
|
||||
first_cert_expire_2="$(get_cert_expiration_epoch "${domains[1]}" "$le_container_name")"
|
||||
first_cert_expire_3="$(get_cert_expiration_epoch "${domains[2]}" "$le_container_name")"
|
||||
|
||||
# Wait for ${domains[2]} set certificate validity to expire
|
||||
sleep 10
|
||||
|
||||
# Manually trigger letsencrypt_service
|
||||
docker exec "$le_container_name" /bin/bash -c "source /app/letsencrypt_service --source-only; update_certs" > /dev/null 2>&1
|
||||
|
||||
# Grab the new expiration times of the certificates
|
||||
second_cert_expire_1="$(get_cert_expiration_epoch "${domains[0]}" "$le_container_name")"
|
||||
second_cert_expire_2="$(get_cert_expiration_epoch "${domains[1]}" "$le_container_name")"
|
||||
second_cert_expire_3="$(get_cert_expiration_epoch "${domains[2]}" "$le_container_name")"
|
||||
|
||||
if [[ $second_cert_expire_1 -eq $first_cert_expire_1 ]]; then
|
||||
echo "Certificate for ${domains[0]} was not renewed."
|
||||
else
|
||||
echo "Certificate for ${domains[0]} was incorrectly renewed."
|
||||
echo "First certificate expiration epoch : $first_cert_expire_1."
|
||||
echo "Second certificate expiration epoch : $second_cert_expire_1."
|
||||
fi
|
||||
if [[ $second_cert_expire_2 -eq $first_cert_expire_2 ]]; then
|
||||
echo "Certificate for ${domains[1]} was not renewed."
|
||||
else
|
||||
echo "Certificate for ${domains[1]} was incorrectly renewed."
|
||||
echo "First certificate expiration epoch : $first_cert_expire_2."
|
||||
echo "Second certificate expiration epoch : $second_cert_expire_2."
|
||||
fi
|
||||
if [[ $second_cert_expire_3 -gt $first_cert_expire_3 ]]; then
|
||||
echo "Certificate for ${domains[2]} was renewed."
|
||||
else
|
||||
echo "Certificate for ${domains[2]} was not renewed."
|
||||
echo "First certificate expiration epoch : $first_cert_expire_3."
|
||||
echo "Second certificate expiration epoch : $second_cert_expire_3."
|
||||
fi
|
Loading…
Reference in New Issue
Block a user