diff --git a/Dockerfile b/Dockerfile index d7c1b83..3116ad7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,17 +11,30 @@ FROM base-${TARGETARCH}${TARGETVARIANT} ARG S6_OVERLAY_VERSION=3.1.5.0 -ENV DOMAINS= -ENV EMAIL= -ENV INTERVAL="0 */6 * * *" -ENV STAGING=false -ENV PROPOGATION_TIME=10 -ENV GENERATE_DHPARAM=true -ENV TZ=UTC +# Core variables ENV PUID=1000 ENV PGID=1000 +ENV TZ=UTC +ENV GENERATE_DHPARAM=true +ENV INTERVAL="0 */6 * * *" + +# Single domain +ENV DOMAINS= +ENV EMAIL= +ENV STAGING=false + +# Custom CA support +ENV CUSTOM_CA= +ENV CUSTOM_CA_SERVER= + +# Different plugin support (to support Cloudflare but also normal mode) +ENV PLUGIN=standalone +ENV PROPOGATION_TIME=10 ENV CLOUDFLARE_TOKEN= +## Multi-cert support +ENV CERT_COUNT=1 + #Get required packages RUN apk update && apk add curl bash python3 py3-virtualenv procps tzdata nano shadow xz busybox-suid openssl diff --git a/README.md b/README.md index c6cdc14..3c5655b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![Drone (self-hosted) with branch](https://img.shields.io/drone/build/MrMeeb/certbot-cron-docker/master?label=latest&server=https%3A%2F%2Fdrone.mrmeeb.stream&style=for-the-badge) ![Drone (self-hosted) with branch](https://img.shields.io/drone/build/MrMeeb/certbot-cron-docker/develop?label=develop&server=https%3A%2F%2Fdrone.mrmeeb.stream&style=for-the-badge) -Dockerised Certbot that utilises cron to schedule creating and renewing SSL certificates. Uses Cloudflare for DNS-01 verification. Automatic renewal attempt happens every 6 hours by default. +Dockerised Certbot that utilises cron to schedule creating and renewing SSL certificates. Supports standalone, webroot or Cloudflare methods. Automatic renewal attempt happens every 6 hours by default. ## Tags @@ -14,17 +14,18 @@ Dockerised Certbot that utilises cron to schedule creating and renewing SSL cert ## Running ### Docker CLI -``` +```bash docker run -d --name certbot \ -e EMAIL=admin@domain.com \ -e DOMAINS=domain.com \ + -e PLUGIN=cloudflare \ -e CLOUDFLARE_TOKEN=123abc - -v /docker/certbot-cron:/config \ + -v ./certbot-cron:/config \ git.mrmeeb.stream/mrmeeb/certbot-cron:latest ``` ### Docker Compose -``` +```yaml version: "3" services: certbot: @@ -36,30 +37,153 @@ services: environment: - EMAIL=admin@domain.com - DOMAINS=domain.com,*.domain.com + - PLUGIN=cloudflare - CLOUDFLARE_TOKEN=123abc ``` ## Environment Variables: -| Variable | Default Value | Description | +### Core Options: + +Core options to the container + +| Variable | Default | Description | | --- | --- | --- | |PUID |int |1000 |Sets the UID of the user certbot runs under | |PGID |int |1000 |Sets the GID of the user certbot runs under | |TZ |[List of valid TZs](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List) |UTC |Sets the timezone of the container | +| GENERATE_DHPARAM | true (case-sensitive) | Generate Diffie-Hellman keys in /config/letsencrypt/keys | +| INTERVAL | 0 */6 * * * | How often certbot attempts to renew the certificate. Cron syntax | +| CERT_COUNT | 1 | How many certificates certbot will try to issue (more than 1 not yet implemented) | + +### Certificate Options + +These options apply when `CERT_COUNT` is `1` + +| Variable | Default | Description | +| --- | --- | --- | | EMAIL | None | Email address for renewal information & other communications | | DOMAINS | None | Domains to be included in the certificate. Comma separated list, no spaces. Wildcards supported | -| INTERVAL | 0 */6 * * * | How often certbot attempts to renew the certificate. Cron syntax | -| STAGING | false (case-sensitive) | Uses the LetsEncrypt staging endpoint for testing - avoids the aggressive rate-limiting of the production endpoint | +| STAGING | false (case-sensitive) | Uses the LetsEncrypt staging endpoint for testing - avoids the aggressive rate-limiting of the production endpoint. **Not supported when using a custom Certificate Authority.** | + +### Plugins + +Plugins that can used for issuing a certificate + +| Variable | Default | Description | +| --- | --- | --- | +| PLUGIN | standalone | Options are `webroot`, `standalone`, or `cloudflare` | + +- `webroot` - relies on a webserver running on the FQDN for which you're trying to issue a certificate to serve validation files + - Requires the webserver's root directory to be mounted to the container as `/config/webroot` +- `standalone` - certbot spawns a webserver on port 80 for validation + - Requires this container to be bound to port 80 on the host +- `cloudflare` - Creates a TXT record with Cloudflare pointing to the domain you're requesting a certificate for + - Requires the domain you're requesting a certificate for to be entered in Cloudflare + +#### Cloudflare Plugin + +Options that affect the behaviour of certbot running with the Cloudflare plugin + +| Variable | Default | Description | +| --- | --- | --- | | PROPOGATION_TIME | 10 | The amount of time (seconds) that certbot waits for the TXT records to propogate to Cloudflare before verifying - the more domains in the certificate, the longer you might need | -| GENERATE_DHPARAM | true (case-sensitive) | Generate Diffie-Hellman keys in /config/letsencrypt/keys | -| CLOUDFLARE_TOKEN | N/A | Cloudflare token for verification | +| CLOUDFLARE_TOKEN | null | Cloudflare token for verification | + +### Custom Certificate Authority + +Options to use a custom Certificate Authority, for example when issuing internal certificates + +| Variable | Default | Description | +| --- | --- | --- | +| CUSTOM_CA | null | Name of the root certificate Certbot/ACME will trust requesting the certificate, e.g `root.pem`. **Must be placed in `/config/custom_ca`** | +| CUSTOM_CA_SERVER | null | Custom server URL used by Certbot/ACME when requesting a certificate, e.g `https://ca.internal/acme/acme/directory` | + +### Multiple Certificates + +This container can issue multiple certificates each containing different domains. This could be used to issue a certificate for a public domain on Cloudflare, but then also for a local certificate from an internal Certificate Authority, for example. Another example would be you have a web-server hosting two separate websites and you want them to have dedicated SSL certificates instead of sharing one. + +When issuing multiple certificates, first `CERT_COUNT` must be set to a value greater than 1. + +#### Global Environment Variables + +Some environment variables can be set globally, where they apply to all certificates (unless otherwise specifically specified). The following can be used globally: + +| Variable | DESCRIPTION | +| --- | --- | +|EMAIL| Email address for renewal information & other communications | +|STAGING| Uses the LetsEncrypt staging endpoint for testing - avoids the aggressive rate-limiting of the production endpoint. **Not supported when using a custom Certificate Authority.** | +|CUSTOM_CA| Name of the root certificate Certbot/ACME will trust requesting the certificate, e.g `root.pem`. **Must be placed in `/config/custom_ca`** | +|CUSTOM_CA_SERVER| Custom server URL used by Certbot/ACME when requesting a certificate, e.g `https://ca.internal/acme/acme/directory` | +|PLUGIN| Options are `webroot`, `standalone`, or `cloudflare` | +|PROPOGATION_TIME| **(Applies to Cloudflare plugin)** The amount of time (seconds) that certbot waits for the TXT records to propogate to Cloudflare before verifying - the more domains in the certificate, the longer you might need | + +More detail on these environment variables may be found further up. + +#### Certificate-specific Environment Variables + +Any variable other than those described as **Core Options** can be set per-certificate in a multi-certificate environment. The syntax is `${VARIABLE_NAME}_${CERT_NUMBER}`. The only certificate-specific option that **must** be set is the `DOMAINS` option. + +##### Multi-certificate container using global variables: + +```yaml + certbot: + container_name: certbot + image: git.mrmeeb.stream/mrmeeb/certbot-cron + volumes: + - /docker/certbot-cron:/config + - /docker/nginx/www:/config/webroot + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/London + - GENERATE_DHPARAM=false + - CERT_COUNT=2 + - EMAIL=admin@domain.com + - CUSTOM_CA=root.pem + - CUSTOM_CA_SERVER=https://ca.internal/acme/acme/directory + - PLUGIN=webroot + - STAGING=false + - DOMAINS_1=website1.com + - DOMAINS_2=website2.com +``` + +##### Multi-certificate container using different options for each certificate: +```yaml + certbot: + container_name: certbot + image: git.mrmeeb.stream/mrmeeb/certbot-cron + volumes: + - /docker/certbot-cron:/config + - /docker/nginx/www:/config/webroot + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/London + - GENERATE_DHPARAM=false + - CERT_COUNT=2 + - EMAIL=admin@domain.com + - DOMAINS_1=website1.com + - CUSTOM_CA_1=root.pem + - CUSTOM_CA_SERVER_1=https://ca.internal/acme/acme/directory + - PLUGIN_1=webroot + - STAGING_1=false + - DOMAINS_2=website2.com + - PLUGIN_2=cloudflare + - CLOUDFLARE_TOKEN_2=abc123 + - PROPOGATION_TIME_2=30 + - STAGING_2=true +``` ## Volumes | Docker path | Purpose | | --- | --- | | /config | Stores configs and LetsEncrypt output for mounting in other containers +| /config/webroot | Mountpoint for the webroot of a separate webserver. **Required if `PLUGIN=webroot` is set** -## Other +## Ports -Thanks to [this guy](https://stackoverflow.com/questions/63447441/docker-stop-for-crond-times-out) for explaining how to make cron actually shutdown when stopping the container. \ No newline at end of file +| Port | Purpose | +| --- | --- | +| 80 | Used by ACME to verify domain ownership. **Required if `PLUGIN=standalone` is set** \ No newline at end of file diff --git a/root/certbot-prepare.sh b/root/certbot-prepare.sh index d7c6437..55c2c41 100644 --- a/root/certbot-prepare.sh +++ b/root/certbot-prepare.sh @@ -1,7 +1,10 @@ #!/command/with-contenv bash # shellcheck shell=bash -#Creating needed folders and files if they don't already exist +# Halt container if anything returns a non-zero exit code +set -e + +# Creating needed folders and files if they don't already exist if [ ! -d /config/.secrets ] then mkdir /config/.secrets @@ -32,54 +35,734 @@ then touch /config/.crontab.txt fi -if [ ! -f /config/.secrets/cloudflare.ini ] +function better_exit { + + echo "" + echo "" + echo "" + echo "You can ignore the below error messages - they happened because the container exited with a non-0 exit code due misconfiguration" + echo "==========================================================" + exit 1 + +} + +# Cleanup renew list and create it fresh, ready for commands to be run and added +echo "#!/command/with-contenv bash" > /config/.renew-list.sh +echo "" >> /config/.renew-list.sh + +# Create original config file to track changes to environmental variables +if [ ! -f /config/.donoteditthisfile ] then - touch /config/.secrets/cloudflare.ini + echo -e "ORIGDOMAINS=\"${DOMAINS}\" ORIGEMAIL=\"${EMAIL}\" ORIGSTAGING=\"${STAGING}\" ORIGCUSTOM_CA=\"${CUSTOM_CA}\" ORIGCUSTOM_CA_SERVER=\"${CUSTOM_CA_SERVER}\" ORIGPLUGIN=\"${PLUGIN}\" ORIGPROPOGATION_TIME=\"${PROPOGATION_TIME}\" ORIGCERT_COUNT=${CERT_COUNT}" > /config/.donoteditthisfile fi -if [ -n "$CLOUDFLARE_TOKEN" ] -then - echo "Cloudflare token is present" +# Load original config file +. /config/.donoteditthisfile - echo "dns_cloudflare_api_token = $CLOUDFLARE_TOKEN" > /config/.secrets/cloudflare.ini +# Revoke all certs if CERT_COUNT has decreased, starting fresh +if [ "${CERT_COUNT}" -lt "${ORIGCERT_COUNT}" ]; then + + echo "" + + echo "CERT_COUNT has decreased - revoking all certificates then reissuing to cleanup any lingerers." + + # Use .donoteditthisfile_cert_* to get details of each issued certificate to revoke with correct parameters + + x=1 + while [ $x -le ${ORIGCERT_COUNT} ]; do + + # Load config of particular cert + . /config/.donoteditthisfile_cert_${x} + + # Setting up variables (requires two passes to clean away requirement for indirect variables) + ## Pass 1 + DOMAINS_P1=ORIGDOMAINS_${x} + EMAIL_P1=ORIGEMAIL_${x} + STAGING_P1=ORIGSTAGING_${x} + CUSTOM_CA_P1=ORIGCUSTOM_CA_${x} + CUSTOM_CA_SERVER_P1=ORIGCUSTOM_CA_SERVER_${x} + PLUGIN_P1=ORIGPLUGIN_${x} + PROPOGATION_TIME_P1=ORIGPROPOGATION_TIME_${x} + CLOUDFLARE_TOKEN_P1=ORIGCLOUDFLARE_TOKEN_${x} + + ## Pass 2 + DOMAINS_MULTI=${!DOMAINS_P1} + EMAIL_MULTI=${!EMAIL_P1} + STAGING_MULTI=${!STAGING_P1} + CUSTOM_CA_MULTI=${!CUSTOM_CA_P1} + CUSTOM_CA_SERVER_MULTI=${!CUSTOM_CA_SERVER_P1} + PLUGIN_MULTI=${!PLUGIN_P1} + PROPOGATION_TIME_MULTI=${!PROPOGATION_TIME_P1} + CLOUDFLARE_TOKEN_MULTI=${!CLOUDFLARE_TOKEN_P1} + + FIRST_DOMAIN_MULTI=$(echo ${DOMAINS_MULTI} | cut -d \, -f1) + + echo ${FIRST_DOMAIN_MULTI} + + if [ ! -z ${CUSTOM_CA_MULTI} ] + then + + echo "A custom CA was used for issuing certificate ${x}. Using it to revoke as well." + + if [ ! -d /config/custom_ca ] + then + mkdir /config/custom_ca + echo "Please place the custom CA root file used to generate the current certificate ${x} into /config/custom_ca and restart the container" + better_exit + fi + + if [ -z "$(ls -A /config/custom_ca)" ] + then + echo "A root certificate called ${CUSTOM_CA_MULTI} was used to generate a certificate, but the /config/custom_ca dir is now empty. Please place this root certificate back this directory and restart the container so it can be safely revoked" + better_exit + fi + + CUSTOM_CA_PATH_MULTI=/config/custom_ca/${CUSTOM_CA_MULTI} + CUSTOM_CA_SERVER_OPT_MULTI="--server ${CUSTOM_CA_SERVER_MULTI}" + + fi + + if [ $STAGING_MULTI = "true" ] + then + + # Reusing the CUSTOM_CA_SERVER_OPT variable to add staging option if that was selected + CUSTOM_CA_SERVER_OPT_MULTI="--server https://acme-staging-v02.api.letsencrypt.org/directory" + + fi + + if [ -f /config/letsencrypt/live/"${FIRST_DOMAIN_MULTI}"/fullchain.pem ] + then + + REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH_MULTI certbot revoke --non-interactive --agree-tos --email $EMAIL_MULTI --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --cert-path /config/letsencrypt/live/"${FIRST_DOMAIN_MULTI}"/fullchain.pem ${CUSTOM_CA_SERVER_OPT_MULTI} || true + + rm -rf /config/letsencrypt/archive/"${FIRST_DOMAIN_MULTI}" + rm -rf /config/letsencrypt/live/"${FIRST_DOMAIN_MULTI}" + rm -rf /config/letsencrypt/renewal/"${FIRST_DOMAIN_MULTI}".conf + + fi + + # Delete .donoteditthisfile_cert_${x} + rm -rf /config/.donoteditthisfile_cert_${x} + + # Scrubbing variables before running next cert revoke to prevent overlap of values + DOMAINS_MULTI= + EMAIL_MULTI= + STAGING_MULTI= + CUSTOM_CA_MULTI= + CUSTOM_CA_SERVER_MULTI= + PLUGIN_MULTI= + PROPOGATION_TIME_MULTI= + CLOUDFLARE_TOKEN_MULTI= + CUSTOM_CA_PATH_MULTI= + CUSTOM_CA_SERVER_OPT_MULTI= + + x=$(( $x + 1 )) + + done + + echo "Tidying up any potential lingering ACME challenges in /config/webroot from failed webroot activations" + rm -rf /config/webroot/.well-known/acme-challenge fi -if [ ! -s /config/.secrets/cloudflare.ini ] -then - echo "cloudflare.ini is empty - please add your Cloudflare credentials or API key before continuing. This can be done as an ENV var, or by editing the file directly" +function single_domain { - exit 22 + # Checking for changes to config file, revoke certs if necessary + if [ ! "${DOMAINS}" = "${ORIGDOMAINS}" ] || + [ ! "${EMAIL}" = "${ORIGEMAIL}" ] || + [ ! "${STAGING}" = "${ORIGSTAGING}" ] || + [ ! "${CUSTOM_CA}" = "${ORIGCUSTOM_CA}" ] || + [ ! "${CUSTOM_CA_SERVER}" = "${ORIGCUSTOM_CA_SERVER}" ] || + [ ! "${PLUGIN}" = "${ORIGPLUGIN}" ] || + [ ! "${PROPOGATION_TIME}" = "${ORIGPROPOGATION_TIME}" ] + then + + echo "" + + echo "Configuration has changed since the last certificate was issued. Revoking and regenerating certs" + FIRST_DOMAIN=$(echo $ORIGDOMAINS | cut -d \, -f1) + + if [ ! -z $ORIGCUSTOM_CA ] + then + + echo "A custom CA was used for issuing. Using it to revoke as well." + + if [ ! -d /config/custom_ca ] + then + mkdir /config/custom_ca + echo "Please place the custom CA root file used to generate the current certificate into /config/custom_ca and restart the container" + better_exit + fi + + if [ -z "$(ls -A /config/custom_ca)" ] + then + echo "A root certificate called ${ORIGCUSTOM_CA} was used to generate a certificate, but the /config/custom_ca dir is now empty. Please place this root certificate back this directory and restart the container so it can be safely revoked" + better_exit + fi + + ORIGCUSTOM_CA_PATH=/config/custom_ca/$ORIGCUSTOM_CA + ORIGCUSTOM_CA_SERVER_OPT="--server $ORIGCUSTOM_CA_SERVER" + + fi + + if [ $ORIGSTAGING = "true" ] + then + + # Reusing the CUSTOM_CA_SERVER_OPT variable to add staging option if that was selected + ORIGCUSTOM_CA_SERVER_OPT="--server https://acme-staging-v02.api.letsencrypt.org/directory" + + fi + + if [ -f /config/letsencrypt/live/"${FIRST_DOMAIN}"/fullchain.pem ] + then + + REQUESTS_CA_BUNDLE=$ORIGCUSTOM_CA_PATH certbot revoke --non-interactive --agree-tos --email $ORIGEMAIL --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --cert-path /config/letsencrypt/live/"${FIRST_DOMAIN}"/fullchain.pem $ORIGCUSTOM_CA_SERVER_OPT || true + + rm -rf /config/letsencrypt/archive/"${FIRST_DOMAIN}" + rm -rf /config/letsencrypt/live/"${FIRST_DOMAIN}" + rm -rf /config/letsencrypt/renewal/"${FIRST_DOMAIN}".conf + + fi + + fi + + # Update config file with new env vars + echo -e "ORIGDOMAINS=\"${DOMAINS}\" ORIGEMAIL=\"${EMAIL}\" ORIGSTAGING=\"${STAGING}\" ORIGCUSTOM_CA=\"${CUSTOM_CA}\" ORIGCUSTOM_CA_SERVER=\"${CUSTOM_CA_SERVER}\" ORIGPLUGIN=\"${PLUGIN}\" ORIGPROPOGATION_TIME=\"${PROPOGATION_TIME}\" ORIGCERT_COUNT=${CERT_COUNT}" > /config/.donoteditthisfile + + echo "" + + if [ ! -z $CUSTOM_CA ] + then + + echo "Using a custom CA for issuing certificates" + + if [ ! -d /config/custom_ca ] + then + mkdir /config/custom_ca + echo "Please place your custom CA file into /config/custom_ca and restart the container" + better_exit + fi + + if [ -z "$(ls -A /config/custom_ca)" ] + then + echo "The CUSTOM_CA option is populated, but the /config/custom_ca dir is empty. Please place your root certificate in this directory and restart the container" + better_exit + fi + + if [ -z $CUSTOM_CA_SERVER ] + then + echo "CUSTOM_CA_SERVER has not been defined. It is required for using a custom CA to issue a certificate" + better_exit + fi + + CUSTOM_CA_PATH=/config/custom_ca/$CUSTOM_CA + CUSTOM_CA_SERVER_OPT="--server $CUSTOM_CA_SERVER" + + if [ $STAGING = "true" ] + then + + echo "Staging option is not supported when using a custom CA. To remove this alert, set staging to false. If your CA has a standing endpoint, use the CUSTOM_CA_SERVER option to point to it instead" + better_exit + + fi + + fi + + BASE_COMMAND=(certbot certonly --non-interactive --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --key-path /config/letsencrypt/keys --expand --agree-tos $CUSTOM_CA_SERVER_OPT --email $EMAIL -d $DOMAINS) + + ## Run with Cloudflare plugin + if [ $PLUGIN == "cloudflare" ] + then + + echo "Using Cloudflare plugin" + + if [ ! -f /config/.secrets/cloudflare.ini ] + then + touch /config/.secrets/cloudflare.ini + fi + + if [ -n "$CLOUDFLARE_TOKEN" ] + then + echo "Cloudflare token is present" + + echo "dns_cloudflare_api_token = $CLOUDFLARE_TOKEN" > /config/.secrets/cloudflare.ini + + fi + + if [ ! -s /config/.secrets/cloudflare.ini ] + then + echo "cloudflare.ini is empty - please add your Cloudflare credentials or API key before continuing. This can be done by setting CLOUDFLARE_TOKEN, or by editing /config/.secrets/cloudflare.ini directly" + + better_exit + fi + + #Securing cloudflare.ini to supress warnings + chmod 600 /config/.secrets/cloudflare.ini + + echo "Creating certificates, or attempting to renew if they already exist" + + if [ $STAGING = true ] + then + echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" + ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --staging + # Add to renewal list + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --staging" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + elif [ $STAGING = false ] + then + echo "Using production endpoint" + ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini + # Add to renewal list + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + else + echo "Unrecognised option for STAGING variable - check your configuration" + + better_exit + fi + + ## Run with Standalone plugin + elif [ $PLUGIN == "standalone" ] + then + + echo "Using HTTP verification via built-in web-server - please ensure port 80 is exposed." + + if [ $STAGING = true ] + then + echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" + REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --standalone --staging + # Add to renewal list + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --standalone --staging" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + elif [ $STAGING = false ] + then + echo "Using production endpoint" + REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --standalone + # Add to renewal list + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --standalone" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + else + echo "Unrecognised option for STAGING variable - check your configuration" + + better_exit + fi + + ## Run with webroot plugin + elif [ $PLUGIN == "webroot" ] + then + + echo "Using HTTP verification via webroot - please ensure you have mounted a webroot at /config/webroot from a web-server reachable via the domain you are issuing a certificate for." + + if [ $STAGING = true ] + then + echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" + REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot --staging + # Add to renewal list + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot --staging" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + elif [ $STAGING = false ] + then + echo "Using production endpoint" + REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot + # Add to renewal list + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + else + echo "Unrecognised option for STAGING variable - check your configuration" + + better_exit + fi + + else + + echo "Unrecognised option for PLUGIN variable - check your configuration" + + fi + +} + +function multi_domain { + + # Update config file with new env vars + echo -e "ORIGDOMAINS=\"${DOMAINS}\" ORIGEMAIL=\"${EMAIL}\" ORIGSTAGING=\"${STAGING}\" ORIGCUSTOM_CA=\"${CUSTOM_CA}\" ORIGCUSTOM_CA_SERVER=\"${CUSTOM_CA_SERVER}\" ORIGPLUGIN=\"${PLUGIN}\" ORIGPROPOGATION_TIME=\"${PROPOGATION_TIME}\" ORIGCERT_COUNT=${CERT_COUNT}" > /config/.donoteditthisfile + + ## Start multi-domain looper + x=1 + while [ $x -le $CERT_COUNT ] + do + + # Setting up variables (requires two passes to clean away requirement for indirect variable) + ## Pass 1 + DOMAINS_P1=DOMAINS_${x} + EMAIL_P1=EMAIL_${x} + STAGING_P1=STAGING_${x} + CUSTOM_CA_P1=CUSTOM_CA_${x} + CUSTOM_CA_SERVER_P1=CUSTOM_CA_SERVER_${x} + PLUGIN_P1=PLUGIN_${x} + PROPOGATION_TIME_P1=PROPOGATION_TIME_${x} + CLOUDFLARE_TOKEN_P1=CLOUDFLARE_TOKEN_${x} + + ## Pass 2 + DOMAINS_MULTI=${!DOMAINS_P1} + EMAIL_MULTI=${!EMAIL_P1} + STAGING_MULTI=${!STAGING_P1} + CUSTOM_CA_MULTI=${!CUSTOM_CA_P1} + CUSTOM_CA_SERVER_MULTI=${!CUSTOM_CA_SERVER_P1} + PLUGIN_MULTI=${!PLUGIN_P1} + PROPOGATION_TIME_MULTI=${!PROPOGATION_TIME_P1} + CLOUDFLARE_TOKEN_MULTI=${!CLOUDFLARE_TOKEN_P1} + + # Inheriting global default if undefined for certain variables + if [ -z ${EMAIL_MULTI} ]; then + EMAIL_MULTI=${EMAIL} + fi + + if [ -z ${STAGING_MULTI} ]; then + STAGING_MULTI=${STAGING} + fi + + if [ -z ${CUSTOM_CA_MULTI} ]; then + CUSTOM_CA_MULTI=${CUSTOM_CA} + fi + + if [ -z ${CUSTOM_CA_SERVER_MULTI} ]; then + CUSTOM_CA_SERVER_MULTI=${CUSTOM_CA_SERVER} + fi + + if [ -z ${PLUGIN_MULTI} ]; then + PLUGIN_MULTI=${PLUGIN} + fi + + if [ -z ${PROPOGATION_TIME_MULTI} ]; then + PROPOGATION_TIME_MULTI=${PROPOGATION_TIME} + fi + + # Create original config file to track changes to environmental variables + if [ ! -f /config/.donoteditthisfile_cert_${x} ] + then + echo -e "ORIGDOMAINS_${x}=\"${DOMAINS_MULTI}\" ORIGEMAIL_${x}=\"${EMAIL_MULTI}\" ORIGSTAGING_${x}=\"${STAGING_MULTI}\" ORIGCUSTOM_CA_${x}=\"${CUSTOM_CA_MULTI}\" ORIGCUSTOM_CA_SERVER_${x}=\"${CUSTOM_CA_SERVER_MULTI}\" ORIGPLUGIN_${x}=\"${PLUGIN_MULTI}\" ORIGPROPOGATION_TIME_${x}=\"${PROPOGATION_TIME_MULTI}\"" > /config/.donoteditthisfile_cert_${x} + fi + + # Load original config file + . /config/.donoteditthisfile_cert_${x} + + ORIGDOMAINS_MULTI=ORIGDOMAINS_${x} + ORIGEMAIL_MULTI=ORIGEMAIL_${x} + ORIGSTAGING_MULTI=ORIGSTAGING_${x} + ORIGCUSTOM_CA_MULTI=ORIGCUSTOM_CA_${x} + ORIGCUSTOM_CA_SERVER_MULTI=ORIGCUSTOM_CA_SERVER_${x} + ORIGPLUGIN_MULTI=ORIGPLUGIN_${x} + ORIGPROPOGATION_TIME_MULTI=ORIGPROPOGATION_TIME_${x} + ORIGCLOUDFLARE_TOKEN_MULTI=ORIGCLOUDFLARE_TOKEN_${x} + + # Log variables to console (have to remove indent because bash dumb) + + echo " +---------------------------------------------------------------------- +CERTIFICATE ${x} ENVIRONMENT +----------------------------------------------------------------------" +echo \ +"DOMAINS_${x}=${DOMAINS_MULTI} +EMAIL_${x}=${EMAIL_MULTI} +STAGING_${x}=${STAGING_MULTI} +CUSTOM_CA_${x}=${CUSTOM_CA_MULTI} +CUSTOM_CA_SERVER_${x}=${CUSTOM_CA_SERVER_MULTI} +PLUGIN_${x}=${PLUGIN_MULTI}" +## Get plugin-specific data if single certificate config +if [ ${PLUGIN_MULTI} == 'cloudflare' ]; then +echo \ +"PROPOGATION_TIME_${x}=${PROPOGATION_TIME_MULTI}" fi +if [ ${PLUGIN_MULTI} == 'cloudflare' ] && [ ! -z ${CLOUDFLARE_TOKEN_MULTI} ]; then +echo \ +"CLOUDFLARE_TOKEN_${x}=[hidden]" +elif [ ${PLUGIN_MULTI} == 'cloudflare' ] && [ -z ${CLOUDFLARE_TOKEN_MULTI} ]; then +echo \ +"CLOUDFLARE_TOKEN_${x}=" +fi +echo \ +"---------------------------------------------------------------------- +" -#Securing cloudflare.ini to supress warnings -chmod 600 /config/.secrets/cloudflare.ini + # Begin actually requesting the certificate -echo "Creating certificates, or attempting to renew if they already exist" + echo "Requesting certificate $x" -if [[ $STAGING = true ]] + # Checking for changes to config file, revoke certs if necessary + if [ ! "${DOMAINS_MULTI}" = "${!ORIGDOMAINS_MULTI}" ] || + [ ! "${EMAIL_MULTI}" = "${!ORIGEMAIL_MULTI}" ] || + [ ! "${STAGING_MULTI}" = "${!ORIGSTAGING_MULTI}" ] || + [ ! "${CUSTOM_CA_MULTI}" = "${!ORIGCUSTOM_CA_MULTI}" ] || + [ ! "${CUSTOM_CA_SERVER_MULTI}" = "${!ORIGCUSTOM_CA_SERVER_MULTI}" ] || + [ ! "${PLUGIN_MULTI}" = "${!ORIGPLUGIN_MULTI}" ] || + [ ! "${PROPOGATION_TIME_MULTI}" = "${!ORIGPROPOGATION_TIME_MULTI}" ] + then + + echo "" + + echo "Configuration has changed since certificate ${x} was last issued. Revoking and regenerating cert ${x}" + FIRST_DOMAIN_MULTI=$(echo ${!ORIGDOMAINS_MULTI} | cut -d \, -f1) + + if [ ! -z ${!ORIGCUSTOM_CA_MULTI} ] + then + + echo "A custom CA was used for issuing certificate ${x}. Using it to revoke as well." + + if [ ! -d /config/custom_ca ] + then + mkdir /config/custom_ca + echo "Please place the custom CA root file used to generate the current certificate ${x} into /config/custom_ca and restart the container" + better_exit + fi + + if [ -z "$(ls -A /config/custom_ca)" ] + then + echo "A root certificate called ${!ORIGCUSTOM_CA_MULTI} was used to generate a certificate, but the /config/custom_ca dir is now empty. Please place this root certificate back this directory and restart the container so it can be safely revoked" + better_exit + fi + + ORIGCUSTOM_CA_PATH_MULTI=/config/custom_ca/${!ORIGCUSTOM_CA_MULTI} + ORIGCUSTOM_CA_SERVER_OPT_MULTI="--server ${!ORIGCUSTOM_CA_SERVER_MULTI}" + + fi + + if [ $ORIGSTAGING_MULTI = "true" ] + then + + # Reusing the CUSTOM_CA_SERVER_OPT variable to add staging option if that was selected + ORIGCUSTOM_CA_SERVER_OPT_MULTI="--server https://acme-staging-v02.api.letsencrypt.org/directory" + + fi + + if [ -f /config/letsencrypt/live/"${FIRST_DOMAIN_MULTI}"/fullchain.pem ] + then + + REQUESTS_CA_BUNDLE=$ORIGCUSTOM_CA_PATH_MULTI certbot revoke --non-interactive --agree-tos --email $ORIGEMAIL_MULTI --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --cert-path /config/letsencrypt/live/"${FIRST_DOMAIN_MULTI}"/fullchain.pem ${ORIGCUSTOM_CA_SERVER_OPT_MULTI} || true + + rm -rf /config/letsencrypt/archive/"${FIRST_DOMAIN_MULTI}" + rm -rf /config/letsencrypt/live/"${FIRST_DOMAIN_MULTI}" + rm -rf /config/letsencrypt/renewal/"${FIRST_DOMAIN_MULTI}".conf + + fi + + echo "Tidying up any potential lingering ACME challenges in /config/webroot from failed webroot activations" + rm -rf /config/webroot/.well-known/acme-challenge + + fi + + # Update config file with new cert-specific env vars + echo -e "ORIGDOMAINS_${x}=\"${DOMAINS_MULTI}\" ORIGEMAIL_${x}=\"${EMAIL_MULTI}\" ORIGSTAGING_${x}=\"${STAGING_MULTI}\" ORIGCUSTOM_CA_${x}=\"${CUSTOM_CA_MULTI}\" ORIGCUSTOM_CA_SERVER_${x}=\"${CUSTOM_CA_SERVER_MULTI}\" ORIGPLUGIN_${x}=\"${PLUGIN_MULTI}\" ORIGPROPOGATION_TIME_${x}=\"${PROPOGATION_TIME_MULTI}\"" > /config/.donoteditthisfile_cert_${x} + + echo "" + + if [ ! -z ${CUSTOM_CA_MULTI} ] + then + + echo "Using a custom CA for issuing certificate ${x}" + + if [ ! -d /config/custom_ca ] + then + mkdir /config/custom_ca + echo "Please place your custom CA file into /config/custom_ca and restart the container" + better_exit + fi + + if [ -z "$(ls -A /config/custom_ca)" ] + then + echo "The CUSTOM_CA_${x} option is populated, but the /config/custom_ca dir is empty. Please place your root certificate for certificate ${x} in this directory and restart the container" + better_exit + fi + + if [ -z ${CUSTOM_CA_SERVER_MULTI} ] + then + echo "CUSTOM_CA_SERVER_${x} has not been defined. It is required when using a custom CA to issue certificate ${x}" + better_exit + fi + + CUSTOM_CA_PATH_MULTI=/config/custom_ca/${CUSTOM_CA_MULTI} + CUSTOM_CA_SERVER_OPT_MULTI="--server ${CUSTOM_CA_SERVER_MULTI}" + + if [ ${STAGING_MULTI} = "true" ] + then + + echo "Staging option is not supported when using a custom CA. To remove this alert, set staging to false. If your CA has a standing endpoint, use the CUSTOM_CA_SERVER_${x} option to point to it instead" + better_exit + + fi + + fi + + BASE_COMMAND=(certbot certonly --non-interactive --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --key-path /config/letsencrypt/keys --expand --agree-tos "${CUSTOM_CA_SERVER_OPT_MULTI}" --email "${EMAIL_MULTI}" -d "${DOMAINS_MULTI}") + + ## Run with Cloudflare plugin + if [ ${PLUGIN_MULTI} == "cloudflare" ] + then + + echo "Using Cloudflare plugin" + + if [ ! -f /config/.secrets/cloudflare.ini ] + then + touch /config/.secrets/cloudflare.ini + fi + + if [ -n "${CLOUDFLARE_TOKEN_MULTI}" ] + then + echo "Cloudflare token is present" + + echo "dns_cloudflare_api_token = ${CLOUDFLARE_TOKEN_MULTI}" > /config/.secrets/cloudflare.ini + + fi + + if [ ! -s /config/.secrets/cloudflare.ini ] + then + echo "cloudflare.ini is empty - please add your Cloudflare credentials or API key before continuing. This can be done by setting CLOUDFLARE_TOKEN_${x}" + + better_exit + fi + + #Securing cloudflare.ini to supress warnings + chmod 600 /config/.secrets/cloudflare.ini + + echo "Creating certificates, or attempting to renew if they already exist" + + if [ ${STAGING_MULTI} = true ] + then + echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" + ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds ${PROPOGATION_TIME_MULTI} --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --staging + # Add to renewal list + echo "## Certificate ${x}" >> /config/.renew-list.sh + echo "${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds ${PROPOGATION_TIME_MULTI} --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --staging" >> /config/.renew-list.sh + echo "" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + elif [ ${STAGING_MULTI} = false ] + then + echo "Using production endpoint" + ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds ${PROPOGATION_TIME_MULTI} --dns-cloudflare-credentials /config/.secrets/cloudflare.ini + # Add to renewal list + echo "## Certificate ${x}" >> /config/.renew-list.sh + echo "REQUESTS_CA_BUNDLE=$CUSTOM_CA_PATH ${BASE_COMMAND[@]} --dns-cloudflare --dns-cloudflare-propagation-seconds ${PROPOGATION_TIME_MULTI} --dns-cloudflare-credentials /config/.secrets/cloudflare.ini" >> /config/.renew-list.sh + echo "" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + else + echo "Unrecognised option for STAGING variable - check your configuration" + + better_exit + fi + + ## Run with Standalone plugin + elif [ ${PLUGIN_MULTI} == "standalone" ] + then + + echo "Using HTTP verification via built-in web-server - please ensure port 80 is exposed." + + if [ ${STAGING_MULTI} = true ] + then + echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" + REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --standalone --staging + # Add to renewal list + echo "## Certificate ${x}" >> /config/.renew-list.sh + echo "REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --standalone --staging" >> /config/.renew-list.sh + echo "" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + elif [ ${STAGING_MULTI} = false ] + then + echo "Using production endpoint" + REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --standalone + # Add to renewal list + echo "## Certificate ${x}" >> /config/.renew-list.sh + echo "REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --standalone" >> /config/.renew-list.sh + echo "" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + else + echo "Unrecognised option for STAGING variable - check your configuration" + + better_exit + fi + + ## Run with webroot plugin + elif [ ${PLUGIN_MULTI} == "webroot" ] + then + + echo "Using HTTP verification via webroot - please ensure you have mounted a webroot at /config/webroot from a web-server reachable via the domain you are issuing a certificate for." + + if [ ${STAGING_MULTI} = true ] + then + echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" + REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot --staging + # Add to renewal list + echo "## Certificate ${x}" >> /config/.renew-list.sh + echo "REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot --staging" >> /config/.renew-list.sh + echo "" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + elif [ ${STAGING_MULTI} = false ] + then + echo "Using production endpoint" + REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot + # Add to renewal list + echo "## Certificate ${x}" >> /config/.renew-list.sh + echo "REQUESTS_CA_BUNDLE=${CUSTOM_CA_PATH_MULTI} ${BASE_COMMAND[@]} --webroot --webroot-path /config/webroot" >> /config/.renew-list.sh + echo "" >> /config/.renew-list.sh + echo "Creation/renewal attempt complete" + else + echo "Unrecognised option for STAGING variable - check your configuration" + + better_exit + fi + + else + + echo "Unrecognised option for PLUGIN variable - check your configuration" + + fi + + # Scrubbing variables before running next cert to prevent overlap of values + DOMAINS_MULTI= + EMAIL_MULTI= + STAGING_MULTI= + CUSTOM_CA_MULTI= + CUSTOM_CA_SERVER_MULTI= + PLUGIN_MULTI= + PROPOGATION_TIME_MULTI= + CLOUDFLARE_TOKEN_MULTI= + CUSTOM_CA_PATH_MULTI= + CUSTOM_CA_SERVER_OPT_MULTI= + ORIGDOMAINS_MULTI= + ORIGEMAIL_MULTI= + ORIGSTAGING_MULTI= + ORIGCUSTOM_CA_MULTI= + ORIGCUSTOM_CA_SERVER_MULTI= + ORIGPLUGIN_MULTI= + ORIGPROPOGATION_TIME_MULTI= + ORIGCLOUDFLARE_TOKEN_MULTI= + FIRST_DOMAIN_MULTI= + ORIGCUSTOM_CA_PATH_MULTI= + ORIGCUSTOM_CA_SERVER_OPT_MULTI= + + x=$(( $x + 1 )) + + done + +} + +if [ $CERT_COUNT == 1 ] then - echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" - certbot certonly --staging --non-interactive --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --key-path /config/letsencrypt/keys --expand --agree-tos --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --email $EMAIL -d $DOMAINS - echo "Creation/renewal attempt complete" -elif [[ $STAGING = false ]] + single_domain +elif [ $CERT_COUNT -gt 1 ] then - echo "Using production endpoint" - certbot certonly --non-interactive --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --key-path /config/letsencrypt/keys --expand --agree-tos --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --email $EMAIL -d $DOMAINS - echo "Creation/renewal attempt complete" + multi_domain else - echo "Unrecognised option for STAGING variable - check your configuration" - - exit 22 + echo "CERT_COUNT varaible not recognised. It needs to be a value of 1 or greater." fi -if [[ $GENERATE_DHPARAM = true ]] && [[ ! -s /config/letsencrypt/keys/ssl-dhparams.pem ]] +if [ $GENERATE_DHPARAM = true ] && [ ! -s /config/letsencrypt/keys/ssl-dhparams.pem ] then - echo "Generating Diffie-Hellman keys, saved to /config/letsencrypt/keys" + echo "Generating Diffie-Hellman keys, saved to /config/letsencrypt/keys. This can take a long time!" openssl dhparam -out /config/letsencrypt/keys/ssl-dhparams.pem 4096 fi echo "$INTERVAL /certbot-renew.sh >> /config/logs/renew.log" > /config/.crontab.txt +echo "" + echo "Starting automatic renewal job. Schedule is $INTERVAL" crontab /config/.crontab.txt \ No newline at end of file diff --git a/root/certbot-renew.sh b/root/certbot-renew.sh index 485a0d5..acedd1c 100644 --- a/root/certbot-renew.sh +++ b/root/certbot-renew.sh @@ -3,18 +3,4 @@ echo '' date echo "Attempting to renew certificates" -if [[ $STAGING = true ]] -then - echo "Using staging endpoint - THIS SHOULD BE USED FOR TESTING ONLY" - certbot certonly --staging --non-interactive --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --key-path /config/letsencrypt/keys --expand --agree-tos --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --email $EMAIL -d $DOMAINS - echo "Renewal attempt complete" -elif [[ $STAGING = false ]] -then - echo "Using production endpoint" - certbot certonly --non-interactive --config-dir /config/letsencrypt --work-dir /config/.tmp --logs-dir /config/logs --key-path /config/letsencrypt/keys --expand --agree-tos --dns-cloudflare --dns-cloudflare-propagation-seconds $PROPOGATION_TIME --dns-cloudflare-credentials /config/.secrets/cloudflare.ini --email $EMAIL -d $DOMAINS - echo "Renewal attempt complete" -else - echo "Unrecognised option for STAGING variable - check your configuration" - - exit 8 -fi \ No newline at end of file +bash /config/.renew-list.sh \ No newline at end of file diff --git a/root/container-init.sh b/root/container-init.sh index 1f4fe54..10683bb 100644 --- a/root/container-init.sh +++ b/root/container-init.sh @@ -13,21 +13,48 @@ echo "| |" echo "================================================" echo "" echo "Initialising container" -echo " ----------------------------------------------------------------------- +if [ ${CERT_COUNT} == 1 ]; then +echo \ +"---------------------------------------------------------------------- ENVIRONMENT ----------------------------------------------------------------------- -PUID=${PUID} +----------------------------------------------------------------------" +else +echo \ +"---------------------------------------------------------------------- +ENVIRONMENT (Certificate options logged later) +----------------------------------------------------------------------" +fi +echo \ +"PUID=${PUID} PGID=${PGID} TZ=${TZ} -DOMAINS=${DOMAINS} -EMAIL=${EMAIL} INTERVAL=${INTERVAL} -STAGING=${STAGING} -PROPOGATION_TIME=${PROPOGATION_TIME} GENERATE_DHPARAM=${GENERATE_DHPARAM} -CLOUDFLARE_TOKEN=${CLOUDFLARE_TOKEN} ----------------------------------------------------------------------- +CERT_COUNT=${CERT_COUNT}" +## Send extra detail to logs if single certificate config +if [ ${CERT_COUNT} == 1 ]; then +echo \ +"DOMAINS=${DOMAINS} +EMAIL=${EMAIL} +STAGING=${STAGING} +CUSTOM_CA=${CUSTOM_CA} +CUSTOM_CA_SERVER=${CUSTOM_CA_SERVER} +PLUGIN=${PLUGIN}" +fi +## Get plugin-specific data if single certificate config +if [ ${CERT_COUNT} == 1 ] && [ ${PLUGIN} == 'cloudflare' ]; then +echo \ +"PROPOGATION_TIME=${PROPOGATION_TIME}" +fi +if [ ${CERT_COUNT} == 1 ] && [ ${PLUGIN} == 'cloudflare' ] && [ ! -z ${CLOUDFLARE_TOKEN} ]; then +echo \ +"CLOUDFLARE_TOKEN=[hidden]" +elif [ ${CERT_COUNT} == 1 ] && [ ${PLUGIN} == 'cloudflare' ] && [ -z ${CLOUDFLARE_TOKEN} ]; then +echo \ +"CLOUDFLARE_TOKEN=" +fi +echo \ +"---------------------------------------------------------------------- " #Setting UID and GID as configured @@ -41,7 +68,7 @@ if [[ ! "${PUID}" -eq 0 ]] && [[ ! "${PGID}" -eq 0 ]]; then groupmod -o -g "${PGID}" mrmeeb else echo "Running as root is not supported, please fix your PUID and PGID!" - exit 1 + sleep infinity fi echo "Checking permissions in /config and /app."