From 3cb7df6fdda5d4a55f3ce498e9ad95d72028ed7b Mon Sep 17 00:00:00 2001 From: Nicolas Duchon Date: Sat, 12 Oct 2024 19:07:26 +0200 Subject: [PATCH] feat: disable default certificate creation by default (#1157) --- app/cleanup_test_artifacts | 8 -- app/entrypoint.sh | 6 +- docs/Let's-Encrypt-and-ACME.md | 4 + docs/Persistent-data.md | 4 - test/config.sh | 1 - test/tests/certs_single_domain/run.sh | 1 - test/tests/default_cert/expected-std-out.txt | 1 - test/tests/default_cert/run.sh | 105 ------------------- test/tests/permissions_custom/run.sh | 8 +- test/tests/permissions_default/run.sh | 8 +- test/tests/symlinks/run.sh | 3 +- test/tests/test-functions.sh | 6 -- 12 files changed, 15 insertions(+), 140 deletions(-) delete mode 100644 test/tests/default_cert/expected-std-out.txt delete mode 100755 test/tests/default_cert/run.sh diff --git a/app/cleanup_test_artifacts b/app/cleanup_test_artifacts index 4e76d3f..a7dbec1 100755 --- a/app/cleanup_test_artifacts +++ b/app/cleanup_test_artifacts @@ -7,14 +7,6 @@ while [[ $# -gt 0 ]]; do flag="$1" 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) 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" diff --git a/app/entrypoint.sh b/app/entrypoint.sh index 616715e..00f1ef2 100755 --- a/app/entrypoint.sh +++ b/app/entrypoint.sh @@ -110,7 +110,9 @@ function check_dh_group { } 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 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/conf.d' fi - check_default_cert_key + parse_true "${CREATE_DEFAULT_CERTIFICATE:=false}" && check_default_cert_key check_dh_group reload_nginx check_default_account diff --git a/docs/Let's-Encrypt-and-ACME.md b/docs/Let's-Encrypt-and-ACME.md index 42fd745..a04d0c2 100644 --- a/docs/Let's-Encrypt-and-ACME.md +++ b/docs/Let's-Encrypt-and-ACME.md @@ -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 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) + +#### 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. diff --git a/docs/Persistent-data.md b/docs/Persistent-data.md index d2c16f3..ceb87e5 100644 --- a/docs/Persistent-data.md +++ b/docs/Persistent-data.md @@ -65,8 +65,6 @@ By default, the **acme-companion** container will enforce the following ownershi ``` [drwxr-xr-x] /etc/nginx/certs ├── [-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 │ ├── [-rw-r--r-- root root] cert.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 ├── [-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 │ ├── [-rw-r--r-- 1000 1000] cert.pem │ ├── [-rw-r--r-- 1000 1000] chain.pem diff --git a/test/config.sh b/test/config.sh index 474b4f4..9b72e04 100755 --- a/test/config.sh +++ b/test/config.sh @@ -5,7 +5,6 @@ globalTests+=( docker_api docker_api_legacy location_config - default_cert certs_single certs_san certs_single_domain diff --git a/test/tests/certs_single_domain/run.sh b/test/tests/certs_single_domain/run.sh index 7a068a0..7ea0d7d 100755 --- a/test/tests/certs_single_domain/run.sh +++ b/test/tests/certs_single_domain/run.sh @@ -96,7 +96,6 @@ for hosts in "${letsencrypt_hosts[@]}"; do done docker stop "$container" &> /dev/null - docker exec "$le_container_name" /app/cleanup_test_artifacts --default-cert i=$(( i + 1 )) done diff --git a/test/tests/default_cert/expected-std-out.txt b/test/tests/default_cert/expected-std-out.txt deleted file mode 100644 index 8b13789..0000000 --- a/test/tests/default_cert/expected-std-out.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/test/tests/default_cert/run.sh b/test/tests/default_cert/run.sh deleted file mode 100755 index 54b2a70..0000000 --- a/test/tests/default_cert/run.sh +++ /dev/null @@ -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 diff --git a/test/tests/permissions_custom/run.sh b/test/tests/permissions_custom/run.sh index 01a5f56..5f69f08 100755 --- a/test/tests/permissions_custom/run.sh +++ b/test/tests/permissions_custom/run.sh @@ -66,9 +66,8 @@ done # Array of private file paths to test private_files=( \ - [0]="/etc/nginx/certs/default.key" \ - [1]="/etc/nginx/certs/${domains[0]}/key.pem" \ - [2]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \ + [0]="/etc/nginx/certs/${domains[0]}/key.pem" \ + [1]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \ ) # Test private file paths @@ -85,8 +84,7 @@ public_files=( \ [1]="/etc/nginx/certs/${domains[0]}/cert.pem" \ [2]="/etc/nginx/certs/${domains[0]}/chain.pem" \ [3]="/etc/nginx/certs/${domains[0]}/fullchain.pem" \ - [4]="/etc/nginx/certs/default.crt" \ - [5]="/etc/nginx/certs/dhparam.pem" \ + [4]="/etc/nginx/certs/dhparam.pem" \ ) # Test public file paths diff --git a/test/tests/permissions_default/run.sh b/test/tests/permissions_default/run.sh index 21bc138..7e5f880 100755 --- a/test/tests/permissions_default/run.sh +++ b/test/tests/permissions_default/run.sh @@ -60,9 +60,8 @@ done # Array of private file paths to test private_files=( \ - [0]="/etc/nginx/certs/default.key" \ - [1]="/etc/nginx/certs/${domains[0]}/key.pem" \ - [2]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \ + [0]="/etc/nginx/certs/${domains[0]}/key.pem" \ + [1]="/etc/acme.sh/default/${domains[0]}/${domains[0]}.key" \ ) # Test private file paths @@ -79,8 +78,7 @@ public_files=( \ [1]="/etc/nginx/certs/${domains[0]}/cert.pem" \ [2]="/etc/nginx/certs/${domains[0]}/chain.pem" \ [3]="/etc/nginx/certs/${domains[0]}/fullchain.pem" \ - [4]="/etc/nginx/certs/default.crt" \ - [5]="/etc/nginx/certs/dhparam.pem" \ + [4]="/etc/nginx/certs/dhparam.pem" \ ) # Test public file paths diff --git a/test/tests/symlinks/run.sh b/test/tests/symlinks/run.sh index 4ad20c7..2889ba1 100755 --- a/test/tests/symlinks/run.sh +++ b/test/tests/symlinks/run.sh @@ -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/key.pem ./le4.wtf.key' -# symlink default certificate to le1.wtf certificate -docker exec "$le_container_name" rm -f /etc/nginx/certs/default.crt /etc/nginx/certs/default.key +# Symlink default certificate to le1.wtf certificate 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' diff --git a/test/tests/test-functions.sh b/test/tests/test-functions.sh index 6d067bc..40adde3 100755 --- a/test/tests/test-functions.sh +++ b/test/tests/test-functions.sh @@ -263,7 +263,6 @@ export -f check_cert_subj # 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 is the default one (--default-cert) # - until the served certificate subject match a string (--subject-match) function wait_for_conn { local action @@ -280,11 +279,6 @@ function wait_for_conn { shift ;; - --default-cert) - action='--match' - shift - ;; - --subject-match) action='--match' string="$2"