1
0
Fork 0

Change ACME client to acme.sh

This commit is contained in:
Nicolas Duchon 2018-12-31 12:53:21 +01:00
parent 96c9cbf821
commit c821d809f6
No known key found for this signature in database
GPG Key ID: EA3151C66A4D79E7
21 changed files with 145 additions and 203 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@ certs/
conf.d/
data/
vhost.d/
.vscode
# tests
go/

View File

@ -28,8 +28,7 @@ before_install:
install:
- docker build -t "$IMAGE" .
- docker inspect "$IMAGE"
- docker run --rm "$IMAGE" simp_le --version
- docker run --rm "$IMAGE" simp_le -v --test
- docker run --rm "$IMAGE" acme.sh --version
- docker images
before_script:

View File

@ -21,32 +21,35 @@ FROM alpine:3.11
LABEL maintainer="Yves Blusseau <90z7oey02@sneakemail.com> (@blusseau)"
ENV DEBUG=false \
DOCKER_HOST=unix:///var/run/docker.sock
ENV DOCKER_HOST=unix:///var/run/docker.sock \
PATH=$PATH:/app
# Install packages required by the image
RUN apk add --update \
bash \
ca-certificates \
coreutils \
curl \
jq \
netcat-openbsd \
openssl \
socat \
&& rm /var/cache/apk/*
# Install docker-gen from build stage
COPY --from=go-builder /go/src/github.com/jwilder/docker-gen/docker-gen /usr/local/bin/
# Install simp_le
COPY /install_simp_le.sh /app/install_simp_le.sh
RUN chmod +rx /app/install_simp_le.sh \
COPY /install_acme.sh /app/install_acme.sh
RUN chmod +rx /app/install_acme.sh \
&& sync \
&& /app/install_simp_le.sh \
&& rm -f /app/install_simp_le.sh
&& /app/install_acme.sh \
&& rm -f /app/install_acme.sh
COPY /app/ /app/
WORKDIR /app
VOLUME ["/etc/acme.sh", "/etc/nginx/certs"]
ENTRYPOINT [ "/bin/bash", "/app/entrypoint.sh" ]
CMD [ "/bin/bash", "/app/start.sh" ]

View File

@ -4,7 +4,6 @@ set -u
# shellcheck source=functions.sh
source /app/functions.sh
DEBUG="$(lc "$DEBUG")"
function check_deprecated_env_var {
if [[ -n "${ACME_TOS_HASH:-}" ]]; then
@ -109,7 +108,7 @@ function check_default_cert_key {
# than 3 months / 7776000 seconds (60 x 60 x 24 x 30 x 3).
check_cert_min_validity /etc/nginx/certs/default.crt 7776000
cert_validity=$?
[[ "$DEBUG" == true ]] && echo "Debug: a default certificate with $default_cert_cn is present."
[[ "$DEBUG" == 1 ]] && echo "Debug: a default certificate with $default_cert_cn is present."
fi
# Create a default cert and private key if:
@ -126,23 +125,35 @@ function check_default_cert_key {
&& mv /etc/nginx/certs/default.key.new /etc/nginx/certs/default.key \
&& mv /etc/nginx/certs/default.crt.new /etc/nginx/certs/default.crt
echo "Info: a default key and certificate have been created at /etc/nginx/certs/default.key and /etc/nginx/certs/default.crt."
elif [[ "$DEBUG" == true && "${default_cert_cn:-}" =~ $cn ]]; then
elif [[ "$DEBUG" == 1 && "${default_cert_cn:-}" =~ $cn ]]; then
echo "Debug: the self generated default certificate is still valid for more than three months. Skipping default certificate creation."
elif [[ "$DEBUG" == true ]]; then
elif [[ "$DEBUG" == 1 ]]; then
echo "Debug: the default certificate is user provided. Skipping default certificate creation."
fi
set_ownership_and_permissions "/etc/nginx/certs/default.key"
set_ownership_and_permissions "/etc/nginx/certs/default.crt"
}
if [[ "$*" == "/bin/bash /app/start.sh" ]]; then
acmev1_r='acme-(v01\|staging)\.api\.letsencrypt\.org'
if [[ "${ACME_CA_URI:-}" =~ $acmev1_r ]]; then
echo "Error: the ACME v1 API is no longer supported by simp_le."
echo "See https://github.com/zenhack/simp_le/pull/119"
echo "Please use one of Let's Encrypt ACME v2 endpoints instead."
exit 1
function configure_default_email {
# Configure the email used by the default config
[[ -d /etc/acme.sh/default ]] || mkdir -p /etc/acme.sh/default
if [[ -f /etc/acme.sh/default/account.conf ]]; then
if [[ -f /etc/acme.sh/default/ca/acme-v01.api.letsencrypt.org/account.json ]]; then
acme.sh --update-account --accountemail "${DEFAULT_EMAIL:-}"
return 0
elif grep -q ACCOUNT_EMAIL /etc/acme.sh/default/account.conf; then
if grep -q "${DEFAULT_EMAIL:-}" /etc/acme.sh/default/account.conf; then
return 0
else
sed -i "s/^ACCOUNT_EMAIL=.*$/ACCOUNT_EMAIL='${DEFAULT_EMAIL:-}'/g" /etc/acme.sh/default/account.conf
return 0
fi
fi
fi
echo "ACCOUNT_EMAIL='${DEFAULT_EMAIL:-}'" >> /etc/acme.sh/default/account.conf
}
if [[ "$*" == "/bin/bash /app/start.sh" ]]; then
check_docker_socket
if [[ -z "$(get_nginx_proxy_container)" ]]; then
echo "Error: can't get nginx-proxy container ID !" >&2
@ -160,12 +171,13 @@ if [[ "$*" == "/bin/bash /app/start.sh" ]]; then
fi
check_writable_directory '/etc/nginx/certs'
check_writable_directory '/etc/nginx/vhost.d'
check_writable_directory '/etc/acme.sh'
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
reload_nginx
[[ -n ${DEFAULT_EMAIL:-} ]] && configure_default_email
fi
exec "$@"

View File

@ -5,7 +5,10 @@ function lc {
echo "${@,,}"
}
DEBUG="$(lc "$DEBUG")"
DEBUG="$(lc "${DEBUG:-}")"
if [[ "$DEBUG" == true ]]; then
DEBUG=1 && export DEBUG
fi
[[ -z "${VHOST_DIR:-}" ]] && \
declare -r VHOST_DIR=/etc/nginx/vhost.d
@ -325,7 +328,7 @@ function set_ownership_and_permissions {
return 1
fi
[[ "$DEBUG" == true ]] && echo "Debug: checking $path ownership and permissions."
[[ "$DEBUG" == 1 ]] && echo "Debug: checking $path ownership and permissions."
# Find the user numeric ID if the FILES_UID environment variable isn't numeric.
if [[ "$user" =~ ^[0-9]+$ ]]; then
@ -334,7 +337,7 @@ function set_ownership_and_permissions {
elif id -u "$user" > /dev/null 2>&1; then
# Convert the user name to numeric ID
local user_num; user_num="$(id -u "$user")"
[[ "$DEBUG" == true ]] && echo "Debug: numeric ID of user $user is $user_num."
[[ "$DEBUG" == 1 ]] && echo "Debug: numeric ID of user $user is $user_num."
else
echo "Warning: user $user not found in the container, please use a numeric user ID instead of a user name. Skipping ownership and permissions check."
return 1
@ -347,7 +350,7 @@ function set_ownership_and_permissions {
elif getent group "$group" > /dev/null 2>&1; then
# Convert the group name to numeric ID
local group_num; group_num="$(getent group "$group" | awk -F ':' '{print $3}')"
[[ "$DEBUG" == true ]] && echo "Debug: numeric ID of group $group is $group_num."
[[ "$DEBUG" == 1 ]] && echo "Debug: numeric ID of group $group is $group_num."
else
echo "Warning: group $group not found in the container, please use a numeric group ID instead of a group name. Skipping ownership and permissions check."
return 1
@ -356,7 +359,7 @@ function set_ownership_and_permissions {
# Check and modify ownership if required.
if [[ -e "$path" ]]; then
if [[ "$(stat -c %u:%g "$path" )" != "$user_num:$group_num" ]]; then
[[ "$DEBUG" == true ]] && echo "Debug: setting $path ownership to $user:$group."
[[ "$DEBUG" == 1 ]] && echo "Debug: setting $path ownership to $user:$group."
if [[ -L "$path" ]]; then
chown -h "$user_num:$group_num" "$path"
else
@ -366,7 +369,7 @@ function set_ownership_and_permissions {
# If the path is a folder, check and modify permissions if required.
if [[ -d "$path" ]]; then
if [[ "$(stat -c %a "$path")" != "$d_perms" ]]; then
[[ "$DEBUG" == true ]] && echo "Debug: setting $path permissions to $d_perms."
[[ "$DEBUG" == 1 ]] && echo "Debug: setting $path permissions to $d_perms."
chmod "$d_perms" "$path"
fi
# If the path is a file, check and modify permissions if required.
@ -374,13 +377,13 @@ function set_ownership_and_permissions {
# Use different permissions for private files (private keys and ACME account files) ...
if [[ "$path" =~ ^.*(default\.key|key\.pem|\.json)$ ]]; then
if [[ "$(stat -c %a "$path")" != "$f_perms" ]]; then
[[ "$DEBUG" == true ]] && echo "Debug: setting $path permissions to $f_perms."
[[ "$DEBUG" == 1 ]] && echo "Debug: setting $path permissions to $f_perms."
chmod "$f_perms" "$path"
fi
# ... and for public files (certificates, chains, fullchains, DH parameters).
else
if [[ "$(stat -c %a "$path")" != "644" ]]; then
[[ "$DEBUG" == true ]] && echo "Debug: setting $path permissions to 644."
[[ "$DEBUG" == 1 ]] && echo "Debug: setting $path permissions to 644."
chmod "644" "$path"
fi
fi

View File

@ -2,20 +2,18 @@
# shellcheck source=functions.sh
source /app/functions.sh
DEBUG="$(lc "$DEBUG")"
seconds_to_wait=3600
ACME_CA_URI="${ACME_CA_URI:-https://acme-v02.api.letsencrypt.org/directory}"
DEFAULT_KEY_SIZE=4096
REUSE_ACCOUNT_KEYS="$(lc "${REUSE_ACCOUNT_KEYS:-true}")"
REUSE_PRIVATE_KEYS="$(lc "${REUSE_PRIVATE_KEYS:-false}")"
DEFAULT_KEY_SIZE="${DEFAULT_KEY_SIZE:-4096}"
RENEW_PRIVATE_KEYS="$(lc "${RENEW_PRIVATE_KEYS:-true}")"
function create_link {
local -r source=${1?missing source argument}
local -r target=${2?missing target argument}
if [[ -f "$target" ]] && [[ "$(readlink "$target")" == "$source" ]]; then
set_ownership_and_permissions "$target"
[[ "$DEBUG" == true ]] && echo "$target already linked to $source"
[[ "$DEBUG" == 1 ]] && echo "$target already linked to $source"
return 1
else
ln -sf "$source" "$target" \
@ -62,7 +60,7 @@ function cleanup_links {
symlinked_domain="${symlinked_domain%*.crt}"
SYMLINKED_DOMAINS+=("$symlinked_domain")
done
[[ "$DEBUG" == true ]] && echo "Symlinked domains: ${SYMLINKED_DOMAINS[*]}"
[[ "$DEBUG" == 1 ]] && echo "Symlinked domains: ${SYMLINKED_DOMAINS[*]}"
# Create an array containing domains that are considered
# enabled (ie present on /app/letsencrypt_service_data or /app/letsencrypt_user_data).
@ -77,7 +75,7 @@ function cleanup_links {
ENABLED_DOMAINS+=("$domain")
done
done
[[ "$DEBUG" == true ]] && echo "Enabled domains: ${ENABLED_DOMAINS[*]}"
[[ "$DEBUG" == 1 ]] && echo "Enabled domains: ${ENABLED_DOMAINS[*]}"
# 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
@ -88,28 +86,28 @@ function cleanup_links {
"${ENABLED_DOMAINS[@]}" \
| tr ' ' '\n' | sort | uniq -u)
fi
[[ "$DEBUG" == true ]] && echo "Disabled domains: ${DISABLED_DOMAINS[*]}"
[[ "$DEBUG" == 1 ]] && echo "Disabled domains: ${DISABLED_DOMAINS[*]}"
# Remove disabled domains symlinks if present.
# Return 1 if nothing was removed and 0 otherwise.
if [[ ${#DISABLED_DOMAINS[@]} -gt 0 ]]; then
[[ "$DEBUG" == true ]] && echo "Some domains are disabled :"
[[ "$DEBUG" == 1 ]] && echo "Some domains are disabled :"
for disabled_domain in "${DISABLED_DOMAINS[@]}"; do
[[ "$DEBUG" == true ]] && echo "Checking domain ${disabled_domain}"
cert_folder="$(readlink -f /etc/nginx/certs/"${disabled_domain}".crt)"
[[ "$DEBUG" == 1 ]] && echo "Checking domain ${disabled_domain}"
cert_folder="$(readlink -f "/etc/nginx/certs/${disabled_domain}.crt")"
# If the dotfile is absent, skip domain.
if [[ ! -e "${cert_folder%/*}/.companion" ]]; then
[[ "$DEBUG" == true ]] && echo "No .companion file found in ${cert_folder}. ${disabled_domain} is not managed by letsencrypt-nginx-proxy-companion. Skipping domain."
[[ "$DEBUG" == 1 ]] && echo "No .companion file found in ${cert_folder}. ${disabled_domain} is not managed by letsencrypt-nginx-proxy-companion. Skipping domain."
continue
else
[[ "$DEBUG" == true ]] && echo "${disabled_domain} is managed by letsencrypt-nginx-proxy-companion. Removing unused symlinks."
[[ "$DEBUG" == 1 ]] && echo "${disabled_domain} is managed by letsencrypt-nginx-proxy-companion. Removing unused symlinks."
fi
for extension in .crt .key .dhparam.pem .chain.pem; do
file="${disabled_domain}${extension}"
if [[ -n "${file// }" ]] && [[ -L "/etc/nginx/certs/${file}" ]]; then
[[ "$DEBUG" == true ]] && echo "Removing /etc/nginx/certs/${file}"
[[ "$DEBUG" == 1 ]] && echo "Removing /etc/nginx/certs/${file}"
rm -f "/etc/nginx/certs/${file}"
fi
done
@ -124,6 +122,7 @@ function update_certs {
local -a LETSENCRYPT_CONTAINERS
local -a LETSENCRYPT_STANDALONE_CERTS
pushd /etc/nginx/certs > /dev/null || return
check_nginx_proxy_container_run || return
# Load relevant container settings
@ -163,18 +162,10 @@ function update_certs {
params_d_arr=()
# Use container's LETSENCRYPT_EMAIL if set, fallback to DEFAULT_EMAIL
email_varname="LETSENCRYPT_${cid}_EMAIL"
email_address="${!email_varname:-"<no value>"}"
if [[ "$email_address" != "<no value>" ]]; then
params_d_arr+=(--email "$email_address")
elif [[ -n "${DEFAULT_EMAIL:-}" ]]; then
params_d_arr+=(--email "$DEFAULT_EMAIL")
fi
keysize_varname="LETSENCRYPT_${cid}_KEYSIZE"
cert_keysize="${!keysize_varname:-"<no value>"}"
if [[ "$cert_keysize" == "<no value>" ]]; then
if [[ "$cert_keysize" == "<no value>" ]] || \
[[ ! "$cert_keysize" =~ ^(2048|3072|4096|8192|ec-256|ec-384)$ ]]; then
cert_keysize=$DEFAULT_KEY_SIZE
fi
@ -192,114 +183,61 @@ function update_certs {
certificate_dir="/etc/nginx/certs/$base_domain"
fi
account_varname="LETSENCRYPT_${cid}_ACCOUNT_ALIAS"
account_alias="${!account_varname:-"<no value>"}"
if [[ "$account_alias" == "<no value>" ]]; then
account_alias=default
config_varname="LETSENCRYPT_${cid}_ACMESH_CONFIG"
config_name="${!config_varname:-"<no value>"}"
if [[ "$config_name" == "<no value>" ]]; then
config_name=default
else
[[ ! -d "/etc/acme.sh/$config_name" ]] && mkdir -p "/etc/acme.sh/$config_name"
fi
[[ "$DEBUG" == true ]] && params_d_arr+=(-v)
[[ $REUSE_PRIVATE_KEYS == true ]] && params_d_arr+=(--reuse_key)
[[ "${1}" == "--force-renew" ]] && params_d_arr+=(--valid_min 7776000)
[[ "$DEBUG" == 1 ]] && params_d_arr+=("--debug")
[[ "$RENEW_PRIVATE_KEYS" == true ]] && params_d_arr+=("--always-force-new-domain-key")
[[ "$1" == "--force-renew" ]] && params_d_arr+=("--force")
# Create directory for the first domain,
# make it root readable only and make it the cwd
# Create directory for the first domain
mkdir -p "$certificate_dir"
set_ownership_and_permissions "$certificate_dir"
pushd "$certificate_dir" || return
for domain in "${!hosts_array}"; do
# Add all the domains to certificate
params_d_arr+=(-d "$domain")
params_d_arr+=("--domain" "$domain")
# Add location configuration for the domain
add_location_configuration "$domain" || reload_nginx
done
if [[ -e "./account_key.json" ]] && [[ ! -e "./account_reg.json" ]]; then
# If there is an account key present without account registration, this is
# a leftover from the ACME v1 version of simp_le. Remove this account key.
rm -f ./account_key.json
[[ "$DEBUG" == true ]] \
&& echo "Debug: removed ACME v1 account key $certificate_dir/account_key.json"
fi
# The ACME account key and registration full path are derived from the
# endpoint URI + the account alias (set to 'default' if no alias is provided)
account_dir="../accounts/${acme_ca_uri#*://}"
if [[ $REUSE_ACCOUNT_KEYS == true ]]; then
for type in "key" "reg"; do
file_full_path="${account_dir}/${account_alias}_${type}.json"
simp_le_file="./account_${type}.json"
if [[ -f "$file_full_path" ]]; then
# If there is no symlink to the account file, create it
if [[ ! -L "$simp_le_file" ]]; then
ln -sf "$file_full_path" "$simp_le_file" \
&& set_ownership_and_permissions "$simp_le_file"
# If the symlink target the wrong account file, replace it
elif [[ "$(readlink -f "$simp_le_file")" != "$file_full_path" ]]; then
ln -sf "$file_full_path" "$simp_le_file" \
&& set_ownership_and_permissions "$simp_le_file"
fi
fi
done
fi
echo "Creating/renewal $base_domain certificates... (${hosts_array_expanded[*]})"
/usr/bin/simp_le \
-f account_key.json -f account_reg.json \
-f key.pem -f chain.pem -f fullchain.pem -f cert.pem \
"${params_d_arr[@]}" \
--cert_key_size="$cert_keysize" \
--server="$acme_ca_uri" \
--default_root /usr/share/nginx/html/
acme.sh --issue \
--log /dev/null \
--config-home "/etc/acme.sh/$config_name" \
"${params_d_arr[@]}" \
--keylength "$cert_keysize" \
--server "$acme_ca_uri" \
--webroot /usr/share/nginx/html \
--cert-file "${certificate_dir}/cert.pem" \
--key-file "${certificate_dir}/key.pem" \
--ca-file "${certificate_dir}/chain.pem" \
--fullchain-file "${certificate_dir}/fullchain.pem"
simp_le_return=$?
acmesh_return=$?
if [[ $REUSE_ACCOUNT_KEYS == true ]]; then
mkdir -p "$account_dir"
for type in "key" "reg"; do
file_full_path="${account_dir}/${account_alias}_${type}.json"
simp_le_file="./account_${type}.json"
# If the account file to be reused does not exist yet, copy it
# from the CWD and replace the file in CWD with a symlink
if [[ ! -f "$file_full_path" && -f "$simp_le_file" ]]; then
cp "$simp_le_file" "$file_full_path"
ln -sf "$file_full_path" "$simp_le_file"
fi
done
fi
popd || return
if [[ $simp_le_return -ne 2 ]]; then
if [[ $acmesh_return -ne 2 ]]; then
for domain in "${!hosts_array}"; do
if [[ "$acme_ca_uri" == "$le_staging_uri" ]]; then
if [[ $acme_ca_uri =~ ^https://acme-staging.* ]]; then
create_links "_test_$base_domain" "$domain" && should_reload_nginx='true' && should_restart_container='true'
else
create_links "$base_domain" "$domain" && should_reload_nginx='true' && should_restart_container='true'
fi
done
touch "${certificate_dir}/.companion"
# Set ownership and permissions of the files inside $certificate_dir
for file in .companion cert.pem key.pem chain.pem fullchain.pem account_key.json account_reg.json; do
set_ownership_and_permissions "${certificate_dir}/.companion"
# Make private key root readable only
for file in cert.pem key.pem chain.pem fullchain.pem; do
file_path="${certificate_dir}/${file}"
[[ -e "$file_path" ]] && set_ownership_and_permissions "$file_path"
done
account_path="/etc/nginx/certs/accounts/${acme_ca_uri#*://}"
account_key_perm_path="${account_path}/${account_alias}_key.json"
account_reg_perm_path="${account_path}/${account_alias}_reg.json"
# Account key and registration files do not necessarily exists after
# simp_le exit code 1. Check if they exist before perm check (#591).
[[ -f "$account_key_perm_path" ]] && set_ownership_and_permissions "$account_key_perm_path"
[[ -f "$account_reg_perm_path" ]] && set_ownership_and_permissions "$account_reg_perm_path"
# Set ownership and permissions of the ACME account folder and its
# parent folders (up to /etc/nginx/certs/accounts included)
until [[ "$account_path" == /etc/nginx/certs ]]; do
set_ownership_and_permissions "$account_path"
account_path="$(dirname "$account_path")"
done
# Queue nginx reload if a certificate was issued or renewed
[[ $simp_le_return -eq 0 ]] && should_reload_nginx='true' && should_restart_container='true'
[[ $acmesh_return -eq 0 ]] && should_reload_nginx='true' && should_restart_container='true'
fi
# Restart container if certs are updated and the respective environmental variable is set
@ -311,7 +249,7 @@ function update_certs {
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"
[[ "$DEBUG" == 1 ]] && 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
@ -321,6 +259,8 @@ function update_certs {
cleanup_links && should_reload_nginx='true'
[[ "$should_reload_nginx" == 'true' ]] && reload_nginx
popd > /dev/null || return
}
# Allow the script functions to be sourced without starting the Service Loop.

View File

@ -25,18 +25,16 @@ LETSENCRYPT_CONTAINERS=(
{{ $host := trimSuffix "." $host }}
{{ $hostHash := sha1 $host }}
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_HOST=('{{ $host }}')
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_KEYSIZE="{{ $container.Env.LETSENCRYPT_KEYSIZE }}"
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_TEST="{{ $container.Env.LETSENCRYPT_TEST }}"
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_ACCOUNT_ALIAS="{{ $container.Env.LETSENCRYPT_ACCOUNT_ALIAS }}"
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_ACMESH_CONFIG="{{ $container.Env.LETSENCRYPT_ACMESH_CONFIG }}"
LETSENCRYPT_{{ $cid }}_{{ $hostHash }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
{{ end }}
{{ else }}
LETSENCRYPT_{{ $cid }}_HOST=( {{ range $host := split $hosts "," }}{{ $host := trim $host }}{{ $host := trimSuffix "." $host }}'{{ $host }}' {{ end }})
LETSENCRYPT_{{ $cid }}_EMAIL="{{ $container.Env.LETSENCRYPT_EMAIL }}"
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 }}_ACMESH_CONFIG="{{ $container.Env.LETSENCRYPT_ACMESH_CONFIG }}"
LETSENCRYPT_{{ $cid }}_RESTART_CONTAINER="{{ $container.Env.LETSENCRYPT_RESTART_CONTAINER }}"
{{ end }}
{{ end }}

26
install_acme.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
set -e
# Install git (required to fetch acme.sh)
apk --update add git
# Get acme.sh Let's Encrypt client source
tag="2.8.7"
mkdir /src
git -C /src clone https://github.com/Neilpang/acme.sh.git
cd /src/acme.sh
git checkout "$tag"
# Install acme.sh in /app
./acme.sh --install \
--nocron \
--auto-upgrade 0 \
--home /app \
--config-home /etc/acme.sh/default
# Make house cleaning
cd /
rm -rf /src
apk del git
rm -rf /var/cache/apk/*

View File

@ -1,30 +0,0 @@
#!/bin/bash
set -e
# Install python and packages needed to build simp_le
apk add --update python3 git gcc musl-dev libffi-dev python3-dev openssl-dev
# Create expected symlinks if they don't exist
[[ -e /usr/bin/pip ]] || ln -sf /usr/bin/pip3 /usr/bin/pip
[[ -e /usr/bin/python ]] || ln -sf /usr/bin/python3 /usr/bin/python
# Get Let's Encrypt simp_le client source
branch="0.18.0"
mkdir -p /src
git -C /src clone --depth=1 --branch $branch https://github.com/zenhack/simp_le.git
# Install simp_le in /usr/bin
cd /src/simp_le
#pip install wheel requests
for pkg in pip setuptools wheel
do
pip3 install -U "${pkg?}"
done
pip3 install .
# Make house cleaning
cd /
rm -rf /src
apk del git gcc musl-dev libffi-dev python3-dev openssl-dev
rm -rf /var/cache/apk/*

View File

@ -12,12 +12,16 @@ setup_boulder() {
pushd $GOPATH/src/github.com/letsencrypt/boulder
git checkout release-2019-10-07
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
# 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
# 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

View File

@ -35,7 +35,7 @@ The correct certificate for le2.wtf was served by Nginx.
le3.wtf is on certificate.
Connection to le3.wtf using https was successful.
The correct certificate for le3.wtf was served by Nginx.
Started test web server for le1.wtf.,le2.wtf.,le3.wtf
Started test web server for le1.wtf.,le3.wtf.,le2.wtf
Symlink to le1.wtf certificate has been generated.
The link is pointing to the file ./le1.wtf/fullchain.pem
le1.wtf is on certificate.

View File

@ -21,7 +21,7 @@ function cleanup {
i=$(( $i + 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}
@ -35,7 +35,7 @@ letsencrypt_hosts=( \
[0]="${domains[0]},${domains[1]},${domains[2]}" \ #straight comma separated list
[1]="${domains[1]}, ${domains[2]}, ${domains[0]}" \ #comma separated list with spaces
[2]="${domains[2]}, ${domains[0]}, ${domains[1]}," \ #comma separated list with spaces and a trailing comma
[3]="${domains[0]}.,${domains[1]}.,${domains[2]}" ) #trailing dots
[3]="${domains[0]}.,${domains[2]}.,${domains[1]}" ) #trailing dots
i=1
@ -94,7 +94,7 @@ for hosts in "${letsencrypt_hosts[@]}"; do
done
docker stop "$container" > /dev/null 2>&1
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
i=$(( $i + 1 ))
done

View File

@ -19,7 +19,7 @@ function cleanup {
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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}

View File

@ -21,7 +21,7 @@ function cleanup {
i=$(( $i + 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}
@ -99,7 +99,7 @@ for hosts in "${letsencrypt_hosts[@]}"; do
done
docker stop "$container" > /dev/null 2>&1
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
i=$(( $i + 1 ))
done

View File

@ -17,7 +17,7 @@ function cleanup {
# Remove the Nginx container silently.
docker rm --force "$subdomain" > /dev/null 2>&1
# 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}

View File

@ -29,7 +29,7 @@ function cleanup {
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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}

View File

@ -17,7 +17,7 @@ function cleanup {
# Remove the Nginx container silently.
docker rm --force "${domains[0]}" > /dev/null 2>&1
# 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}

View File

@ -23,7 +23,7 @@ function cleanup {
# Remove the ${domains[0]} Nginx container silently.
docker rm --force "${domains[0]}" > /dev/null 2>&1
# 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}
@ -41,10 +41,7 @@ wait_for_symlink "${domains[0]}" "$le_container_name"
# Array of folder paths to test
folders=( \
[0]="/etc/nginx/certs/accounts" \
[1]="/etc/nginx/certs/accounts/boulder:4001" \
[2]="/etc/nginx/certs/accounts/boulder:4001/directory" \
[3]="/etc/nginx/certs/${domains[0]}" \
[0]="/etc/nginx/certs/${domains[0]}" \
)
# Test folder paths
@ -61,8 +58,6 @@ symlinks=( \
[1]="/etc/nginx/certs/${domains[0]}.key" \
[2]="/etc/nginx/certs/${domains[0]}.chain.pem" \
[3]="/etc/nginx/certs/${domains[0]}.dhparam.pem" \
[4]="/etc/nginx/certs/${domains[0]}/account_key.json" \
[5]="/etc/nginx/certs/${domains[0]}/account_reg.json" \
)
# Test symlinks paths
@ -76,9 +71,7 @@ symlinks=( \
# Array of private file paths to test
private_files=( \
[0]="/etc/nginx/certs/default.key" \
[1]="/etc/nginx/certs/accounts/boulder:4001/directory/default_key.json" \
[2]="/etc/nginx/certs/accounts/boulder:4001/directory/default_reg.json" \
[3]="/etc/nginx/certs/${domains[0]}/key.pem" \
[1]="/etc/nginx/certs/${domains[0]}/key.pem" \
)
# Test private file paths

View File

@ -17,7 +17,7 @@ function cleanup {
# Remove the ${domains[0]} Nginx container silently.
docker rm --force "${domains[0]}" > /dev/null 2>&1
# 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}
@ -35,10 +35,7 @@ wait_for_symlink "${domains[0]}" "$le_container_name"
# Array of folder paths to test
folders=( \
[0]="/etc/nginx/certs/accounts" \
[1]="/etc/nginx/certs/accounts/boulder:4001" \
[2]="/etc/nginx/certs/accounts/boulder:4001/directory" \
[3]="/etc/nginx/certs/${domains[0]}" \
[0]="/etc/nginx/certs/${domains[0]}" \
)
# Test folder paths
@ -55,8 +52,6 @@ symlinks=( \
[1]="/etc/nginx/certs/${domains[0]}.key" \
[2]="/etc/nginx/certs/${domains[0]}.chain.pem" \
[3]="/etc/nginx/certs/${domains[0]}.dhparam.pem" \
[4]="/etc/nginx/certs/${domains[0]}/account_key.json" \
[5]="/etc/nginx/certs/${domains[0]}/account_reg.json" \
)
# Test symlinks paths
@ -70,9 +65,7 @@ symlinks=( \
# Array of private file paths to test
private_files=( \
[0]="/etc/nginx/certs/default.key" \
[1]="/etc/nginx/certs/accounts/boulder:4001/directory/default_key.json" \
[2]="/etc/nginx/certs/accounts/boulder:4001/directory/default_reg.json" \
[3]="/etc/nginx/certs/${domains[0]}/key.pem" \
[1]="/etc/nginx/certs/${domains[0]}/key.pem" \
)
# Test private file paths

View File

@ -23,8 +23,8 @@ function cleanup {
symlink-lim-le2 \
> /dev/null 2>&1
# 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*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/lim.it*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/le?.wtf* && rm -rf /etc/acme.sh/default/le?.wtf*'
docker exec "$le_container_name" bash -c 'rm -rf /etc/nginx/certs/lim.it* && rm -rf /etc/acme.sh/default/lim.it*'
# Stop the LE container
docker stop "$le_container_name" > /dev/null
}

View File

@ -23,7 +23,7 @@ function run_le_container {
--volume /var/run/docker.sock:/var/run/docker.sock:ro \
$cli_args \
--env "DHPARAM_BITS=256" \
--env "DEBUG=true" \
--env "DEBUG=2" \
--env "ACME_CA_URI=http://boulder:4001/directory" \
--label com.github.jrcs.letsencrypt_nginx_proxy_companion.test_suite \
--network boulder_bluenet \