Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e9dca8a5a | ||
|
|
e0492cfd5b |
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,3 +8,4 @@ go/
|
||||
nginx.tmpl
|
||||
test/local_test_env.sh
|
||||
test/tests/docker_api/expected-std-out.txt
|
||||
test/tests/certs_standalone/letsencrypt_user_data
|
||||
|
||||
@ -47,6 +47,7 @@ after_failure:
|
||||
- docker logs default_cert
|
||||
- docker logs certs_single
|
||||
- docker logs certs_san
|
||||
- docker logs certs_standalone
|
||||
- docker logs force_renew
|
||||
- docker logs permissions_default
|
||||
- docker logs permissions_custom
|
||||
|
||||
@ -162,6 +162,7 @@ if [[ "$*" == "/bin/bash /app/start.sh" ]]; then
|
||||
check_writable_directory '/etc/nginx/certs'
|
||||
check_writable_directory '/etc/nginx/vhost.d'
|
||||
check_writable_directory '/usr/share/nginx/html'
|
||||
[[ -f /app/letsencrypt_user_data ]] && check_writable_directory '/etc/nginx/conf.d'
|
||||
check_deprecated_env_var
|
||||
check_default_cert_key
|
||||
check_dh_group
|
||||
|
||||
@ -36,6 +36,33 @@ function add_location_configuration {
|
||||
return 1
|
||||
}
|
||||
|
||||
function add_standalone_configuration {
|
||||
local domain="${1:?}"
|
||||
cat > "/etc/nginx/conf.d/standalone-cert-$domain.conf" << EOF
|
||||
server {
|
||||
server_name $domain;
|
||||
listen 80;
|
||||
access_log /var/log/nginx/access.log vhost;
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
auth_basic off;
|
||||
allow all;
|
||||
root /usr/share/nginx/html;
|
||||
try_files \$uri =404;
|
||||
break;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
function remove_all_standalone_configurations {
|
||||
local old_shopt_options=$(shopt -p) # Backup shopt options
|
||||
shopt -s nullglob
|
||||
for file in "/etc/nginx/conf.d/standalone-cert-"*".conf"; do
|
||||
rm -f "$file"
|
||||
done
|
||||
eval "$old_shopt_options" # Restore shopt options
|
||||
}
|
||||
|
||||
function remove_all_location_configurations {
|
||||
local old_shopt_options=$(shopt -p) # Backup shopt options
|
||||
shopt -s nullglob
|
||||
|
||||
@ -45,6 +45,8 @@ function create_links {
|
||||
}
|
||||
|
||||
function cleanup_links {
|
||||
local -a LETSENCRYPT_CONTAINERS
|
||||
local -a LETSENCRYPT_STANDALONE_CERTS
|
||||
local -a ENABLED_DOMAINS
|
||||
local -a SYMLINKED_DOMAINS
|
||||
local -a DISABLED_DOMAINS
|
||||
@ -60,9 +62,10 @@ function cleanup_links {
|
||||
[[ $DEBUG == true ]] && echo "Symlinked domains: ${SYMLINKED_DOMAINS[*]}"
|
||||
|
||||
# Create an array containing domains that are considered
|
||||
# enabled (ie present on /app/letsencrypt_service_data).
|
||||
# shellcheck source=/dev/null
|
||||
source /app/letsencrypt_service_data
|
||||
# enabled (ie present on /app/letsencrypt_service_data or /app/letsencrypt_user_data).
|
||||
[[ -f /app/letsencrypt_service_data ]] && source /app/letsencrypt_service_data
|
||||
[[ -f /app/letsencrypt_user_data ]] && source /app/letsencrypt_user_data
|
||||
LETSENCRYPT_CONTAINERS+=( "${LETSENCRYPT_STANDALONE_CERTS[@]}" )
|
||||
for cid in "${LETSENCRYPT_CONTAINERS[@]}"; do
|
||||
host_varname="LETSENCRYPT_${cid}_HOST"
|
||||
hosts_array="${host_varname}[@]"
|
||||
@ -75,7 +78,7 @@ function cleanup_links {
|
||||
|
||||
# Create an array containing only domains for which a symlinked private key exists
|
||||
# in /etc/nginx/certs but that no longer have a corresponding LETSENCRYPT_HOST set
|
||||
# on an active container.
|
||||
# on an active container or on /app/letsencrypt_user_data
|
||||
if [[ ${#SYMLINKED_DOMAINS[@]} -gt 0 ]]; then
|
||||
mapfile -t DISABLED_DOMAINS < <(echo "${SYMLINKED_DOMAINS[@]}" \
|
||||
"${ENABLED_DOMAINS[@]}" \
|
||||
@ -115,15 +118,34 @@ function cleanup_links {
|
||||
}
|
||||
|
||||
function update_certs {
|
||||
local -a LETSENCRYPT_CONTAINERS
|
||||
local -a LETSENCRYPT_STANDALONE_CERTS
|
||||
|
||||
check_nginx_proxy_container_run || return
|
||||
|
||||
[[ -f /app/letsencrypt_service_data ]] || return
|
||||
|
||||
# Load relevant container settings
|
||||
unset LETSENCRYPT_CONTAINERS
|
||||
# shellcheck source=/dev/null
|
||||
source /app/letsencrypt_service_data
|
||||
if [[ -f /app/letsencrypt_service_data ]]; then
|
||||
source /app/letsencrypt_service_data
|
||||
else
|
||||
echo "Warning: /app/letsencrypt_service_data not found, skipping data from containers."
|
||||
fi
|
||||
|
||||
# Load settings for standalone certs
|
||||
if [[ -f /app/letsencrypt_user_data ]]; then
|
||||
if source /app/letsencrypt_user_data; then
|
||||
for cid in "${LETSENCRYPT_STANDALONE_CERTS[@]}"; do
|
||||
host_varname="LETSENCRYPT_${cid}_HOST"
|
||||
hosts_array="${host_varname}[@]"
|
||||
for domain in "${!hosts_array}"; do
|
||||
add_standalone_configuration "$domain"
|
||||
done
|
||||
done
|
||||
reload_nginx
|
||||
LETSENCRYPT_CONTAINERS+=( "${LETSENCRYPT_STANDALONE_CERTS[@]}" )
|
||||
else
|
||||
echo "Warning: could not source /app/letsencrypt_user_data, skipping user data"
|
||||
fi
|
||||
fi
|
||||
|
||||
should_reload_nginx='false'
|
||||
for cid in "${LETSENCRYPT_CONTAINERS[@]}"; do
|
||||
@ -138,13 +160,13 @@ function update_certs {
|
||||
params_d_str=""
|
||||
|
||||
email_varname="LETSENCRYPT_${cid}_EMAIL"
|
||||
email_address="${!email_varname}"
|
||||
email_address="${!email_varname:-"<no value>"}"
|
||||
if [[ "$email_address" != "<no value>" ]]; then
|
||||
params_d_str+=" --email $email_address"
|
||||
fi
|
||||
|
||||
keysize_varname="LETSENCRYPT_${cid}_KEYSIZE"
|
||||
cert_keysize="${!keysize_varname}"
|
||||
cert_keysize="${!keysize_varname:-"<no value>"}"
|
||||
if [[ "$cert_keysize" == "<no value>" ]]; then
|
||||
cert_keysize=$DEFAULT_KEY_SIZE
|
||||
fi
|
||||
@ -164,7 +186,7 @@ function update_certs {
|
||||
fi
|
||||
|
||||
account_varname="LETSENCRYPT_${cid}_ACCOUNT_ALIAS"
|
||||
account_alias="${!account_varname}"
|
||||
account_alias="${!account_varname:-"<no value>"}"
|
||||
if [[ "$account_alias" == "<no value>" ]]; then
|
||||
account_alias=default
|
||||
fi
|
||||
@ -249,6 +271,13 @@ function update_certs {
|
||||
[[ $simp_le_return -eq 0 ]] && should_reload_nginx='true'
|
||||
fi
|
||||
|
||||
for domain in "${!hosts_array}"; do
|
||||
if [[ -f "/etc/nginx/conf.d/standalone-cert-$domain.conf" ]]; then
|
||||
[[ $DEBUG == true ]] && echo "Debug: removing standalone configuration file /etc/nginx/conf.d/standalone-cert-$domain.conf"
|
||||
rm -f "/etc/nginx/conf.d/standalone-cert-$domain.conf" && should_reload_nginx='true'
|
||||
fi
|
||||
done
|
||||
|
||||
done
|
||||
|
||||
cleanup_links && should_reload_nginx='true'
|
||||
|
||||
@ -7,6 +7,7 @@ term_handler() {
|
||||
|
||||
source /app/functions.sh
|
||||
remove_all_location_configurations
|
||||
remove_all_standalone_configurations
|
||||
|
||||
exit 0
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ imageTests+=(
|
||||
default_cert
|
||||
certs_single
|
||||
certs_san
|
||||
certs_standalone
|
||||
force_renew
|
||||
permissions_default
|
||||
permissions_custom
|
||||
|
||||
@ -9,6 +9,7 @@ case $SETUP in
|
||||
--name $NGINX_CONTAINER_NAME \
|
||||
--env "DHPARAM_BITS=256" \
|
||||
-v /etc/nginx/vhost.d \
|
||||
-v /etc/nginx/conf.d \
|
||||
-v /usr/share/nginx/html \
|
||||
-v /var/run/docker.sock:/tmp/docker.sock:ro \
|
||||
--label com.github.jrcs.letsencrypt_nginx_proxy_companion.test_suite \
|
||||
|
||||
8
test/tests/certs_standalone/expected-std-out.txt
Normal file
8
test/tests/certs_standalone/expected-std-out.txt
Normal file
@ -0,0 +1,8 @@
|
||||
Started letsencrypt container for test certs_standalone
|
||||
Symlink to le1.wtf certificate has been generated.
|
||||
The link is pointing to the file ./le1.wtf/fullchain.pem
|
||||
Domain le1.wtf is on certificate.
|
||||
Symlink to le2.wtf certificate has been generated.
|
||||
The link is pointing to the file ./le2.wtf/fullchain.pem
|
||||
Domain le2.wtf is on certificate.
|
||||
Domain le3.wtf is on certificate.
|
||||
74
test/tests/certs_standalone/run.sh
Executable file
74
test/tests/certs_standalone/run.sh
Executable file
@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
## Test for standalone certificates.
|
||||
|
||||
if [[ -z $TRAVIS_CI ]]; then
|
||||
le_container_name="$(basename ${0%/*})_$(date "+%Y-%m-%d_%H.%M.%S")"
|
||||
else
|
||||
le_container_name="$(basename ${0%/*})"
|
||||
fi
|
||||
|
||||
# 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" bash -c 'rm -rf /etc/nginx/certs/le?.wtf*'
|
||||
# Stop the LE container
|
||||
docker stop "$le_container_name" > /dev/null
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create letsencrypt_user_data with a single domain cert
|
||||
cat > ${TRAVIS_BUILD_DIR}/test/tests/certs_standalone/letsencrypt_user_data <<EOF
|
||||
LETSENCRYPT_STANDALONE_CERTS=('single')
|
||||
LETSENCRYPT_single_HOST=('${domains[0]}')
|
||||
EOF
|
||||
|
||||
run_le_container ${1:?} "$le_container_name" \
|
||||
"--volume ${TRAVIS_BUILD_DIR}/test/tests/certs_standalone/letsencrypt_user_data:/app/letsencrypt_user_data"
|
||||
|
||||
# Wait for a symlink at /etc/nginx/certs/${domains[0]}.crt
|
||||
# then grab the certificate in text form ...
|
||||
wait_for_symlink "${domains[0]}" "$le_container_name"
|
||||
created_cert="$(docker exec "$le_container_name" \
|
||||
openssl x509 -in /etc/nginx/certs/${domains[0]}/cert.pem -text -noout)"
|
||||
|
||||
# Check if the domain is on the certificate.
|
||||
if grep -q "${domains[0]}" <<< "$created_cert"; then
|
||||
echo "Domain ${domains[0]} is on certificate."
|
||||
else
|
||||
echo "Domain ${domains[0]} did not appear on certificate."
|
||||
fi
|
||||
|
||||
docker exec "$le_container_name" bash -c "[[ -f /etc/nginx/conf.d/standalone-cert-${domains[0]}.conf ]]" \
|
||||
&& echo "Standalone configuration for ${domains[0]} wasn't correctly removed."
|
||||
|
||||
# Add another (SAN) certificate to letsencrypt_user_data
|
||||
cat > ${TRAVIS_BUILD_DIR}/test/tests/certs_standalone/letsencrypt_user_data <<EOF
|
||||
LETSENCRYPT_STANDALONE_CERTS=('single' 'san')
|
||||
LETSENCRYPT_single_HOST=('${domains[0]}')
|
||||
LETSENCRYPT_san_HOST=('${domains[1]}' '${domains[2]}')
|
||||
EOF
|
||||
|
||||
# Manually trigger the service loop
|
||||
docker exec "$le_container_name" /app/signal_le_service > /dev/null
|
||||
|
||||
# Wait for a symlink at /etc/nginx/certs/${domains[1]}.crt
|
||||
# then grab the certificate in text form ...
|
||||
wait_for_symlink "${domains[1]}" "$le_container_name"
|
||||
created_cert="$(docker exec "$le_container_name" \
|
||||
openssl x509 -in /etc/nginx/certs/${domains[1]}/cert.pem -text -noout)"
|
||||
|
||||
for domain in "${domains[1]}" "${domains[2]}"; do
|
||||
# Check if the domain is on the certificate.
|
||||
if grep -q "$domain" <<< "$created_cert"; then
|
||||
echo "Domain $domain is on certificate."
|
||||
else
|
||||
echo "Domain $domain did not appear on certificate."
|
||||
fi
|
||||
done
|
||||
|
||||
docker exec "$le_container_name" bash -c "[[ ! -f /etc/nginx/conf.d/standalone-cert-${domains[1]}.conf ]]" \
|
||||
|| echo "Standalone configuration for ${domains[1]} wasn't correctly removed."
|
||||
Loading…
Reference in New Issue
Block a user