Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 97 additions & 1 deletion containers/agent/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,101 @@ copy_awf_ca_cert() {
fi
}

copy_system_ca_bundle() {
# Detect and copy the host system CA bundle to a chroot-accessible path.
# On Amazon Linux / RHEL-family systems, the CA bundle lives under /etc/pki/
# which is not mounted into the chroot. This function finds the system bundle
# and copies it to /tmp/awf-lib/ so TLS works regardless of distro.
#
# In SSL Bump mode, the AWF CA must remain the active trust bundle for MITM
# proxy validation. We only append the system bundle to that staged AWF CA.
SYSTEM_CA_CHROOT=""

if [ "${AWF_SSL_BUMP_ENABLED}" = "true" ]; then
if [ -z "$AWF_CA_CHROOT" ] || [ ! -f "/host${AWF_CA_CHROOT}" ]; then
echo "[entrypoint][WARN] SSL Bump enabled but chroot AWF CA bundle is unavailable — preserving existing TLS env vars"
return
fi

# SSL Bump already configured TLS env vars; detect system bundle and append
# it to the AWF CA so tools trust both the AWF proxy CA AND the upstream CAs.
local SYSTEM_BUNDLE=""
for candidate in \
/host/etc/ssl/certs/ca-certificates.crt \
/host/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
/host/etc/pki/tls/certs/ca-bundle.crt \
/host/etc/pki/tls/cert.pem \
/host/etc/ssl/cert.pem; do
if [ -s "$candidate" ]; then
SYSTEM_BUNDLE="$candidate"
break
fi
done
if [ -n "$SYSTEM_BUNDLE" ]; then
# Append system bundle to the AWF CA cert so both are trusted
if { printf '\n'; cat "$SYSTEM_BUNDLE"; } >> "/host${AWF_CA_CHROOT}" 2>/dev/null; then
echo "[entrypoint] System CA bundle ($SYSTEM_BUNDLE) appended to AWF CA cert"
fi
fi
return
fi

# No SSL Bump — detect and expose the system CA bundle for chroot.
local SYSTEM_BUNDLE=""
for candidate in \
/host/etc/ssl/certs/ca-certificates.crt \
/host/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
/host/etc/pki/tls/certs/ca-bundle.crt \
/host/etc/pki/tls/cert.pem \
/host/etc/ssl/cert.pem; do
if [ -s "$candidate" ]; then
SYSTEM_BUNDLE="$candidate"
break
fi
done

if [ -z "$SYSTEM_BUNDLE" ]; then
echo "[entrypoint][WARN] No system CA bundle found — TLS may fail inside chroot"
return
fi

# Check if the bundle is already accessible inside the chroot via existing mounts.
# AWF mounts /etc/ssl and /etc/ca-certificates into the chroot; paths under those
# prefixes are already visible. Paths under /etc/pki (RHEL/Amazon Linux) are not.
local CHROOT_RELATIVE="${SYSTEM_BUNDLE#/host}"
case "$CHROOT_RELATIVE" in
/etc/ssl/*|/etc/ca-certificates/*)
# Already accessible via existing bind mounts
export SSL_CERT_FILE="$CHROOT_RELATIVE"
export NODE_EXTRA_CA_CERTS="$CHROOT_RELATIVE"
export REQUESTS_CA_BUNDLE="$CHROOT_RELATIVE"
export CURL_CA_BUNDLE="$CHROOT_RELATIVE"
export GIT_SSL_CAINFO="$CHROOT_RELATIVE"
echo "[entrypoint] System CA bundle found at $CHROOT_RELATIVE (already accessible in chroot)"
return
;;
esac

# Bundle is not accessible in chroot (e.g., /etc/pki paths). Copy it.
if mkdir -p /host/tmp/awf-lib 2>/dev/null; then
if cp "$SYSTEM_BUNDLE" /host/tmp/awf-lib/system-ca-certificates.crt 2>/dev/null && \
[ -s /host/tmp/awf-lib/system-ca-certificates.crt ]; then
local CA_PATH="/tmp/awf-lib/system-ca-certificates.crt"
SYSTEM_CA_CHROOT="$CA_PATH"
export SSL_CERT_FILE="$CA_PATH"
export NODE_EXTRA_CA_CERTS="$CA_PATH"
export REQUESTS_CA_BUNDLE="$CA_PATH"
export CURL_CA_BUNDLE="$CA_PATH"
export GIT_SSL_CAINFO="$CA_PATH"
echo "[entrypoint] System CA bundle copied from $SYSTEM_BUNDLE to $CA_PATH"
Comment on lines +778 to +788
else
echo "[entrypoint][WARN] Could not copy system CA bundle to chroot — TLS may fail"
fi
else
echo "[entrypoint][WARN] Could not create /host/tmp/awf-lib for system CA bundle"
fi
}

check_chroot_prereqs() {
# Verify prerequisites for chroot execution: glibc-based host, capsh, and bash.
# Each check fails fast with exit 1 on failure.
Expand Down Expand Up @@ -1109,6 +1204,7 @@ run_chroot_command() {
copy_agent_helper_scripts
copy_dind_runner_binary
copy_awf_ca_cert
copy_system_ca_bundle
setup_chroot_etc

# Determine working directory inside the chroot
Expand Down Expand Up @@ -1165,7 +1261,7 @@ run_chroot_command() {
echo "[entrypoint] host.docker.internal will be removed from /etc/hosts on exit"
fi
# Clean up /tmp/awf-lib if anything was copied (one-shot-token, CA cert, key helper)
if [ -n "${ONE_SHOT_TOKEN_LIB}" ] || [ -n "${AWF_CA_CHROOT}" ] || [ -n "${CHROOT_KEY_HELPER}" ] || [ -n "${STAGED_RUNNER_BINARY_CHROOT}" ]; then
if [ -n "${ONE_SHOT_TOKEN_LIB}" ] || [ -n "${AWF_CA_CHROOT}" ] || [ -n "${SYSTEM_CA_CHROOT}" ] || [ -n "${CHROOT_KEY_HELPER}" ] || [ -n "${STAGED_RUNNER_BINARY_CHROOT}" ]; then
CLEANUP_CMD="${CLEANUP_CMD}; rm -rf /tmp/awf-lib 2>/dev/null || true"
fi

Expand Down
2 changes: 2 additions & 0 deletions docs/chroot-mode.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ When `chroot.binariesSourcePath` is set in stdin config, AWF also mounts:

**Note:** As of v0.13.13, `/proc` is no longer bind-mounted. Instead, a fresh container-scoped procfs is mounted at `/host/proc` during entrypoint initialization. This provides dynamic `/proc/self/exe` resolution required by Java and .NET runtimes.

**System CA Bundle Detection:** The entrypoint automatically detects the host system CA bundle from common locations (Debian/Ubuntu `/etc/ssl/certs/ca-certificates.crt`, RHEL/Amazon Linux `/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem`, `/etc/pki/tls/certs/ca-bundle.crt`, `/etc/pki/tls/cert.pem`, macOS `/etc/ssl/cert.pem`). If the bundle is not already accessible in the chroot via existing mounts (e.g., `/etc/pki` paths), it is copied to `/tmp/awf-lib/system-ca-certificates.crt` and `SSL_CERT_FILE`, `NODE_EXTRA_CA_CERTS`, `REQUESTS_CA_BUNDLE`, `CURL_CA_BUNDLE`, and `GIT_SSL_CAINFO` are set to point at it.

### Read-Write Mounts

| Host Path | Container Path | Purpose |
Expand Down
27 changes: 27 additions & 0 deletions tests/entrypoint-phase-functions.test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ required_functions=(
copy_agent_helper_scripts
copy_dind_runner_binary
copy_awf_ca_cert
copy_system_ca_bundle
check_chroot_prereqs
setup_chroot_etc
build_path_script
Expand Down Expand Up @@ -102,13 +103,20 @@ CHROOT_BLOCK="$(awk '
in_fn { print }
' "${ENTRYPOINT}")"

COPY_SYSTEM_CA_BUNDLE_BLOCK="$(awk '
/^[[:space:]]*copy_system_ca_bundle\(\)[[:space:]]*\{[[:space:]]*$/ { in_fn=1; next }
in_fn && /^[[:space:]]*}[[:space:]]*$/ { in_fn=0; exit }
in_fn { print }
' "${ENTRYPOINT}")"

chroot_helpers=(
'mount_host_procfs'
'check_chroot_prereqs'
'copy_preload_libs'
'copy_agent_helper_scripts'
'copy_dind_runner_binary'
'copy_awf_ca_cert'
'copy_system_ca_bundle'
'setup_chroot_etc'
'build_path_script'
)
Expand All @@ -128,6 +136,25 @@ for helper in "${chroot_helpers[@]}"; do
pass "run_chroot_command() calls ${helper} in order"
done

if printf '%s\n' "${COPY_SYSTEM_CA_BUNDLE_BLOCK}" | grep -Fq 'if [ "${AWF_SSL_BUMP_ENABLED}" = "true" ]'; then
pass "copy_system_ca_bundle() keys SSL Bump handling off AWF_SSL_BUMP_ENABLED"
else
fail "copy_system_ca_bundle() does not key SSL Bump handling off AWF_SSL_BUMP_ENABLED"
fi

if printf '%s\n' "${COPY_SYSTEM_CA_BUNDLE_BLOCK}" | grep -Fq "printf '\\n'" && \
printf '%s\n' "${COPY_SYSTEM_CA_BUNDLE_BLOCK}" | grep -Fq '"/host${AWF_CA_CHROOT}"'; then
pass "copy_system_ca_bundle() appends system roots to the staged AWF CA bundle safely"
else
fail "copy_system_ca_bundle() does not safely append system roots to the staged AWF CA bundle"
fi

if grep -Eq '\[ -n "\$\{SYSTEM_CA_CHROOT\}" \]' "${ENTRYPOINT}"; then
pass "run_chroot_command() cleans up copied system CA bundles"
else
fail "run_chroot_command() does not clean up copied system CA bundles"
fi

echo ""
echo "Results: ${PASS} passed, ${FAIL} failed"

Expand Down
Loading