mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
feat(ca): trust package-cache frontend CA in build containers
The package-cache frontend MITMs the registry with a cert signed by an independent CA, not the stack root CA. Wire that extra CA into all three container entry points so npm traffic through the cache validates. Gated on the CA file existing, so it is a no-op when the cache is inactive. - container.py: mount the frontend CA and set CA_TRUST_CERT_EXTRA in the container-run wrapper - with-ca-trust.sh: consume CA_TRUST_CERT_EXTRA (combined bundle for single-file readers plus a separate OS trust anchor) - compose_ca.py: compose and swarm side injection (env-only when unwrapped) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
0a3570ecea
commit
e79183f96a
3 files changed
+61
-35
No files matched your search
@@ -26,7 +26,6 @@ if [ ! -r "$CA_TRUST_CERT" ]; then
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Sanitize trust name
|
||||
name="$(printf '%s' "$CA_TRUST_NAME" | tr -c 'A-Za-z0-9._-' '_' )"
|
||||
if [ -z "$name" ]; then
|
||||
echo "[with-ca-trust] ERROR: CA_TRUST_NAME resolved to empty after sanitization" >&2
|
||||
@@ -37,13 +36,21 @@ log "Sanitized trust name: $name"
|
||||
|
||||
installed=0
|
||||
|
||||
# Always provide env-based trust hints as a fallback (works for many TLS stacks)
|
||||
export SSL_CERT_FILE="$CA_TRUST_CERT"
|
||||
export REQUESTS_CA_BUNDLE="$CA_TRUST_CERT"
|
||||
export CURL_CA_BUNDLE="$CA_TRUST_CERT"
|
||||
# Optional (harmless if unused; helps Node-based tools if any)
|
||||
export NODE_EXTRA_CA_CERTS="$CA_TRUST_CERT"
|
||||
|
||||
if [ -n "${CA_TRUST_CERT_EXTRA:-}" ] && [ -r "${CA_TRUST_CERT_EXTRA}" ]; then
|
||||
combined="/tmp/infinito/ca-trust-combined.crt"
|
||||
mkdir -p "$(dirname "$combined")"
|
||||
cat "$CA_TRUST_CERT" "$CA_TRUST_CERT_EXTRA" > "$combined"
|
||||
export SSL_CERT_FILE="$combined"
|
||||
export REQUESTS_CA_BUNDLE="$combined"
|
||||
export CURL_CA_BUNDLE="$combined"
|
||||
export NODE_EXTRA_CA_CERTS="$combined"
|
||||
fi
|
||||
|
||||
install_anchor() {
|
||||
src="$1"
|
||||
dst="$2"
|
||||
@@ -58,9 +65,6 @@ install_anchor() {
|
||||
return 1
|
||||
}
|
||||
|
||||
#
|
||||
# Debian / Ubuntu style
|
||||
#
|
||||
if command -v update-ca-certificates >/dev/null 2>&1; then
|
||||
log "Detected update-ca-certificates"
|
||||
if install_anchor "$CA_TRUST_CERT" "/usr/local/share/ca-certificates/${name}.crt"; then
|
||||
@@ -68,9 +72,6 @@ if command -v update-ca-certificates >/dev/null 2>&1; then
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# RHEL / p11-kit style
|
||||
#
|
||||
if command -v update-ca-trust >/dev/null 2>&1; then
|
||||
log "Detected update-ca-trust"
|
||||
if install_anchor "$CA_TRUST_CERT" "/etc/pki/ca-trust/source/anchors/${name}.crt"; then
|
||||
@@ -78,9 +79,6 @@ if command -v update-ca-trust >/dev/null 2>&1; then
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Arch / pure p11-kit style
|
||||
#
|
||||
if command -v trust >/dev/null 2>&1; then
|
||||
log "Detected trust"
|
||||
if install_anchor "$CA_TRUST_CERT" "/etc/ca-certificates/trust-source/anchors/${name}.crt"; then
|
||||
@@ -88,18 +86,19 @@ if command -v trust >/dev/null 2>&1; then
|
||||
fi
|
||||
fi
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Chromium / NSS trust (per-user DB)
|
||||
#
|
||||
# Puppeteer/Chromium often uses NSS trust DB and may ignore OS CA store.
|
||||
# Import the CA into the user's NSS DB if certutil is available.
|
||||
#
|
||||
# Requires:
|
||||
# - Debian/Ubuntu: apt-get install libnss3-tools
|
||||
# - Alpine: apk add nss-tools
|
||||
# ------------------------------------------------------------
|
||||
if [ -n "${CA_TRUST_CERT_EXTRA:-}" ] && [ -r "${CA_TRUST_CERT_EXTRA}" ]; then
|
||||
if command -v update-ca-certificates >/dev/null 2>&1 && install_anchor "$CA_TRUST_CERT_EXTRA" "/usr/local/share/ca-certificates/${name}-extra.crt"; then
|
||||
run update-ca-certificates || true
|
||||
fi
|
||||
if command -v update-ca-trust >/dev/null 2>&1 && install_anchor "$CA_TRUST_CERT_EXTRA" "/etc/pki/ca-trust/source/anchors/${name}-extra.crt"; then
|
||||
run update-ca-trust extract || true
|
||||
fi
|
||||
if command -v trust >/dev/null 2>&1 && install_anchor "$CA_TRUST_CERT_EXTRA" "/etc/ca-certificates/trust-source/anchors/${name}-extra.crt"; then
|
||||
run trust extract-compat || true
|
||||
fi
|
||||
fi
|
||||
|
||||
if command -v certutil >/dev/null 2>&1; then
|
||||
# Prefer real HOME; fall back to a writable temp dir
|
||||
home_dir="${HOME:-}"
|
||||
if [ -z "$home_dir" ] || [ ! -d "$home_dir" ] || [ ! -w "$home_dir" ]; then
|
||||
home_dir="/tmp"
|
||||
@@ -108,18 +107,14 @@ if command -v certutil >/dev/null 2>&1; then
|
||||
nss_db="${home_dir}/.pki/nssdb"
|
||||
log "Detected certutil; importing CA into NSS DB: ${nss_db}"
|
||||
|
||||
# Ensure directory exists
|
||||
run mkdir -p "$nss_db" 2>/dev/null || true
|
||||
|
||||
# Create NSS DB if missing (empty password)
|
||||
if [ ! -f "$nss_db/cert9.db" ]; then
|
||||
run certutil -N -d "sql:${nss_db}" --empty-password 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# Remove existing cert entry (best-effort)
|
||||
run certutil -D -d "sql:${nss_db}" -n "$name" >/dev/null 2>&1 || true
|
||||
|
||||
# Import as trusted CA (C,, = trusted CA for SSL)
|
||||
run certutil -A -d "sql:${nss_db}" -n "$name" -t "C,," -i "$CA_TRUST_CERT" 2>/dev/null || true
|
||||
|
||||
log "NSS trust import attempted (best-effort)"
|
||||
|
||||
@@ -502,6 +502,16 @@ def _load_services_via_config(
|
||||
return services
|
||||
|
||||
|
||||
def _cache_frontend_ca_host() -> str:
|
||||
"""Runner-internal path to the package-cache frontend CA, or '' when the cache is inactive."""
|
||||
path = os.environ.get(
|
||||
"CA_TRUST_CERT_EXTRA_HOST", "/opt/package-frontend-ca.crt"
|
||||
).strip()
|
||||
if path and Path(path).is_file() and Path(path).stat().st_size > 0:
|
||||
return path
|
||||
return ""
|
||||
|
||||
|
||||
def render_override(
|
||||
services: dict[str, Any],
|
||||
service_to_compose_cmd: dict[str, list[str]],
|
||||
@@ -537,6 +547,7 @@ def render_override(
|
||||
We escape any $ in the command argv with $$ so container-side expansion works.
|
||||
"""
|
||||
out_services: dict[str, Any] = {}
|
||||
extra_ca_host = _cache_frontend_ca_host()
|
||||
|
||||
image_meta = gather_image_meta(
|
||||
sorted(
|
||||
@@ -563,16 +574,22 @@ def render_override(
|
||||
if php_ini_host and php_ini_container:
|
||||
volumes.append(f"{php_ini_host}:{php_ini_container}:ro")
|
||||
|
||||
environment: dict[str, str] = {
|
||||
"CA_TRUST_CERT": ca_container,
|
||||
"CA_TRUST_NAME": trust_name,
|
||||
"SSL_CERT_FILE": ca_container,
|
||||
"REQUESTS_CA_BUNDLE": ca_container,
|
||||
"CURL_CA_BUNDLE": ca_container,
|
||||
"NODE_EXTRA_CA_CERTS": ca_container,
|
||||
}
|
||||
if extra_ca_host:
|
||||
extra_ca_container = str(Path(ca_container).parent / "ca-trust-extra.crt")
|
||||
volumes.append(f"{extra_ca_host}:{extra_ca_container}:ro")
|
||||
environment["CA_TRUST_CERT_EXTRA"] = extra_ca_container
|
||||
|
||||
override_svc: dict[str, Any] = {
|
||||
"volumes": volumes,
|
||||
"environment": {
|
||||
"CA_TRUST_CERT": ca_container,
|
||||
"CA_TRUST_NAME": trust_name,
|
||||
"SSL_CERT_FILE": ca_container,
|
||||
"REQUESTS_CA_BUNDLE": ca_container,
|
||||
"CURL_CA_BUNDLE": ca_container,
|
||||
"NODE_EXTRA_CA_CERTS": ca_container,
|
||||
},
|
||||
"environment": environment,
|
||||
}
|
||||
|
||||
if not wrap:
|
||||
|
||||
@@ -341,10 +341,24 @@ def container_run(argv: list[str], debug: bool, with_ca: bool) -> int:
|
||||
"--entrypoint",
|
||||
wrapper_container,
|
||||
]
|
||||
extra_opts: list[str] = []
|
||||
extra_host = os.environ.get(
|
||||
"CA_TRUST_CERT_EXTRA_HOST", "/opt/package-frontend-ca.crt"
|
||||
).strip()
|
||||
extra_path = Path(extra_host) if extra_host else None
|
||||
if extra_path and extra_path.is_file() and extra_path.stat().st_size > 0:
|
||||
extra_container = str(Path(ca_container).parent / "ca-trust-extra.crt")
|
||||
extra_opts = [
|
||||
"-v",
|
||||
f"{extra_host}:{extra_container}:ro",
|
||||
"-e",
|
||||
f"CA_TRUST_CERT_EXTRA={extra_container}",
|
||||
]
|
||||
|
||||
final_cmd: list[str] = ["docker", "run"]
|
||||
final_cmd.extend(run_opts)
|
||||
final_cmd.extend(inject_opts)
|
||||
final_cmd.extend(extra_opts)
|
||||
final_cmd.append(image)
|
||||
|
||||
if user_entrypoint:
|
||||
|
||||
Reference in new issue
Block a user