diff --git a/gateway-docker/src/main/resources/docker/Dockerfile b/gateway-docker/src/main/resources/docker/Dockerfile index 052ac3d12e..c9ae429670 100644 --- a/gateway-docker/src/main/resources/docker/Dockerfile +++ b/gateway-docker/src/main/resources/docker/Dockerfile @@ -56,7 +56,8 @@ ARG ENTRYPOINT COPY --chown=8000:0 ${ENTRYPOINT} /home/knox/knox/entrypoint.sh RUN chmod +x /home/knox/knox/entrypoint.sh -# Add the Amazon Root CA and Let's Encrypt production certificates (best-effort) +# Add the Amazon Root CA and Let's Encrypt production root certificates (best-effort). +# Staging roots are downloaded at runtime when IMPORT_DEFAULT_STAGING_CERTS=true (default). RUN mkdir /home/knox/cacrts && \ curl -sSLo /home/knox/cacrts/AmazonRootCA1.cer https://www.amazontrust.com/repository/AmazonRootCA1.cer || true && \ curl -sSLo /home/knox/cacrts/AmazonRootCA2.cer https://www.amazontrust.com/repository/AmazonRootCA2.cer || true && \ diff --git a/gateway-docker/src/main/resources/docker/gateway-entrypoint.sh b/gateway-docker/src/main/resources/docker/gateway-entrypoint.sh index 2cb0277a3d..5a49dc7bb0 100755 --- a/gateway-docker/src/main/resources/docker/gateway-entrypoint.sh +++ b/gateway-docker/src/main/resources/docker/gateway-entrypoint.sh @@ -30,6 +30,9 @@ # - DATABASE_CONNECTION_PASSWORD - (optional) gateway database password # - DATABASE_CONNECTION_TRUSTSTORE_PASSWORD - (optional) gateway database ssl truststore password # - CUSTOM_CERT - (optional) the location of a file containing the custom certs +# - IMPORT_DEFAULT_STAGING_CERTS - (optional) when 'true' (default), download Let's Encrypt staging root +# CAs into /home/knox/cacrts at startup and import them into the gateway truststore. Set to 'false' to +# skip staging CA download and import (Amazon and ISRG production roots in TRUSTSTORE_IMPORTS are unaffected). # - TRUSTSTORE_IMPORTS - (optional) - a string containing one or more of the following: {aliasIdForImport:PEMEncodedTrustCertificateFileLocation} separated by space(s). # Example: # TRUSTSTORE_IMPORTS="myRootCA:/mountedpath/enterprise_root_cert.pem myBizPartnerCA:/mountedpath/mybiz_partner_cert.pem" @@ -40,6 +43,9 @@ set -e set -o pipefail +# Default: false, download and import Let's Encrypt staging root CAs (see IMPORT_DEFAULT_STAGING_CERTS above). +IMPORT_DEFAULT_STAGING_CERTS="${IMPORT_DEFAULT_STAGING_CERTS:-false}" + ## Helper function used to import certs into truststore ## Function takes cert file as argument ## At this time ALIAS_PASSPHRASE is already initialized @@ -76,6 +82,27 @@ importMultipleCerts() { return "$import_failed" } +## Download Let's Encrypt staging root CAs (best-effort) when IMPORT_DEFAULT_STAGING_CERTS is true. +downloadDefaultStagingCerts() { + local cacrts_dir="/home/knox/cacrts" + mkdir -p "${cacrts_dir}" + echo "Downloading default Let's Encrypt staging root CAs into ${cacrts_dir} ..." + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-x1.pem" \ + https://letsencrypt.org/certs/staging/letsencrypt-stg-root-x1.pem || true + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-x2.pem" \ + https://letsencrypt.org/certs/staging/letsencrypt-stg-root-x2.pem || true + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-x2-signed-by-x1.pem" \ + https://letsencrypt.org/certs/staging/letsencrypt-stg-root-x2-signed-by-x1.pem || true + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-ye.pem" \ + https://letsencrypt.org/certs/staging/gen-y/root-ye.pem || true + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-ye-by-x2.pem" \ + https://letsencrypt.org/certs/staging/gen-y/root-ye-by-x2.pem || true + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-yr.pem" \ + https://letsencrypt.org/certs/staging/gen-y/root-yr.pem || true + curl -sSLo "${cacrts_dir}/letsencrypt-stg-root-yr-by-x1.pem" \ + https://letsencrypt.org/certs/staging/gen-y/root-yr-by-x1.pem || true +} + ## Helper function to save an alias ## Function takes alias name, environment variable value, and optional default value saveAlias() { @@ -223,6 +250,19 @@ then isrgrootx2:/home/knox/cacrts/isrg-root-x2.pem" fi +if [[ "${IMPORT_DEFAULT_STAGING_CERTS}" == "true" ]] +then + downloadDefaultStagingCerts + TRUSTSTORE_IMPORTS="${TRUSTSTORE_IMPORTS} + letsencrypt-stg-root-x1:/home/knox/cacrts/letsencrypt-stg-root-x1.pem + letsencrypt-stg-root-x2:/home/knox/cacrts/letsencrypt-stg-root-x2.pem + letsencrypt-stg-root-x2-signed-by-x1:/home/knox/cacrts/letsencrypt-stg-root-x2-signed-by-x1.pem + letsencrypt-stg-root-ye:/home/knox/cacrts/letsencrypt-stg-root-ye.pem + letsencrypt-stg-root-ye-by-x2:/home/knox/cacrts/letsencrypt-stg-root-ye-by-x2.pem + letsencrypt-stg-root-yr:/home/knox/cacrts/letsencrypt-stg-root-yr.pem + letsencrypt-stg-root-yr-by-x1:/home/knox/cacrts/letsencrypt-stg-root-yr-by-x1.pem" +fi + for certinfo in ${TRUSTSTORE_IMPORTS} do aliasId=$(echo "${certinfo}" | awk -F: '{ print $1 }') @@ -247,7 +287,16 @@ do fi done -export KNOX_GATEWAY_DBG_OPTS="${KNOX_GATEWAY_DBG_OPTS} -Djavax.net.ssl.trustStore=${KEYSTORE_DIR}/truststore.jks -Djavax.net.ssl.trustStorePassword=${ALIAS_PASSPHRASE}" +# To avoid leaking password into the process command line +# we pass the trust options through a 0600 Java argument file. +# Java launcher expands @file after exec, so only "@" appears in the process args. +TRUSTSTORE_JVM_OPTS_FILE="${KEYSTORE_DIR}/truststore-jvm.options" +cat > "${TRUSTSTORE_JVM_OPTS_FILE}" <