generated from Dicken/dickendock
83 lines
3.0 KiB
Bash
83 lines
3.0 KiB
Bash
#!/bin/sh
|
|
set -e
|
|
|
|
CERT_DIR="/etc/nginx/certs"
|
|
CA_KEY="$CERT_DIR/ca-key.pem"
|
|
CA_CERT="$CERT_DIR/ca-cert.pem"
|
|
CERT_FILE="$CERT_DIR/fullchain.pem"
|
|
KEY_FILE="$CERT_DIR/privkey.pem"
|
|
CERT_HOST_FILE="$CERT_DIR/.cert-host"
|
|
HOST="${LAUNCHPAD_HOST:-localhost}"
|
|
EXTRA_HOST="${LAUNCHPAD_EXTRA_HOST:-}"
|
|
|
|
mkdir -p "$CERT_DIR"
|
|
|
|
# Baut einen SAN-Eintrag (IP:... oder DNS:...) für einen einzelnen Hostwert.
|
|
san_entry_for() {
|
|
case "$1" in
|
|
*[0-9]*.*[0-9]*.*[0-9]*.*[0-9]*)
|
|
echo "IP:$1"
|
|
;;
|
|
*)
|
|
echo "DNS:$1"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
if [ -f "$CERT_FILE" ] && [ -f "$KEY_FILE" ] && [ ! -f "$CA_CERT" ]; then
|
|
# fullchain.pem/privkey.pem wurden vom Nutzer eingebunden (z. B. eigenes
|
|
# Zertifikat) und es gibt keine von uns erzeugte CA dazu -> nichts anfassen.
|
|
echo "[entrypoint] Eingebundenes Zertifikat gefunden (kein CA-Download unter /ca.crt verfügbar)."
|
|
else
|
|
# Eigene lokale Root-CA erzeugen, falls noch keine existiert. Liegt im
|
|
# Volume "launchpad-certs" und bleibt über Neustarts/Rebuilds stabil -
|
|
# einmal pro Gerät importiert, reicht dauerhaft.
|
|
if [ ! -f "$CA_KEY" ] || [ ! -f "$CA_CERT" ]; then
|
|
echo "[entrypoint] Erzeuge neue lokale Root-CA für LaunchPad..."
|
|
openssl genrsa -out "$CA_KEY" 2048 2>/dev/null
|
|
openssl req -x509 -new -nodes -key "$CA_KEY" -sha256 -days 3650 \
|
|
-subj "/CN=LaunchPad Local CA" \
|
|
-out "$CA_CERT" 2>/dev/null
|
|
fi
|
|
|
|
# Kombinierte Kennung aus HOST + EXTRA_HOST, um zu erkennen ob sich einer
|
|
# von beiden geändert hat -> dann Server-Zertifikat neu ausstellen. Die CA
|
|
# selbst bleibt davon unberührt (bereits erteiltes Gerätevertrauen gilt weiter).
|
|
HOST_SIGNATURE="$HOST|$EXTRA_HOST"
|
|
NEED_NEW_LEAF=false
|
|
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then
|
|
NEED_NEW_LEAF=true
|
|
elif [ "$(cat "$CERT_HOST_FILE" 2>/dev/null)" != "$HOST_SIGNATURE" ]; then
|
|
NEED_NEW_LEAF=true
|
|
fi
|
|
|
|
if [ "$NEED_NEW_LEAF" = "true" ]; then
|
|
SAN="$(san_entry_for "$HOST"),DNS:localhost,IP:127.0.0.1"
|
|
if [ -n "$EXTRA_HOST" ] && [ "$EXTRA_HOST" != "$HOST" ]; then
|
|
SAN="$SAN,$(san_entry_for "$EXTRA_HOST")"
|
|
fi
|
|
|
|
EXTFILE=$(mktemp)
|
|
printf "subjectAltName=%s\nbasicConstraints=CA:FALSE\nkeyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth\n" "$SAN" > "$EXTFILE"
|
|
|
|
openssl genrsa -out "$KEY_FILE" 2048 2>/dev/null
|
|
openssl req -new -key "$KEY_FILE" -subj "/CN=$HOST" -out "$CERT_DIR/server.csr" 2>/dev/null
|
|
openssl x509 -req -in "$CERT_DIR/server.csr" -CA "$CA_CERT" -CAkey "$CA_KEY" \
|
|
-CAcreateserial -days 825 -sha256 -extfile "$EXTFILE" \
|
|
-out "$CERT_FILE" 2>/dev/null
|
|
|
|
rm -f "$EXTFILE" "$CERT_DIR/server.csr"
|
|
echo "$HOST_SIGNATURE" > "$CERT_HOST_FILE"
|
|
echo "[entrypoint] Server-Zertifikat erzeugt (SAN: $SAN), mit lokaler CA signiert."
|
|
fi
|
|
fi
|
|
|
|
# CA-Zertifikat zum Download bereitstellen (Android/iOS/Windows bieten beim
|
|
# Öffnen einer .crt-Datei im Browser automatisch "Zertifikat installieren" an).
|
|
if [ -f "$CA_CERT" ]; then
|
|
mkdir -p /usr/share/nginx/html
|
|
cp "$CA_CERT" /usr/share/nginx/html/ca.crt
|
|
fi
|
|
|
|
exec "$@"
|