Skip to content

Commit

Permalink
Address comments on the "rootless CA certs" patch
Browse files Browse the repository at this point in the history
Address the following problems with #538:

1. Correct the shell selection for entrypoint, Ubuntu flavours still need explicit `bash` for variables with dots in
their names
2. Change unhelpful exported variable name (changed from `CACERT` to `JRE_CACERTS_PATH`)
3. Change `which` to more-POSIX-compatible `command -v`
4. More cleanup
5. Explicitely use `TMPDIR` when available instead of hard-coded `/tmp`
  • Loading branch information
rassie committed Jun 26, 2024
1 parent 9efca45 commit 089349e
Show file tree
Hide file tree
Showing 63 changed files with 1,016 additions and 707 deletions.
2 changes: 1 addition & 1 deletion .test/tests/java-ca-certificates-update/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ CMD1=date

# CMD2 in each run is to check for the `dockerbuilder` certificate in the Java keystore. Entrypoint export $CACERT to
# point to the Java keystore.
CMD2=(sh -c "keytool -list -keystore \$CACERT -storepass changeit -alias dockerbuilder")
CMD2=(sh -c "keytool -list -keystore \"\$JRE_CACERTS_PATH\" -storepass changeit -alias dockerbuilder")

# For a custom entrypoint test, we need to create a new image. This image will get cleaned up at the end of the script
# by the `finish` trap function.
Expand Down
39 changes: 23 additions & 16 deletions 11/jdk/alpine/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
#!/usr/bin/env sh
# Converted to POSIX shell to avoid the need for bash in the image
# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get
# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but
# are supported by `sh` in some Linux flavours.

set -e

TMPDIR=${TMPDIR:-/tmp}

# JDK truststore location
CACERT=$JAVA_HOME/lib/security/cacerts
JRE_CACERTS_PATH=$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
JRE_CACERTS_PATH=$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

if [ ! -w /tmp ]; then
echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore."
if [ ! -w "$TMPDIR" ]; then
echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore."
exit 1
fi

# 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
if [ ! -w "$JRE_CACERTS_PATH" ]; 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
JRE_CACERTS_PATH_NEW=$(mktemp)
echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW"
cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW"
JRE_CACERTS_PATH=$JRE_CACERTS_PATH_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"
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit"
fi

tmp_store=$(mktemp)
Expand All @@ -37,14 +41,17 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
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
keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt

# Clean up the temporary truststore
rm "$tmp_store"

# 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
keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$JRE_CACERTS_PATH" -storepass changeit # >/dev/null
done

# Add additional certificates to the system CA store. This requires write permissions to several system
Expand All @@ -68,12 +75,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# UBI/CentOS
if which update-ca-trust >/dev/null; then
if command -v update-ca-trust >/dev/null; then
update-ca-trust
fi

# Ubuntu/Alpine
if which update-ca-certificates >/dev/null; then
if command -v update-ca-certificates >/dev/null; then
update-ca-certificates
fi
else
Expand All @@ -84,6 +91,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# Let's provide a variable with the correct path for tools that want or need to use it
export CACERT
export JRE_CACERTS_PATH

exec "$@"
39 changes: 23 additions & 16 deletions 11/jdk/centos/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
#!/usr/bin/env sh
# Converted to POSIX shell to avoid the need for bash in the image
# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get
# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but
# are supported by `sh` in some Linux flavours.

set -e

TMPDIR=${TMPDIR:-/tmp}

# JDK truststore location
CACERT=$JAVA_HOME/lib/security/cacerts
JRE_CACERTS_PATH=$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
JRE_CACERTS_PATH=$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

if [ ! -w /tmp ]; then
echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore."
if [ ! -w "$TMPDIR" ]; then
echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore."
exit 1
fi

# 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
if [ ! -w "$JRE_CACERTS_PATH" ]; 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
JRE_CACERTS_PATH_NEW=$(mktemp)
echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW"
cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW"
JRE_CACERTS_PATH=$JRE_CACERTS_PATH_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"
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit"
fi

tmp_store=$(mktemp)
Expand All @@ -37,14 +41,17 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
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
keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt

# Clean up the temporary truststore
rm "$tmp_store"

# 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
keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$JRE_CACERTS_PATH" -storepass changeit # >/dev/null
done

# Add additional certificates to the system CA store. This requires write permissions to several system
Expand All @@ -68,12 +75,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# UBI/CentOS
if which update-ca-trust >/dev/null; then
if command -v update-ca-trust >/dev/null; then
update-ca-trust
fi

# Ubuntu/Alpine
if which update-ca-certificates >/dev/null; then
if command -v update-ca-certificates >/dev/null; then
update-ca-certificates
fi
else
Expand All @@ -84,6 +91,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# Let's provide a variable with the correct path for tools that want or need to use it
export CACERT
export JRE_CACERTS_PATH

exec "$@"
39 changes: 23 additions & 16 deletions 11/jdk/ubi/ubi9-minimal/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
#!/usr/bin/env sh
# Converted to POSIX shell to avoid the need for bash in the image
# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get
# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but
# are supported by `sh` in some Linux flavours.

set -e

TMPDIR=${TMPDIR:-/tmp}

# JDK truststore location
CACERT=$JAVA_HOME/lib/security/cacerts
JRE_CACERTS_PATH=$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
JRE_CACERTS_PATH=$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

if [ ! -w /tmp ]; then
echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore."
if [ ! -w "$TMPDIR" ]; then
echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore."
exit 1
fi

# 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
if [ ! -w "$JRE_CACERTS_PATH" ]; 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
JRE_CACERTS_PATH_NEW=$(mktemp)
echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW"
cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW"
JRE_CACERTS_PATH=$JRE_CACERTS_PATH_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"
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit"
fi

tmp_store=$(mktemp)
Expand All @@ -37,14 +41,17 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
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
keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt

# Clean up the temporary truststore
rm "$tmp_store"

# 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
keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$JRE_CACERTS_PATH" -storepass changeit # >/dev/null
done

# Add additional certificates to the system CA store. This requires write permissions to several system
Expand All @@ -68,12 +75,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# UBI/CentOS
if which update-ca-trust >/dev/null; then
if command -v update-ca-trust >/dev/null; then
update-ca-trust
fi

# Ubuntu/Alpine
if which update-ca-certificates >/dev/null; then
if command -v update-ca-certificates >/dev/null; then
update-ca-certificates
fi
else
Expand All @@ -84,6 +91,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# Let's provide a variable with the correct path for tools that want or need to use it
export CACERT
export JRE_CACERTS_PATH

exec "$@"
2 changes: 1 addition & 1 deletion 11/jdk/ubuntu/focal/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ RUN set -eux; \
echo "java --version"; java --version; \
echo "Complete."
COPY entrypoint.sh /__cacert_entrypoint.sh
ENTRYPOINT ["/__cacert_entrypoint.sh"]
ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"]

CMD ["jshell"]
39 changes: 23 additions & 16 deletions 11/jdk/ubuntu/focal/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
#!/usr/bin/env sh
# Converted to POSIX shell to avoid the need for bash in the image
# This script defines `sh` as the interpreter, which is available in all POSIX environments. However, it might get
# started with `bash` as the shell to support dotted.environment.variable.names which are not supported by POSIX, but
# are supported by `sh` in some Linux flavours.

set -e

TMPDIR=${TMPDIR:-/tmp}

# JDK truststore location
CACERT=$JAVA_HOME/lib/security/cacerts
JRE_CACERTS_PATH=$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
JRE_CACERTS_PATH=$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

if [ ! -w /tmp ]; then
echo "Using additional CA certificates requires write permissions to /tmp. Cannot create truststore."
if [ ! -w "$TMPDIR" ]; then
echo "Using additional CA certificates requires write permissions to $TMPDIR. Cannot create truststore."
exit 1
fi

# 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
if [ ! -w "$JRE_CACERTS_PATH" ]; 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
JRE_CACERTS_PATH_NEW=$(mktemp)
echo "Using a temporary truststore at $JRE_CACERTS_PATH_NEW"
cp "$JRE_CACERTS_PATH" "$JRE_CACERTS_PATH_NEW"
JRE_CACERTS_PATH=$JRE_CACERTS_PATH_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"
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS} -Djavax.net.ssl.trustStore=${JRE_CACERTS_PATH} -Djavax.net.ssl.trustStorePassword=changeit"
fi

tmp_store=$(mktemp)
Expand All @@ -37,14 +41,17 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
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
keytool -importkeystore -destkeystore "$JRE_CACERTS_PATH" -srckeystore "$tmp_store" -srcstorepass changeit -deststorepass changeit -noprompt

# Clean up the temporary truststore
rm "$tmp_store"

# 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
keytool -import -noprompt -alias "$(basename "$i" .crt)" -file "$i" -keystore "$JRE_CACERTS_PATH" -storepass changeit # >/dev/null
done

# Add additional certificates to the system CA store. This requires write permissions to several system
Expand All @@ -68,12 +75,12 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# UBI/CentOS
if which update-ca-trust >/dev/null; then
if command -v update-ca-trust >/dev/null; then
update-ca-trust
fi

# Ubuntu/Alpine
if which update-ca-certificates >/dev/null; then
if command -v update-ca-certificates >/dev/null; then
update-ca-certificates
fi
else
Expand All @@ -84,6 +91,6 @@ if [ -n "$USE_SYSTEM_CA_CERTS" ]; then
fi

# Let's provide a variable with the correct path for tools that want or need to use it
export CACERT
export JRE_CACERTS_PATH

exec "$@"
2 changes: 1 addition & 1 deletion 11/jdk/ubuntu/jammy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ RUN set -eux; \
echo "java --version"; java --version; \
echo "Complete."
COPY entrypoint.sh /__cacert_entrypoint.sh
ENTRYPOINT ["/__cacert_entrypoint.sh"]
ENTRYPOINT ["/bin/bash", "/__cacert_entrypoint.sh"]

CMD ["jshell"]
Loading

0 comments on commit 089349e

Please sign in to comment.