Private
Public Access
1
0

feat: setup.sh generates CA-signed web cert instead of self-signed
Some checks failed
CI Pipeline / Rust Format Check (push) Failing after 4s
CI Pipeline / Clippy Lints (push) Successful in 46s
CI Pipeline / Rust Unit Tests (push) Successful in 1m1s
CI Pipeline / Security Audit (push) Successful in 4s
CI Pipeline / Frontend Lint & Type Check (push) Failing after 10s
CI Pipeline / Build .deb & Release (push) Has been skipped

- Generate internal CA (ECDSA P-256, 10-year validity) if not present
- Sign web server cert with internal CA (1-year validity)
- Add SANs for hostname, short hostname, localhost, and host IP
- Add EKU: serverAuth to web cert
- pm-ca will load existing CA on startup
- Simplify host cert section to only show agent deployment files
This commit is contained in:
2026-05-06 02:08:01 +00:00
parent 812b23d2d0
commit ee33ba5740

View File

@ -11,6 +11,7 @@
# - Copies configuration and binaries # - Copies configuration and binaries
# - Installs systemd units # - Installs systemd units
# - Generates initial Ed25519 JWT keys # - Generates initial Ed25519 JWT keys
# - Generates internal CA and CA-signed web server certificate
# ============================================================================= # =============================================================================
set -euo pipefail set -euo pipefail
@ -160,27 +161,58 @@ else
fi fi
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
# 6b. Generate self-signed TLS certificate for HTTPS # 6b. Generate CA and CA-signed TLS certificate for HTTPS
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
CA_KEY="${CONFIG_DIR}/ca/ca.key"
CA_CERT="${CONFIG_DIR}/ca/ca.crt"
TLS_CERT="${CONFIG_DIR}/tls/web.crt" TLS_CERT="${CONFIG_DIR}/tls/web.crt"
TLS_KEY="${CONFIG_DIR}/tls/web.key" TLS_KEY="${CONFIG_DIR}/tls/web.key"
TLS_CSR="${CONFIG_DIR}/tls/web.csr"
# Generate CA if not present (pm-ca will load this on startup)
if [[ ! -f "${CA_CERT}" ]]; then
info "Generating internal Certificate Authority (ECDSA P-256, 10-year validity)..."
openssl ecparam -genkey -name prime256v1 -noout -out "${CA_KEY}"
openssl req -new -x509 -key "${CA_KEY}" -out "${CA_CERT}" \
-days 3650 \
-subj "/CN=Patch Manager Root CA/O=Patch Manager" \
-addext "basicConstraints=critical,CA:true" \
-addext "keyUsage=critical,keyCertSign,cRLSign"
chown "${SERVICE_USER}:${SERVICE_GROUP}" "${CA_KEY}" "${CA_CERT}"
chmod 600 "${CA_KEY}" "${CA_CERT}"
info "Internal CA generated."
else
info "Internal CA already exists at ${CA_CERT}, skipping."
fi
# Generate web server certificate signed by the internal CA
if [[ ! -f "${TLS_CERT}" ]]; then if [[ ! -f "${TLS_CERT}" ]]; then
info "Generating self-signed TLS certificate (valid 365 days)..." info "Generating CA-signed web server certificate (valid 365 days)..."
# Generate ECDSA P-256 private key
openssl ecparam -genkey -name prime256v1 -noout -out "${TLS_KEY}"
# Generate self-signed cert with SAN for localhost and the host's FQDN
HOSTNAME_FQDN=$(hostname -f 2>/dev/null || echo "localhost") HOSTNAME_FQDN=$(hostname -f 2>/dev/null || echo "localhost")
HOSTNAME_SHORT=$(hostname -s 2>/dev/null || echo "localhost") HOSTNAME_SHORT=$(hostname -s 2>/dev/null || echo "localhost")
openssl req -new -x509 -key "${TLS_KEY}" -out "${TLS_CERT}" \ # Get the host's primary IP address for SAN
-days 365 \ HOST_IP=$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{print $7; exit}' || echo "127.0.0.1")
-subj "/CN=${HOSTNAME_FQDN}/O=Linux Patch Manager" \
-addext "subjectAltName=DNS:${HOSTNAME_FQDN},DNS:${HOSTNAME_SHORT},DNS:localhost,IP:127.0.0.1,IP:::1" # Generate ECDSA P-256 private key for web server
openssl ecparam -genkey -name prime256v1 -noout -out "${TLS_KEY}"
# Generate CSR with SANs
openssl req -new -key "${TLS_KEY}" -out "${TLS_CSR}" \
-subj "/CN=${HOSTNAME_FQDN}/O=Patch Manager" \
-addext "subjectAltName=DNS:${HOSTNAME_FQDN},DNS:${HOSTNAME_SHORT},DNS:localhost,IP:${HOST_IP},IP:127.0.0.1,IP:::1"
# Sign with the internal CA
openssl x509 -req -in "${TLS_CSR}" -CA "${CA_CERT}" -CAkey "${CA_KEY}" \
-CAcreateserial -days 365 -out "${TLS_CERT}" \
-extfile <(printf "subjectAltName=DNS:${HOSTNAME_FQDN},DNS:${HOSTNAME_SHORT},DNS:localhost,IP:${HOST_IP},IP:127.0.0.1,IP:::1\nextendedKeyUsage=serverAuth")
# Clean up CSR
rm -f "${TLS_CSR}"
chown "${SERVICE_USER}:${SERVICE_GROUP}" "${TLS_CERT}" "${TLS_KEY}" chown "${SERVICE_USER}:${SERVICE_GROUP}" "${TLS_CERT}" "${TLS_KEY}"
chmod 644 "${TLS_CERT}" chmod 644 "${TLS_CERT}"
chmod 600 "${TLS_KEY}" chmod 600 "${TLS_KEY}"
info "TLS certificate generated for ${HOSTNAME_FQDN}." info "CA-signed web server certificate generated for ${HOSTNAME_FQDN}."
warn "Self-signed certificate — replace with CA-signed cert for production!"
else else
warn "TLS certificate already exists at ${TLS_CERT}, skipping." warn "TLS certificate already exists at ${TLS_CERT}, skipping."
fi fi