From bc86c9491af6c7a55d22256417bd7875a4a0aeb8 Mon Sep 17 00:00:00 2001 From: Nikolai Prokoschenko Date: Wed, 24 Apr 2024 10:39:18 +0200 Subject: [PATCH] Update Dockerfiles --- 11/jdk/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 11/jdk/centos/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jdk/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jdk/ubuntu/focal/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jdk/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jre/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 11/jre/centos/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jre/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jre/ubuntu/focal/entrypoint.sh | 91 ++++++++++++++++++++++----- 11/jre/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jdk/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 17/jdk/centos/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jdk/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jdk/ubuntu/focal/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jdk/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jre/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 17/jre/centos/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jre/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jre/ubuntu/focal/entrypoint.sh | 91 ++++++++++++++++++++++----- 17/jre/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 21/jdk/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 21/jdk/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 21/jdk/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 21/jre/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 21/jre/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 21/jre/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 22/jdk/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 22/jdk/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 22/jdk/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 22/jre/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 22/jre/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 22/jre/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jdk/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 8/jdk/centos/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jdk/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jdk/ubuntu/focal/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jdk/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jre/alpine/entrypoint.sh | 87 ++++++++++++++++++++----- 8/jre/centos/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jre/ubi/ubi9-minimal/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jre/ubuntu/focal/entrypoint.sh | 91 ++++++++++++++++++++++----- 8/jre/ubuntu/jammy/entrypoint.sh | 91 ++++++++++++++++++++++----- 42 files changed, 3130 insertions(+), 652 deletions(-) diff --git a/11/jdk/alpine/entrypoint.sh b/11/jdk/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/11/jdk/alpine/entrypoint.sh +++ b/11/jdk/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jdk/centos/entrypoint.sh b/11/jdk/centos/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/11/jdk/centos/entrypoint.sh +++ b/11/jdk/centos/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jdk/ubi/ubi9-minimal/entrypoint.sh b/11/jdk/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/11/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/11/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jdk/ubuntu/focal/entrypoint.sh b/11/jdk/ubuntu/focal/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/11/jdk/ubuntu/focal/entrypoint.sh +++ b/11/jdk/ubuntu/focal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jdk/ubuntu/jammy/entrypoint.sh b/11/jdk/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/11/jdk/ubuntu/jammy/entrypoint.sh +++ b/11/jdk/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jre/alpine/entrypoint.sh b/11/jre/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/11/jre/alpine/entrypoint.sh +++ b/11/jre/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jre/centos/entrypoint.sh b/11/jre/centos/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/11/jre/centos/entrypoint.sh +++ b/11/jre/centos/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jre/ubi/ubi9-minimal/entrypoint.sh b/11/jre/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/11/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/11/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jre/ubuntu/focal/entrypoint.sh b/11/jre/ubuntu/focal/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/11/jre/ubuntu/focal/entrypoint.sh +++ b/11/jre/ubuntu/focal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/11/jre/ubuntu/jammy/entrypoint.sh b/11/jre/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/11/jre/ubuntu/jammy/entrypoint.sh +++ b/11/jre/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jdk/alpine/entrypoint.sh b/17/jdk/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/17/jdk/alpine/entrypoint.sh +++ b/17/jdk/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jdk/centos/entrypoint.sh b/17/jdk/centos/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/17/jdk/centos/entrypoint.sh +++ b/17/jdk/centos/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jdk/ubi/ubi9-minimal/entrypoint.sh b/17/jdk/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/17/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/17/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jdk/ubuntu/focal/entrypoint.sh b/17/jdk/ubuntu/focal/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/17/jdk/ubuntu/focal/entrypoint.sh +++ b/17/jdk/ubuntu/focal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jdk/ubuntu/jammy/entrypoint.sh b/17/jdk/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/17/jdk/ubuntu/jammy/entrypoint.sh +++ b/17/jdk/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jre/alpine/entrypoint.sh b/17/jre/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/17/jre/alpine/entrypoint.sh +++ b/17/jre/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jre/centos/entrypoint.sh b/17/jre/centos/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/17/jre/centos/entrypoint.sh +++ b/17/jre/centos/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jre/ubi/ubi9-minimal/entrypoint.sh b/17/jre/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/17/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/17/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jre/ubuntu/focal/entrypoint.sh b/17/jre/ubuntu/focal/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/17/jre/ubuntu/focal/entrypoint.sh +++ b/17/jre/ubuntu/focal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/17/jre/ubuntu/jammy/entrypoint.sh b/17/jre/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/17/jre/ubuntu/jammy/entrypoint.sh +++ b/17/jre/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/21/jdk/alpine/entrypoint.sh b/21/jdk/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/21/jdk/alpine/entrypoint.sh +++ b/21/jdk/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/21/jdk/ubi/ubi9-minimal/entrypoint.sh b/21/jdk/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/21/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/21/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/21/jdk/ubuntu/jammy/entrypoint.sh b/21/jdk/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/21/jdk/ubuntu/jammy/entrypoint.sh +++ b/21/jdk/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/21/jre/alpine/entrypoint.sh b/21/jre/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/21/jre/alpine/entrypoint.sh +++ b/21/jre/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/21/jre/ubi/ubi9-minimal/entrypoint.sh b/21/jre/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/21/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/21/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/21/jre/ubuntu/jammy/entrypoint.sh b/21/jre/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/21/jre/ubuntu/jammy/entrypoint.sh +++ b/21/jre/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/22/jdk/alpine/entrypoint.sh b/22/jdk/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/22/jdk/alpine/entrypoint.sh +++ b/22/jdk/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/22/jdk/ubi/ubi9-minimal/entrypoint.sh b/22/jdk/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/22/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/22/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/22/jdk/ubuntu/jammy/entrypoint.sh b/22/jdk/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/22/jdk/ubuntu/jammy/entrypoint.sh +++ b/22/jdk/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/22/jre/alpine/entrypoint.sh b/22/jre/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/22/jre/alpine/entrypoint.sh +++ b/22/jre/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/22/jre/ubi/ubi9-minimal/entrypoint.sh b/22/jre/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/22/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/22/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/22/jre/ubuntu/jammy/entrypoint.sh b/22/jre/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/22/jre/ubuntu/jammy/entrypoint.sh +++ b/22/jre/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jdk/alpine/entrypoint.sh b/8/jdk/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/8/jdk/alpine/entrypoint.sh +++ b/8/jdk/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jdk/centos/entrypoint.sh b/8/jdk/centos/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/8/jdk/centos/entrypoint.sh +++ b/8/jdk/centos/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jdk/ubi/ubi9-minimal/entrypoint.sh b/8/jdk/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/8/jdk/ubi/ubi9-minimal/entrypoint.sh +++ b/8/jdk/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jdk/ubuntu/focal/entrypoint.sh b/8/jdk/ubuntu/focal/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/8/jdk/ubuntu/focal/entrypoint.sh +++ b/8/jdk/ubuntu/focal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jdk/ubuntu/jammy/entrypoint.sh b/8/jdk/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/8/jdk/ubuntu/jammy/entrypoint.sh +++ b/8/jdk/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jre/alpine/entrypoint.sh b/8/jre/alpine/entrypoint.sh index 029cade7e..396dd0a7b 100755 --- a/8/jre/alpine/entrypoint.sh +++ b/8/jre/alpine/entrypoint.sh @@ -3,28 +3,87 @@ set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ -n "$(ls -A /certificates 2>/dev/null)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT="$JAVA_HOME/lib/security/cacerts" - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT="$JAVA_HOME/jre/lib/security/cacerts" + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jre/centos/entrypoint.sh b/8/jre/centos/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/8/jre/centos/entrypoint.sh +++ b/8/jre/centos/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jre/ubi/ubi9-minimal/entrypoint.sh b/8/jre/ubi/ubi9-minimal/entrypoint.sh index 481ab8862..396dd0a7b 100755 --- a/8/jre/ubi/ubi9-minimal/entrypoint.sh +++ b/8/jre/ubi/ubi9-minimal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Shebang needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # RHEL-based images already include a routine to update a java truststore from the system CA bundle within - # `update-ca-trust`. All we need to do is to link the system CA bundle to the java truststore. - update-ca-trust + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - ln -sf /etc/pki/ca-trust/extracted/java/cacerts "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jre/ubuntu/focal/entrypoint.sh b/8/jre/ubuntu/focal/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/8/jre/ubuntu/focal/entrypoint.sh +++ b/8/jre/ubuntu/focal/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@" diff --git a/8/jre/ubuntu/jammy/entrypoint.sh b/8/jre/ubuntu/jammy/entrypoint.sh index dfcf546f9..396dd0a7b 100755 --- a/8/jre/ubuntu/jammy/entrypoint.sh +++ b/8/jre/ubuntu/jammy/entrypoint.sh @@ -1,30 +1,89 @@ -#!/usr/bin/env bash -# Sheband needs to be `bash`, see https://github.com/adoptium/containers/issues/415 for details +#!/usr/bin/env sh +# Converted to POSIX shell to avoid the need for bash in the image set -e +# JDK truststore location +CACERT=$JAVA_HOME/lib/security/cacerts + +# JDK8 puts its JRE in a subdirectory +if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then + CACERT=$JAVA_HOME/jre/lib/security/cacerts +fi + # Opt-in is only activated if the environment variable is set if [ -n "$USE_SYSTEM_CA_CERTS" ]; then - # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. - # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the - # system location, for whatever reason. - if [ -d /certificates ] && [ "$(ls -A /certificates)" ]; then - cp -a /certificates/* /usr/local/share/ca-certificates/ + if [ ! -w /tmp ]; then + echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore." + exit 1 fi - CACERT=$JAVA_HOME/lib/security/cacerts - - # JDK8 puts its JRE in a subdirectory - if [ -f "$JAVA_HOME/jre/lib/security/cacerts" ]; then - CACERT=$JAVA_HOME/jre/lib/security/cacerts + # Figure out whether we can write to the JVM truststore. If we can, we'll add the certificates there. If not, + # we'll use a temporary truststore. + if [ ! -w "$CACERT" ]; then + # We cannot write to the JVM truststore, so we create a temporary one + CACERT_NEW=$(mktemp) + echo "Using a temporary truststore at $CACERT_NEW" + cp $CACERT $CACERT_NEW + CACERT=$CACERT_NEW + # If we use a custom truststore, we need to make sure that the JVM uses it + export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${CACERT} -Djavax.net.ssl.trustStorePassword=changeit" fi - # OpenJDK images used to create a hook for `update-ca-certificates`. Since we are using an entrypoint anyway, we - # might as well just generate the truststore and skip the hooks. - update-ca-certificates + tmp_store=$(mktemp) + + # Copy full system CA store to a temporary location + trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$tmp_store" + + # Add the system CA certificates to the JVM truststore. + keytool -importkeystore -destkeystore "$CACERT" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt # >/dev/null + + # Import the additional certificate into JVM truststore + for i in /certificates/*crt; do + if [ ! -f "$i" ]; then + continue + fi + keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$CACERT" -storepass changeit # >/dev/null + done - trust extract --overwrite --format=java-cacerts --filter=ca-anchors --purpose=server-auth "$CACERT" + # Add additional certificates to the system CA store. This requires write permissions to several system + # locations, which is not possible in a container with read-only filesystem and/or non-root container. + if [ "$(id -u)" -eq 0 ]; then + + # Copy certificates from /certificates to the system truststore, but only if the directory exists and is not empty. + # The reason why this is not part of the opt-in is because it leaves open the option to mount certificates at the + # system location, for whatever reason. + if [ -d /certificates ] && [ "$(ls -A /certificates 2>/dev/null)" ]; then + + # UBI/CentOS + if [ -d /usr/share/pki/ca-trust-source/anchors/ ]; then + cp -a /certificates/* /usr/share/pki/ca-trust-source/anchors/ + fi + + # Ubuntu/Alpine + if [ -d /usr/local/share/ca-certificates/ ]; then + cp -a /certificates/* /usr/local/share/ca-certificates/ + fi + fi + + # UBI/CentOS + if which update-ca-trust >/dev/null; then + update-ca-trust + fi + + # Ubuntu/Alpine + if which update-ca-certificates >/dev/null; then + update-ca-certificates + fi + else + # If we are not root, we cannot update the system truststore. That's bad news for tools like `curl` and `wget`, + # but since the JVM is the primary focus here, we can live with that. + true + fi fi +# Let's provide a variable with the correct path for tools that want or need to use it +export CACERT + exec "$@"