From f354bddd1eabe232bf4a41fe2599d59258ac55ea Mon Sep 17 00:00:00 2001 From: patrick Date: Wed, 5 Aug 2026 19:36:19 +0200 Subject: [PATCH] =?UTF-8?q?feat(tls):=20optionales=20Setup=20f=C3=BCr=20in?= =?UTF-8?q?terne=20CA=20vorbereitet?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit setup-tls-internal.sh: Alternative zu setup-tls.sh für rein internes Netz ohne öffentliches DNS. Baut einmalig eine interne Root-CA + signiert Server-Zertifikate damit (openssl, kein Let's Encrypt). Root-CA muss auf Clients importiert werden, danach keine Browser-Warnung mehr für alle künftigen intern signierten Server. Nicht ausgeführt, bleibt inaktiv bis manuell gestartet. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01LTxkZEUdfgMxZvHPiZJ8bV --- setup-tls-internal.sh | 83 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 setup-tls-internal.sh diff --git a/setup-tls-internal.sh b/setup-tls-internal.sh new file mode 100755 index 0000000..41f61ef --- /dev/null +++ b/setup-tls-internal.sh @@ -0,0 +1,83 @@ +#!/usr/bin/env bash +# ============================================================================= +# setup-tls-internal.sh – AUF DEM SERVER ausführen (nicht lokal), OPTIONAL +# +# Alternative zu setup-tls.sh für rein internes Netz OHNE öffentliches DNS: +# baut eine eigene interne CA (einmalig) + signiert damit ein Server- +# Zertifikat für diesen Host. Kein Let's Encrypt, kein Internet nötig, +# funktioniert mit internem Hostnamen ODER reiner IP im SAN. +# +# Unterschied zu selbstsigniertem Einzelzertifikat: die CA wird EINMAL auf +# allen Firmengeräten importiert (Browser/OS-Trust-Store), danach zeigt KEIN +# Client mehr eine Warnung – auch nicht für weitere, später signierte Server. +# +# Noch NICHT ausgeführt / nicht Teil des Deploys. Erst starten wenn: +# - Server rein intern bleibt (kein öffentliches DNS gewollt), UND +# - Klarheit besteht, welche Geräte die CA importieren sollen (Kiosk-Tablets, +# Mitarbeiter-Laptops, ...) – sonst wieder Browser-Warnungen wie bei +# einfachem Self-Signed-Zertifikat. +# +# Usage (Beispiel): +# ./setup-tls-internal.sh timemaster.local 192.168.1.137 +# -> erzeugt /etc/nginx/internal-ca/ca.crt (auf Clients zu importieren) +# und /etc/nginx/internal-ca/server.crt + server.key (für nginx) +# +# CA-Gültigkeit hier bewusst lang (10 Jahre) – interne CA, kein öffentliches +# Vertrauen, Rotation liegt in eigener Hand. Server-Zertifikat 825 Tage +# (Browser-Maximalgrenze für öffentliche CAs, hier nicht zwingend, aber als +# vernünftige Rotationsfrist übernommen). +# ============================================================================= +set -euo pipefail + +HOSTNAME_ARG="${1:-}" +IP_ARG="${2:-}" +if [[ -z "$HOSTNAME_ARG" ]]; then + echo "Usage: ./setup-tls-internal.sh [ip]" >&2 + echo "Beispiel: ./setup-tls-internal.sh timemaster.local 192.168.1.137" >&2 + exit 1 +fi + +CA_DIR="/etc/nginx/internal-ca" +mkdir -p "$CA_DIR" +cd "$CA_DIR" + +if [[ ! -f ca.key ]]; then + echo "==> Erzeuge interne Root-CA (einmalig, 10 Jahre gültig)" + openssl genrsa -out ca.key 4096 + openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 \ + -subj "/CN=TimeMaster Internal CA" -out ca.crt + echo " Root-CA erzeugt: $CA_DIR/ca.crt" + echo " -> MUSS auf allen Clients als vertrauenswürdige Root importiert werden" +else + echo "==> Bestehende interne CA gefunden, wiederverwendet ($CA_DIR/ca.crt)" +fi + +echo "==> Erzeuge Server-Zertifikat für $HOSTNAME_ARG" +SAN="DNS:$HOSTNAME_ARG" +[[ -n "$IP_ARG" ]] && SAN="$SAN,IP:$IP_ARG" + +openssl genrsa -out server.key 2048 +openssl req -new -key server.key -subj "/CN=$HOSTNAME_ARG" -out server.csr + +cat > server.ext < Fertig. Nächste Schritte:" +echo " 1. $CA_DIR/ca.crt auf Clients importieren (Browser/OS-Trust-Store," +echo " bei Kiosk-Tablets/MDM zentral verteilen)" +echo " 2. nginx.conf 443-Block ergänzen:" +echo " ssl_certificate $CA_DIR/server.crt;" +echo " ssl_certificate_key $CA_DIR/server.key;" +echo " 3. nginx -t && systemctl reload nginx" +echo "" +echo " Renewal: Skript einfach erneut mit gleichem Hostnamen aufrufen" +echo " (CA bleibt, nur server.crt/server.key werden neu signiert)."