#!/bin/bash DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" seconds_to_wait=3600 ACME_CA_URI="${ACME_CA_URI:-https://acme-v01.api.letsencrypt.org/directory}" ACME_TOS_HASH="${ACME_TOS_HASH:-6373439b9f29d67a5cd4d18cbc7f264809342dbf21cb2ba2fc7588df987a6221}" DEFAULT_KEY_SIZE=4096 source /app/functions.sh create_link() { local readonly target=${1?missing target argument} local readonly source=${2?missing source argument} [[ -f "$target" ]] && return 1 ln -sf "$source" "$target" } create_links() { local readonly base_domain=${1?missing base_domain argument} local readonly domain=${2?missing base_domain argument} if [[ ! -f "/etc/nginx/certs/$base_domain"/fullchain.pem || \ ! -f "/etc/nginx/certs/$base_domain"/key.pem ]]; then return 1 fi local return_code=1 create_link "/etc/nginx/certs/$domain".crt "./$base_domain"/fullchain.pem return_code=$(( $return_code & $? )) create_link "/etc/nginx/certs/$domain".key "./$base_domain"/key.pem return_code=$(( $return_code & $? )) if [[ -f "/etc/nginx/certs/dhparam.pem" ]]; then create_link "/etc/nginx/certs/$domain".dhparam.pem ./dhparam.pem return_code=$(( $return_code & $? )) fi if [[ -f "/etc/nginx/certs/$base_domain"/chain.pem ]]; then create_link "/etc/nginx/certs/$domain".chain.pem "./$base_domain"/chain.pem return_code=$(( $return_code & $? )) fi return $return_code } update_certs() { [[ ! -f "$DIR"/letsencrypt_service_data ]] && return # Load relevant container settings unset LETSENCRYPT_CONTAINERS source "$DIR"/letsencrypt_service_data reload_nginx='false' for cid in "${LETSENCRYPT_CONTAINERS[@]}"; do # Derive host and email variable names host_varname="LETSENCRYPT_${cid}_HOST" # Array variable indirection hack: http://stackoverflow.com/a/25880676/350221 hosts_array=$host_varname[@] email_varname="LETSENCRYPT_${cid}_EMAIL" keysize_varname="LETSENCRYPT_${cid}_KEYSIZE" cert_keysize="${!keysize_varname}" if [[ "$cert_keysize" == "" ]]; then cert_keysize=$DEFAULT_KEY_SIZE fi test_certificate_varname="LETSENCRYPT_${cid}_TEST" create_test_certificate=false if [[ $(lc "${!test_certificate_varname:-}") == true ]]; then create_test_certificate=true fi params_d_str="" [[ $DEBUG == true ]] && params_d_str+=" -v" hosts_array_expanded=("${!hosts_array}") # First domain will be our base domain base_domain="${hosts_array_expanded[0]}" if [[ "$create_test_certificate" == true ]]; then # Use staging acme end point acme_ca_uri="https://acme-staging.api.letsencrypt.org/directory" if [[ ! -f /etc/nginx/certs/.${base_domain}.test ]]; then # Remove old certificates rm -rf /etc/nginx/certs/${base_domain} for domain in "${!hosts_array}"; do rm -f /etc/nginx/certs/$domain.{crt,key,dhparam.pem} done touch /etc/nginx/certs/.${base_domain}.test fi else acme_ca_uri="$ACME_CA_URI" if [[ -f /etc/nginx/certs/.${base_domain}.test ]]; then # Remove old test certificates rm -rf /etc/nginx/certs/${base_domain} for domain in "${!hosts_array}"; do rm -f /etc/nginx/certs/$domain.{crt,key,dhparam.pem} done rm -f /etc/nginx/certs/.${base_domain}.test fi fi # Create directory for the first domain mkdir -p /etc/nginx/certs/$base_domain cd /etc/nginx/certs/$base_domain for domain in "${!hosts_array}"; do # Add all the domains to certificate params_d_str+=" -d $domain" # Add location configuration for the domain add_location_configuration "$domain" || reload_nginx done echo "Creating/renewal $base_domain certificates... (${hosts_array_expanded[*]})" /usr/bin/simp_le \ -f account_key.json -f key.pem -f chain.pem -f fullchain.pem -f cert.pem \ --tos_sha256 $ACME_TOS_HASH \ $params_d_str \ --cert_key_size=$cert_keysize \ --email "${!email_varname}" \ --server=$acme_ca_uri \ --default_root /usr/share/nginx/html/ simp_le_return=$? for altnames in ${hosts_array_expanded[@]:1}; do # Remove old CN domain that now are altnames rm -rf /etc/nginx/certs/$altnames done if [[ -z $base_domain ]]; then echo "inavalid stuff from container: ${cid}" fi if [[ ! -z $base_domain ]]; then for domain in "${!hosts_array}"; do create_links $base_domain $domain && reload_nginx='true' [[ $simp_le_return -eq 0 ]] && reload_nginx='true' done fi done [[ "$reload_nginx" == 'true' ]] && reload_nginx } pid= # Service Loop: When this script exits, start it again. trap '[[ $pid ]] && kill $pid; exec $0' EXIT trap 'trap - EXIT' INT TERM update_certs # Wait some amount of time echo "Sleep for ${seconds_to_wait}s" sleep $seconds_to_wait & pid=$! wait pid=