1
0

feat: disable default certificate creation by default (#1157)

This commit is contained in:
Nicolas Duchon 2024-10-12 19:07:26 +02:00 committed by GitHub
parent 904b5e38b1
commit 3cb7df6fdd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 15 additions and 140 deletions

@ -7,14 +7,6 @@ while [[ $# -gt 0 ]]; do
flag="$1" flag="$1"
case $flag in case $flag in
--default-cert)
for filename in default.crt default.key; do
filepath="/etc/nginx/certs/$filename"
[[ -f "$filepath" ]] && rm -rf "$filepath"
done
shift
;;
--location-config) --location-config)
for domain in 'le1.wtf' '*.example.com' 'test.*' 'le3.pizza' 'subdomain.example.com' 'test.domain.tld'; do for domain in 'le1.wtf' '*.example.com' 'test.*' 'le3.pizza' 'subdomain.example.com' 'test.domain.tld'; do
[[ -f "/etc/nginx/vhost.d/$domain" ]] && rm -f "/etc/nginx/vhost.d/$domain" [[ -f "/etc/nginx/vhost.d/$domain" ]] && rm -f "/etc/nginx/vhost.d/$domain"

@ -110,7 +110,9 @@ function check_dh_group {
} }
function check_default_cert_key { function check_default_cert_key {
local cn='letsencrypt-nginx-proxy-companion' local cn='acme-companion'
echo "Warning: there is no future support planned for the self signed default certificate creation feature and it might be removed in a future release."
if [[ -e /etc/nginx/certs/default.crt && -e /etc/nginx/certs/default.key ]]; then if [[ -e /etc/nginx/certs/default.crt && -e /etc/nginx/certs/default.key ]]; then
default_cert_cn="$(openssl x509 -noout -subject -in /etc/nginx/certs/default.crt)" default_cert_cn="$(openssl x509 -noout -subject -in /etc/nginx/certs/default.crt)"
@ -179,7 +181,7 @@ if [[ "$*" == "/bin/bash /app/start.sh" ]]; then
check_writable_directory '/etc/nginx/vhost.d' check_writable_directory '/etc/nginx/vhost.d'
check_writable_directory '/etc/nginx/conf.d' check_writable_directory '/etc/nginx/conf.d'
fi fi
check_default_cert_key parse_true "${CREATE_DEFAULT_CERTIFICATE:=false}" && check_default_cert_key
check_dh_group check_dh_group
reload_nginx reload_nginx
check_default_account check_default_account

@ -153,3 +153,7 @@ Reusing private keys can help if you intend to use [HPKP](https://developer.mozi
1. The container will use the special purpose `staging` configuration directory. 1. The container will use the special purpose `staging` configuration directory.
1. The directory URI is forced to The Let's Encrypt v2 staging one (`ACME_CA_URI` is ignored) 1. The directory URI is forced to The Let's Encrypt v2 staging one (`ACME_CA_URI` is ignored)
2. The account email address is forced empty (`DEFAULT_EMAIL` and `LETSENCRYPT_EMAIL` are ignored) 2. The account email address is forced empty (`DEFAULT_EMAIL` and `LETSENCRYPT_EMAIL` are ignored)
#### Self signed default certificate
If you want **acme-companio** to create a self signed certificate as default certificate for **nginx-proxy**, you can set the `CREATE_DEFAULT_CERTIFICATE` environment variable to `true`. This will generate a self signed cert / key pair to `/etc/nginx/certs/default.crt` and `/etc/nginx/certs/default.key`, with `acme-companion` as Common Name. Please note that no future support is planned for this feature and it might be removed in a future release.

@ -65,8 +65,6 @@ By default, the **acme-companion** container will enforce the following ownershi
``` ```
[drwxr-xr-x] /etc/nginx/certs [drwxr-xr-x] /etc/nginx/certs
├── [-rw-r--r-- root root] dhparam.pem ├── [-rw-r--r-- root root] dhparam.pem
├── [-rw-r--r-- root root] default.crt
├── [-rw------- root root] default.key
├── [drwxr-xr-x root root] domain.tld ├── [drwxr-xr-x root root] domain.tld
│ ├── [-rw-r--r-- root root] cert.pem │ ├── [-rw-r--r-- root root] cert.pem
│ ├── [-rw-r--r-- root root] chain.pem │ ├── [-rw-r--r-- root root] chain.pem
@ -90,8 +88,6 @@ For example, `FILES_UID=1000`, `FILES_PERMS=644` and `FOLDERS_PERMS=700` will re
``` ```
[drwxr-xr-x] /etc/nginx/certs [drwxr-xr-x] /etc/nginx/certs
├── [-rw-r--r-- 1000 1000] dhparam.pem ├── [-rw-r--r-- 1000 1000] dhparam.pem
├── [-rw-r--r-- 1000 1000] default.crt
├── [-rw-r--r-- 1000 1000] default.key
├── [drwx------ 1000 1000] domain.tld ├── [drwx------ 1000 1000] domain.tld
│ ├── [-rw-r--r-- 1000 1000] cert.pem │ ├── [-rw-r--r-- 1000 1000] cert.pem
│ ├── [-rw-r--r-- 1000 1000] chain.pem │ ├── [-rw-r--r-- 1000 1000] chain.pem

@ -5,7 +5,6 @@ globalTests+=(
docker_api docker_api
docker_api_legacy docker_api_legacy
location_config location_config
default_cert
certs_single certs_single
certs_san certs_san
certs_single_domain certs_single_domain

@ -96,7 +96,6 @@ for hosts in "${letsencrypt_hosts[@]}"; do
done done
docker stop "$container" &> /dev/null docker stop "$container" &> /dev/null
docker exec "$le_container_name" /app/cleanup_test_artifacts --default-cert
i=$(( i + 1 )) i=$(( i + 1 ))
done done

@ -1,105 +0,0 @@
#!/bin/bash
## Test for default certificate creation.
if [[ -z $GITHUB_ACTIONS ]]; 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 {
# Cleanup the files created by this run of the test to avoid foiling following test(s).
docker exec "$le_container_name" /app/cleanup_test_artifacts --default-cert
docker stop "$le_container_name" > /dev/null
}
trap cleanup EXIT
function check_default_cert_existence {
docker exec "$le_container_name" [[ -f "/etc/nginx/certs/default.crt" ]]
}
function default_cert_fingerprint {
if check_default_cert_existence; then
docker exec "$le_container_name" openssl x509 -in "/etc/nginx/certs/default.crt" -fingerprint -noout
fi
}
function default_cert_subject {
if check_default_cert_existence; then
docker exec "$le_container_name" openssl x509 -in "/etc/nginx/certs/default.crt" -subject -noout
fi
}
user_cn="user-provided"
timeout="$(date +%s)"
timeout="$((timeout + 120))"
until docker exec "$le_container_name" [[ -f /etc/nginx/certs/default.crt ]]; do
if [[ "$(date +%s)" -gt "$timeout" ]]; then
echo "Default cert wasn't created under one minute at container first launch."
break
fi
sleep 0.1
done
# Connection test to unconfigured domains
for domain in "${domains[@]}"; do
wait_for_conn --domain "$domain" --default-cert
done
# Test if the default certificate get re-created when
# the certificate or private key file are deleted
for file in 'default.key' 'default.crt'; do
old_default_cert_fingerprint="$(default_cert_fingerprint)"
docker exec "$le_container_name" /app/cleanup_test_artifacts --default-cert
docker restart "$le_container_name" > /dev/null
timeout="$(date +%s)"
timeout="$((timeout + 120))"
while [[ "$(default_cert_fingerprint)" == "$old_default_cert_fingerprint" ]]; do
if [[ "$(date +%s)" -gt "$timeout" ]]; then
echo "Default cert wasn't re-created under one minute after $file deletion."
break
fi
sleep 0.1
done
done
# Test if the default certificate get re-created when
# the certificate expire in less than three months
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/default.*'
docker exec "$le_container_name" openssl req -x509 \
-newkey rsa:4096 -sha256 -nodes -days 60 \
-subj "/CN=letsencrypt-nginx-proxy-companion" \
-keyout /etc/nginx/certs/default.key \
-out /etc/nginx/certs/default.crt &> /dev/null
old_default_cert_fingerprint="$(default_cert_fingerprint)"
docker restart "$le_container_name" > /dev/null && sleep 10
timeout="$(date +%s)"
timeout="$((timeout + 110))"
while [[ "$(default_cert_fingerprint)" == "$old_default_cert_fingerprint" ]]; do
if [[ "$(date +%s)" -gt "$timeout" ]]; then
echo "Default cert wasn't re-created under one minute when the certificate expire in less than three months."
break
fi
sleep 0.1
done
# Test that a user provided default certificate isn't overwrited
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/default.*'
docker exec "$le_container_name" openssl req -x509 \
-newkey rsa:4096 -sha256 -nodes -days 60 \
-subj "/CN=$user_cn" \
-keyout /etc/nginx/certs/default.key \
-out /etc/nginx/certs/default.crt &> /dev/null
docker restart "$le_container_name" > /dev/null
# Connection test to unconfigured domains
for domain in "${domains[@]}"; do
wait_for_conn --domain "$domain" --subject-match "$user_cn"
done

@ -66,9 +66,8 @@ done
# Array of private file paths to test # Array of private file paths to test
private_files=( \ private_files=( \
[0]="/etc/nginx/certs/default.key" \ [0]="/etc/nginx/certs/${domains[0]}/key.pem" \
[1]="/etc/nginx/certs/${domains[0]}/key.pem" \ [1]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \
[2]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \
) )
# Test private file paths # Test private file paths
@ -85,8 +84,7 @@ public_files=( \
[1]="/etc/nginx/certs/${domains[0]}/cert.pem" \ [1]="/etc/nginx/certs/${domains[0]}/cert.pem" \
[2]="/etc/nginx/certs/${domains[0]}/chain.pem" \ [2]="/etc/nginx/certs/${domains[0]}/chain.pem" \
[3]="/etc/nginx/certs/${domains[0]}/fullchain.pem" \ [3]="/etc/nginx/certs/${domains[0]}/fullchain.pem" \
[4]="/etc/nginx/certs/default.crt" \ [4]="/etc/nginx/certs/dhparam.pem" \
[5]="/etc/nginx/certs/dhparam.pem" \
) )
# Test public file paths # Test public file paths

@ -60,9 +60,8 @@ done
# Array of private file paths to test # Array of private file paths to test
private_files=( \ private_files=( \
[0]="/etc/nginx/certs/default.key" \ [0]="/etc/nginx/certs/${domains[0]}/key.pem" \
[1]="/etc/nginx/certs/${domains[0]}/key.pem" \ [1]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \
[2]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \
) )
# Test private file paths # Test private file paths
@ -79,8 +78,7 @@ public_files=( \
[1]="/etc/nginx/certs/${domains[0]}/cert.pem" \ [1]="/etc/nginx/certs/${domains[0]}/cert.pem" \
[2]="/etc/nginx/certs/${domains[0]}/chain.pem" \ [2]="/etc/nginx/certs/${domains[0]}/chain.pem" \
[3]="/etc/nginx/certs/${domains[0]}/fullchain.pem" \ [3]="/etc/nginx/certs/${domains[0]}/fullchain.pem" \
[4]="/etc/nginx/certs/default.crt" \ [4]="/etc/nginx/certs/dhparam.pem" \
[5]="/etc/nginx/certs/dhparam.pem" \
) )
# Test public file paths # Test public file paths

@ -47,8 +47,7 @@ docker exec "$le_container_name" cp /etc/nginx/certs/le1.wtf/key.pem /etc/nginx/
docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le4.wtf/fullchain.pem ./le4.wtf.crt' docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le4.wtf/fullchain.pem ./le4.wtf.crt'
docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le4.wtf/key.pem ./le4.wtf.key' docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le4.wtf/key.pem ./le4.wtf.key'
# symlink default certificate to le1.wtf certificate # Symlink default certificate to le1.wtf certificate
docker exec "$le_container_name" rm -f /etc/nginx/certs/default.crt /etc/nginx/certs/default.key
docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le1.wtf/fullchain.pem ./default.crt' docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le1.wtf/fullchain.pem ./default.crt'
docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le1.wtf/key.pem ./default.key' docker exec "$le_container_name" bash -c 'cd /etc/nginx/certs; ln -s ./le1.wtf/key.pem ./default.key'

@ -263,7 +263,6 @@ export -f check_cert_subj
# Wait for a successful https connection to domain passed with -d/--domain then wait # Wait for a successful https connection to domain passed with -d/--domain then wait
# - until the served certificate isn't the default one (default behavior) # - until the served certificate isn't the default one (default behavior)
# - until the served certificate is the default one (--default-cert)
# - until the served certificate subject match a string (--subject-match) # - until the served certificate subject match a string (--subject-match)
function wait_for_conn { function wait_for_conn {
local action local action
@ -280,11 +279,6 @@ function wait_for_conn {
shift shift
;; ;;
--default-cert)
action='--match'
shift
;;
--subject-match) --subject-match)
action='--match' action='--match'
string="$2" string="$2"