generated from Dicken/dickendock
HTTPS: eigene lokale Root-CA statt externem DuckDNS/Let's Encrypt
This commit is contained in:
@@ -2,37 +2,70 @@
|
||||
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}"
|
||||
|
||||
# Falls der Nutzer eigene Zertifikate eingebunden hat (siehe README, z. B.
|
||||
# per mkcert erzeugt), diese nicht überschreiben.
|
||||
if [ ! -f "$CERT_FILE" ] || [ ! -f "$KEY_FILE" ]; then
|
||||
HOST="${LAUNCHPAD_HOST:-localhost}"
|
||||
mkdir -p "$CERT_DIR"
|
||||
mkdir -p "$CERT_DIR"
|
||||
|
||||
# IP-Adresse oder Hostname? Browser verlangen bei IP-Zugriff eine
|
||||
# IP-SAN, ein DNS-Name genügt da nicht.
|
||||
case "$HOST" in
|
||||
*[0-9]*.*[0-9]*.*[0-9]*.*[0-9]*)
|
||||
SAN="IP:$HOST,DNS:localhost,IP:127.0.0.1"
|
||||
;;
|
||||
*)
|
||||
SAN="DNS:$HOST,DNS:localhost,IP:127.0.0.1"
|
||||
;;
|
||||
esac
|
||||
|
||||
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
|
||||
-keyout "$KEY_FILE" \
|
||||
-out "$CERT_FILE" \
|
||||
-subj "/CN=$HOST" \
|
||||
-addext "subjectAltName=$SAN" \
|
||||
2>/dev/null
|
||||
|
||||
echo "[entrypoint] Selbstsigniertes HTTPS-Zertifikat für '$HOST' erzeugt."
|
||||
echo "[entrypoint] Der Browser zeigt dafür eine Sicherheitswarnung - siehe README fuer eine Variante ohne Warnung (mkcert)."
|
||||
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
|
||||
echo "[entrypoint] Verwende eingebundenes Zertifikat unter $CERT_DIR."
|
||||
# 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
|
||||
|
||||
# Server-Zertifikat nur neu erzeugen, wenn es noch keins gibt oder sich
|
||||
# LAUNCHPAD_HOST geändert hat (dann würde die alte SAN nicht mehr passen).
|
||||
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" ]; then
|
||||
NEED_NEW_LEAF=true
|
||||
fi
|
||||
|
||||
if [ "$NEED_NEW_LEAF" = "true" ]; then
|
||||
case "$HOST" in
|
||||
*[0-9]*.*[0-9]*.*[0-9]*.*[0-9]*)
|
||||
SAN="IP:$HOST,DNS:localhost,IP:127.0.0.1"
|
||||
;;
|
||||
*)
|
||||
SAN="DNS:$HOST,DNS:localhost,IP:127.0.0.1"
|
||||
;;
|
||||
esac
|
||||
|
||||
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" > "$CERT_HOST_FILE"
|
||||
echo "[entrypoint] Server-Zertifikat für '$HOST' erzeugt und 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 "$@"
|
||||
|
||||
@@ -26,6 +26,14 @@ location = /manifest.webmanifest {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# Root-CA zum Download – Android/iOS erkennen diesen MIME-Type und bieten
|
||||
# beim Öffnen im Browser direkt "Zertifikat installieren" an.
|
||||
location = /ca.crt {
|
||||
add_header Cache-Control "no-cache";
|
||||
default_type application/x-x509-ca-cert;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ~* \.(?:css|js|svg|png|jpg|jpeg|gif|ico|woff2?)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, max-age=604800, immutable";
|
||||
|
||||
Reference in New Issue
Block a user