Proxy-Hosts ueber die API statt ueber den Terminal-Browser

Drei zusammenhaengende Befunde aus der Praxis, alle am laufenden
Container nachgeprueft:

1. Die Standardzugangsdaten admin@example.com/changeme stimmen nicht
   mehr. In backend/setup.js von v2.15.1 steht, dass das erste Konto
   nur angelegt wird, wenn INITIAL_ADMIN_EMAIL und
   INITIAL_ADMIN_PASSWORD gesetzt sind - sonst kommt der
   Einrichtungsassistent. Meine README war an der Stelle falsch.
   Die beiden Werte stehen jetzt als NPM_ADMIN_EMAIL/-PASSWORD in der
   .env und werden von compose und der Quadlet-Unit durchgereicht.
   Gegen einen frisch gestarteten Container geprueft: das Konto ist
   sofort da und die Anmeldung an der API liefert ein Token.

2. Die Weboberfliche laesst sich im Terminal-Browser kaum bedienen
   (JSON-Fehler bei Proxy-Hosts, keine Datei-Uploads). Da der Proxy
   Manager ohnehin lokal laeuft, gibt es jetzt

     proxy status | list | certs | add | del

   Damit legt "proxy add --domain X" in einem Zug an: Zertifikat
   erzeugen bzw. bei Let's Encrypt anfordern, hochladen, Proxy-Host
   anlegen, HTTPS erzwingen, HTTP/2 und Websockets setzen. Der Zielport
   ist frei waehlbar (--forward-port), nicht auf 5000 festgelegt.
   Im Menue unter "proxy" und in den Einstellungen unter NGINX Proxy
   Manager.

3. Let's Encrypt nimmt in 2.15 die E-Mail des angemeldeten Kontos; ein
   letsencrypt_email im Aufruf gibt es nicht mehr. Entsprechend
   umgesetzt und im Fehlerfall erklaert.

Beim Testen gegen die echte Instanz gefunden und behoben:
  - Wieder "set -e": ein grep ohne Treffer beendete das Skript still,
    "proxy add" tat daraufhin gar nichts. Vier Stellen abgesichert.
  - Die Listenantwort laesst sich nicht an "{" zerlegen, weil
    "meta":{...} ebenfalls Klammern enthaelt - dadurch fehlte das
    Schema in der Ausgabe. Die Eintraege werden jetzt einzeln geholt.
  - --update legte jedes Mal ein neues Zertifikat an. Ein vorhandener
    eigener Eintrag gleichen Namens wird jetzt wiederverwendet.

Durchgespielt: Anmeldung, Anlegen mit selbstsigniertem Zertifikat,
Liste, Zertifikatsliste, --update, Loeschen, Neuanlage mit anderem
Zielport und alle Fehlerfaelle. Gegengeprueft, dass Port 443 danach
tatsaechlich mit unserem Zertifikat antwortet (CN=checkmk.test.local)
und Port 80 per 301 dorthin umleitet.

Dokumentiert als Kapitel 10.1 bis 10.3 in beiden Sprachfassungen.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-20 17:36:21 +02:00
co-authored by Claude Opus 5
parent c04b3171d9
commit 9c99429c15
7 changed files with 632 additions and 21 deletions
+429 -1
View File
@@ -167,6 +167,21 @@ KOMMANDOS - Lokale Bedienung ohne externen Zugriff
--build Werkzeug-Image neu bauen
--pull Engine-Image neu laden
KOMMANDOS - Proxy-Hosts (ueber die API des Proxy Managers)
proxy status Anmeldung pruefen, Anzahl Hosts/Zertifikate
proxy list vorhandene Proxy-Hosts
proxy certs vorhandene Zertifikate
proxy add [Opt.] Proxy-Host anlegen
--domain FQDN oeffentlicher Name (Vorgabe: PROXY_DOMAIN)
--forward-host H Ziel (Vorgabe 127.0.0.1)
--forward-port P Zielport (Vorgabe 5000 = Checkmk)
--scheme http|https
--cert self|letsencrypt|none (Vorgabe self)
--update vorhandenen Host ersetzen
--advanced TEXT eigener nginx-Abschnitt
--no-force-ssl --no-http2 --no-websockets --no-block-exploits
proxy del --id N Proxy-Host loeschen
KOMMANDOS - Zertifikat
cert [Optionen] selbstsigniertes Zertifikat fuer den Proxy erzeugen
--domain FQDN Common Name / SAN
@@ -2641,7 +2656,12 @@ checkmk|CMK_HOSTNAME|text|Hostname im Container||
checkmk|CMK_LIVESTATUS_TCP|choice|Livestatus ueber TCP (Port 6557)|off:on|
checkmk|MAIL_RELAY_HOST|text|SMTP-Relay fuer Benachrichtigungen||1
npm|NPM_ENABLED|choice|Proxy Manager betreiben|on:off|
npm|NPM_ADMIN_EMAIL|text|Konto des Proxy Managers (E-Mail)||1
npm|NPM_ADMIN_PASSWORD|password|Kennwort des Proxy-Manager-Kontos||1
npm|NPM_ADMIN_PORT|port|Port der Adminoberflaeche||
npm|PROXY_DOMAIN|text|Vorgabe-Domain fuer Proxy-Hosts||1
npm|PROXY_FORWARD_HOST|text|Weiterleitungsziel (Host)||
npm|PROXY_FORWARD_PORT|port|Weiterleitungsziel (Port)||
npm|NPM_IMAGE|text|Image des Proxy Managers||
npm|NPM_CONTAINER_NAME|text|Containername Proxy Manager||
npm|NPM_DISABLE_IPV6|choice|IPv6 abschalten|true:false|
@@ -3018,6 +3038,300 @@ EOF
$RUNTIME run "${runopts[@]}" "$image" "${args[@]}"
}
# =====================================================================
# Proxy-Hosts ueber die REST-Schnittstelle des NGINX Proxy Managers
#
# Die Weboberflaeche laesst sich im Terminal-Browser nur muehsam
# bedienen - Datei-Uploads und einzelne Dialoge funktionieren dort
# nicht. Da der Proxy Manager ohnehin lokal laeuft, ist die API der
# verlaesslichere Weg.
#
# Voraussetzung ist ein Konto. Seit Version 2.15 legt der Container es
# nur noch an, wenn INITIAL_ADMIN_EMAIL und INITIAL_ADMIN_PASSWORD
# gesetzt sind (das erledigt die .env ueber NPM_ADMIN_EMAIL/-PASSWORD)
# - sonst erscheint beim ersten Aufruf ein Einrichtungsassistent.
#
# Geprueft an der Schnittstellenbeschreibung von v2.15.1:
# POST /api/tokens {identity, secret}
# GET|POST|DELETE /api/nginx/proxy-hosts
# POST /api/nginx/certificates {provider, ...}
# POST /api/nginx/certificates/<id>/upload multipart
# Let's Encrypt nimmt die E-Mail des angemeldeten Kontos - ein
# "letsencrypt_email" im Aufruf gibt es in 2.15 nicht mehr.
# =====================================================================
npm_api_base() { printf 'http://127.0.0.1:%s\n' "${NPM_ADMIN_PORT:-81}"; }
# Sehr einfache Auswertung - kein jq noetig, das fehlt auf vielen Hosts
json_num() { printf '%s' "$1" | tr ',' '\n' | sed -n "s/.*\"$2\"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p" | head -n1; }
json_str() { printf '%s' "$1" | tr ',' '\n' | sed -n "s/.*\"$2\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -n1; }
# IDs aus einer Listenantwort ziehen. "id": trifft dabei NICHT auf
# certificate_id oder owner_user_id zu, weil dort ein _ vor dem id steht.
json_ids() { printf '%s' "$1" | grep -o '"id":[0-9]*' | sed 's/.*://' ; }
npm_api_token() {
local base; base="$(npm_api_base)"
[ -n "${NPM_ADMIN_EMAIL:-}" ] && [ -n "${NPM_ADMIN_PASSWORD:-}" ] || {
err "Es sind keine Zugangsdaten fuer den Proxy Manager hinterlegt."
cat >&2 <<EOF
In der .env eintragen:
NPM_ADMIN_EMAIL=...
NPM_ADMIN_PASSWORD=...
Beim ERSTEN Start mit leerer Datenbank legt der Container damit das
Konto selbst an. Besteht das Konto schon, hier dessen Daten eintragen.
EOF
return 1
}
local body
body="$(curl -sS --max-time 20 -X POST "$base/api/tokens" \
-H 'Content-Type: application/json' \
-d "{\"identity\":\"$NPM_ADMIN_EMAIL\",\"secret\":\"$NPM_ADMIN_PASSWORD\"}" 2>/dev/null)" || true
local tok; tok="$(json_str "$body" token)"
if [ -z "$tok" ]; then
err "Anmeldung am Proxy Manager fehlgeschlagen."
local m; m="$(json_str "$body" message)"
[ -n "$m" ] && printf ' Antwort: %s\n' "$m" >&2
printf ' Geprueft wurde: %s\n' "$base/api/tokens" >&2
return 1
fi
printf '%s' "$tok"
}
# npm_api METHODE PFAD [JSON] -> Antwort auf stdout, HTTP-Code in NPM_CODE
npm_api() {
local method="$1" path="$2" data="${3:-}"
local base; base="$(npm_api_base)"
local -a a=(-sS --max-time 60 -X "$method" -H "Authorization: Bearer $NPM_TOKEN"
-w '\n%{http_code}')
[ -n "$data" ] && a+=(-H 'Content-Type: application/json' -d "$data")
local out; out="$(curl "${a[@]}" "$base$path" 2>/dev/null)" || out=$'\n000'
NPM_CODE="${out##*$'\n'}"
printf '%s' "${out%$'\n'*}"
}
npm_require_running() {
npm_enabled || { err "Der NGINX Proxy Manager ist abgeschaltet (NPM_ENABLED=off)."
log "Einschalten: $SELF npm-enable on"; return 1; }
container_running "$NPM_CONTAINER_NAME" || {
err "Der Container '$NPM_CONTAINER_NAME' laeuft nicht."
log "Starten: $SELF up"; return 1; }
return 0
}
# --- Zertifikat anlegen --------------------------------------------------
# gibt die Zertifikats-ID auf stdout aus
npm_cert_selfsigned() { # domain
local domain="$1"
local dir="$PROJECT_DIR/data/npm/custom-certs/$domain"
if [ ! -f "$dir/fullchain.pem" ] || [ ! -f "$dir/privkey.pem" ]; then
log "Erzeuge selbstsigniertes Zertifikat fuer '$domain' ..." >&2
cmd_cert --domain "$domain" >/dev/null || return 1
else
log "Verwende vorhandenes Zertifikat unter $dir" >&2
fi
# Bereits vorhandenen Eintrag gleichen Namens wiederverwenden, sonst
# sammeln sich bei jedem Aufruf neue Zertifikate an.
local id="" body list cid o
list="$(npm_api GET /api/nginx/certificates)"
for cid in $(json_ids "$list"); do
o="$(npm_api GET "/api/nginx/certificates/$cid")"
if [ "$(json_str "$o" provider)" = other ] && [ "$(json_str "$o" nice_name)" = "$domain" ]; then
id="$cid"; log "Verwende vorhandenen Zertifikatseintrag $id wieder." >&2; break
fi
done
if [ -z "$id" ]; then
body="$(npm_api POST /api/nginx/certificates \
"{\"provider\":\"other\",\"nice_name\":\"$domain\",\"domain_names\":[\"$domain\"]}")"
id="$(json_num "$body" id)"
[ -n "$id" ] || { err "Zertifikatseintrag konnte nicht angelegt werden (HTTP $NPM_CODE)."
printf ' %s\n' "$body" >&2; return 1; }
fi
log "Lade Schluessel und Zertifikat hoch (ID $id) ..." >&2
local up
up="$(curl -sS --max-time 60 -X POST "$(npm_api_base)/api/nginx/certificates/$id/upload" \
-H "Authorization: Bearer $NPM_TOKEN" \
-F "certificate=@$dir/fullchain.pem" \
-F "certificate_key=@$dir/privkey.pem" 2>/dev/null)" || true
case "$up" in
*'"error"'*|'') err "Hochladen fehlgeschlagen."; printf ' %s\n' "$up" >&2; return 1 ;;
esac
printf '%s' "$id"
}
npm_cert_letsencrypt() { # domain
local domain="$1" body
log "Fordere Let's-Encrypt-Zertifikat fuer '$domain' an - das dauert ..." >&2
body="$(npm_api POST /api/nginx/certificates \
"{\"provider\":\"letsencrypt\",\"domain_names\":[\"$domain\"],\"meta\":{}}")"
local id; id="$(json_num "$body" id)"
if [ -z "$id" ]; then
err "Let's Encrypt hat kein Zertifikat ausgestellt (HTTP $NPM_CODE)."
local m; m="$(json_str "$body" message)"
[ -n "$m" ] && printf ' Antwort: %s\n' "$m" >&2
cat >&2 <<EOF
Haeufige Gruende:
* Port 80 ist aus dem Internet nicht erreichbar (HTTP-01-Pruefung)
* der DNS-Name zeigt nicht auf diesen Host
* das Konto hat keine E-Mail-Adresse - Let's Encrypt nimmt in
Version 2.15 die Adresse des angemeldeten Kontos
EOF
return 1
fi
printf '%s' "$id"
}
# --- Proxy-Hosts ---------------------------------------------------------
cmd_proxy() {
local sub="${1:-list}"; [ $# -gt 0 ] && shift || true
case "$sub" in
login|status)
npm_require_running || return 1
NPM_TOKEN="$(npm_api_token)" || return 1
ok "Anmeldung am Proxy Manager erfolgreich ($NPM_ADMIN_EMAIL)."
local body; body="$(npm_api GET /api/nginx/proxy-hosts)"
printf ' Proxy-Hosts: %s\n' "$(printf '%s' "$body" | grep -c '"id"' || true)"
body="$(npm_api GET /api/nginx/certificates)"
printf ' Zertifikate: %s\n' "$(printf '%s' "$body" | grep -c '"id"' || true)"
return 0 ;;
list)
npm_require_running || return 1
NPM_TOKEN="$(npm_api_token)" || return 1
local body; body="$(npm_api GET /api/nginx/proxy-hosts)"
printf '%-5s %-34s %-26s %s\n' "ID" "DOMAINS" "ZIEL" "SSL"
local id o dom fh fp cid n=0
for id in $(json_ids "$body"); do
# Einzeln abfragen: in der Listenantwort laesst sich ein Objekt
# nicht zuverlaessig abgrenzen, weil "meta":{...} ebenfalls
# geschweifte Klammern enthaelt.
o="$(npm_api GET "/api/nginx/proxy-hosts/$id")"
dom="$(printf '%s' "$o" | sed -n 's/.*"domain_names"[[:space:]]*:[[:space:]]*\[\([^]]*\)\].*/\1/p' | tr -d '"' || true)"
fh="$(json_str "$o" forward_host)"; fp="$(json_num "$o" forward_port)"
cid="$(json_num "$o" certificate_id)"
printf '%-5s %-34s %-26s %s\n' "$id" "${dom:-?}" \
"$(json_str "$o" forward_scheme)://$fh:$fp" \
"$([ "${cid:-0}" -gt 0 ] 2>/dev/null && echo "ja (Zert. $cid)" || echo nein)"
n=$((n+1))
done
[ "$n" -eq 0 ] && echo "(noch kein Proxy-Host angelegt)"
return 0 ;;
certs)
npm_require_running || return 1
NPM_TOKEN="$(npm_api_token)" || return 1
local body; body="$(npm_api GET /api/nginx/certificates)"
printf '%-5s %-12s %-28s %s\n' "ID" "ANBIETER" "NAME" "LAEUFT AB"
local id o n=0
for id in $(json_ids "$body"); do
o="$(npm_api GET "/api/nginx/certificates/$id")"
printf '%-5s %-12s %-28s %s\n' "$id" "$(json_str "$o" provider)" \
"$(json_str "$o" nice_name)" "$(json_str "$o" expires_on | awk '{print $1}')"
n=$((n+1))
done
[ "$n" -eq 0 ] && echo "(noch kein Zertifikat vorhanden)"
return 0 ;;
del|delete|rm)
local pid=""
while [ $# -gt 0 ]; do
case "$1" in --id) pid="$2"; shift 2 ;; *) pid="$1"; shift ;; esac
done
[ -n "$pid" ] || die "ID fehlt: $SELF proxy del --id N (IDs zeigt '$SELF proxy list')"
npm_require_running || return 1
NPM_TOKEN="$(npm_api_token)" || return 1
confirm "Proxy-Host mit der ID $pid wirklich loeschen?" || die "Abgebrochen."
npm_api DELETE "/api/nginx/proxy-hosts/$pid" >/dev/null
case "$NPM_CODE" in 200|201|204) ok "Proxy-Host $pid geloescht." ;;
*) die "Loeschen fehlgeschlagen (HTTP $NPM_CODE)." ;; esac
return 0 ;;
add)
local domain="${PROXY_DOMAIN:-}" fhost="${PROXY_FORWARD_HOST:-127.0.0.1}"
local fport="${PROXY_FORWARD_PORT:-5000}" scheme=http cert=self
local force_ssl=true http2=true ws=true block=true update="" adv=""
local adv_set=""
while [ $# -gt 0 ]; do
case "$1" in
--domain) domain="$2"; shift 2 ;;
--forward-host) fhost="$2"; shift 2 ;;
--forward-port) fport="$2"; shift 2 ;;
--scheme) scheme="$2"; shift 2 ;;
--cert) cert="$2"; shift 2 ;;
--advanced) adv="$2"; adv_set=1; shift 2 ;;
--update) update=1; shift ;;
--no-force-ssl) force_ssl=false; shift ;;
--no-http2) http2=false; shift ;;
--no-websockets) ws=false; shift ;;
--no-block-exploits) block=false; shift ;;
*) die "Unbekannte Option fuer 'proxy add': $1" ;;
esac
done
[ -n "$domain" ] || die "--domain fehlt (oder PROXY_DOMAIN in der .env setzen)."
case "$scheme" in http|https) : ;; *) die "--scheme: http oder https" ;; esac
case "$cert" in none|self|letsencrypt) : ;; *) die "--cert: none | self | letsencrypt" ;; esac
valid_port "$fport" || die "--forward-port: keine gueltige Portnummer."
[ -n "$adv_set" ] || adv='client_max_body_size 0;\nproxy_read_timeout 300s;\nproxy_set_header X-Forwarded-Proto $scheme;\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;'
npm_require_running || return 1
NPM_TOKEN="$(npm_api_token)" || return 1
# schon vorhanden?
local existing
# Achtung: grep liefert 1, wenn nichts passt - unter "set -e" wuerde
# das die Zuweisung und damit das ganze Skript beenden.
existing="$(npm_api GET /api/nginx/proxy-hosts | tr '{' '\n' \
| grep -F "\"$domain\"" | head -n1 || true)"
local exid=""; [ -n "$existing" ] && exid="$(json_num "$existing" id)"
if [ -n "$exid" ] && [ -z "$update" ]; then
die "Fuer '$domain' gibt es bereits den Proxy-Host $exid.
Ersetzen mit --update, oder vorher loeschen: $SELF proxy del --id $exid"
fi
local certid=0
case "$cert" in
self) certid="$(npm_cert_selfsigned "$domain")" || return 1 ;;
letsencrypt) certid="$(npm_cert_letsencrypt "$domain")" || return 1 ;;
none) certid=0; force_ssl=false; http2=false ;;
esac
local payload
payload="{\"domain_names\":[\"$domain\"],\"forward_scheme\":\"$scheme\",\"forward_host\":\"$fhost\",\"forward_port\":$fport,\"certificate_id\":$certid,\"ssl_forced\":$force_ssl,\"http2_support\":$http2,\"block_exploits\":$block,\"allow_websocket_upgrade\":$ws,\"caching_enabled\":false,\"advanced_config\":\"$adv\",\"enabled\":true,\"meta\":{}}"
local body
if [ -n "$exid" ]; then
log "Aktualisiere vorhandenen Proxy-Host $exid ..."
body="$(npm_api PUT "/api/nginx/proxy-hosts/$exid" "$payload")"
else
log "Lege Proxy-Host fuer '$domain' an ..."
body="$(npm_api POST /api/nginx/proxy-hosts "$payload")"
fi
local newid; newid="$(json_num "$body" id)"
if [ -z "$newid" ]; then
err "Der Proxy-Host konnte nicht angelegt werden (HTTP $NPM_CODE)."
local m; m="$(json_str "$body" message)"
[ -n "$m" ] && printf ' Antwort: %s\n' "$m" >&2
return 1
fi
ok "Proxy-Host $newid angelegt: $domain -> $scheme://$fhost:$fport"
cat <<EOF
${C_BLD}Erreichbar${C_RST}
https://$domain/${CMK_SITE_ID:-cmk}/ (HTTPS auf Port 443)
http://$domain/ -> $([ "$force_ssl" = true ] && echo 'Weiterleitung auf HTTPS' || echo 'unverschluesselt')
$([ "$cert" = self ] && printf '%s\n' "Das Zertifikat ist selbstsigniert. Damit Browser und Agents ihm
trauen, data/npm/custom-certs/$domain/fullchain.pem auf den Clients
als vertrauenswuerdig einrichten.")
EOF
return 0 ;;
*) die "Unbekanntes Unterkommando 'proxy $sub'.
Moeglich: status | list | certs | add | del" ;;
esac
}
# =====================================================================
# Selbstsigniertes Zertifikat fuer den NGINX Proxy Manager
# =====================================================================
@@ -3939,7 +4253,8 @@ gui_settings_category() {
case "$cat" in
image) items+=("__wizard__" ">> Image beschaffen (Edition, Version, Bezugsweg)")
items+=("__test__" ">> Zugangsdaten jetzt pruefen (Registry + Downloadportal)") ;;
npm) items+=("__npm__" ">> Proxy Manager: Stand und Admin-Port anzeigen") ;;
npm) items+=("__proxy__" ">> Proxy-Hosts anlegen/verwalten")
items+=("__npm__" ">> Proxy Manager: Stand und Admin-Port anzeigen") ;;
backup) items+=("__jobs__" ">> Backup-Jobs verwalten") ;;
esac
items+=("back" "zurueck")
@@ -3948,6 +4263,7 @@ gui_settings_category() {
case "$sel" in
back) return 0 ;;
__wizard__) gui_image_wizard || true; continue ;;
__proxy__) gui_proxy_menu || true; continue ;;
__test__) gui_image_test || true; continue ;;
__jobs__) gui_jobs_menu || true; continue ;;
__npm__) local f; f="$(mktemp)"
@@ -4032,6 +4348,115 @@ Trotzdem starten?
done
}
# ---------------------------------------------------------------------
# Proxy-Hosts im Menue
# ---------------------------------------------------------------------
gui_proxy_menu() {
while :; do
local sel
sel="$(ui_menu "Proxy-Hosts" \
"NGINX Proxy Manager ueber seine Schnittstelle bedienen -
das ist verlaesslicher als der Terminal-Browser.
Konto: ${NPM_ADMIN_EMAIL:-<nicht gesetzt>}
Ziel : ${PROXY_FORWARD_HOST:-127.0.0.1}:${PROXY_FORWARD_PORT:-5000}" \
anlegen "Proxy-Host anlegen (Assistent)" \
list "Vorhandene Proxy-Hosts anzeigen" \
certs "Vorhandene Zertifikate anzeigen" \
del "Proxy-Host loeschen" \
status "Anmeldung pruefen" \
back "zurueck")" || return 0
case "$sel" in
anlegen) gui_proxy_add || true ;;
list) local f; f="$(mktemp)"; NO_COLOR=1 cmd_proxy list >"$f" 2>&1 || true
ui_text "Proxy-Hosts" "$f"; rm -f "$f" ;;
certs) local f2; f2="$(mktemp)"; NO_COLOR=1 cmd_proxy certs >"$f2" 2>&1 || true
ui_text "Zertifikate" "$f2"; rm -f "$f2" ;;
del) gui_proxy_del || true ;;
status) ui_run "Anmeldung pruefen" bash -c "cd '$PROJECT_DIR' && NO_COLOR=1 '$SELF' proxy status" ;;
back) return 0 ;;
esac
done
}
gui_proxy_add() {
if ! npm_require_running 2>/dev/null; then
ui_msg "Proxy Manager laeuft nicht" \
"Der NGINX Proxy Manager muss laufen, damit sich ein Proxy-Host
anlegen laesst.
Abgeschaltet? Einstellungen -> NGINX Proxy Manager
Nicht gestartet? Stack steuern -> Stack starten"
return 0
fi
if [ -z "${NPM_ADMIN_EMAIL:-}" ] || [ -z "${NPM_ADMIN_PASSWORD:-}" ]; then
ui_msg "Zugangsdaten fehlen" \
"Fuer die Schnittstelle werden die Zugangsdaten des Proxy Managers
gebraucht: NPM_ADMIN_EMAIL und NPM_ADMIN_PASSWORD.
Sie stehen unter Einstellungen -> NGINX Proxy Manager.
Hinweis: Seit Version 2.15 legt der Container das Konto nur noch
beim ERSTEN Start an, und nur wenn beide Werte gesetzt sind.
Wurde das Konto im Browser angelegt, hier dessen Daten eintragen."
return 0
fi
local dom fport cert
dom="$(ui_input "Proxy-Host (1/3)" \
"Unter welchem Namen soll Checkmk erreichbar sein?
Der Name muss auf diesen Host zeigen - per DNS oder
per hosts-Datei der Arbeitsplatzrechner." "${PROXY_DOMAIN:-}")" || return 0
[ -n "$dom" ] || return 0
fport="$(ui_input "Proxy-Host (2/3)" \
"Auf welchen Port soll weitergeleitet werden?
5000 = Checkmk-Oberflaeche (Vorgabe)
81 = Oberflaeche des Proxy Managers selbst" "${PROXY_FORWARD_PORT:-5000}")" || return 0
valid_port "$fport" || { ui_msg "Ungueltig" "'$fport' ist keine gueltige Portnummer."; return 0; }
cert="$(ui_menu "Proxy-Host (3/3) - Zertifikat" \
"$dom -> 127.0.0.1:$fport
Womit soll HTTPS abgesichert werden?" \
self "Selbstsigniert (intern, sofort einsatzbereit)" \
letsencrypt "Let's Encrypt (Port 80 muss aus dem Internet erreichbar sein)" \
none "Ohne HTTPS (nur Port 80)")" || return 0
local upd=""
ui_yesno "Anlegen" \
"$dom -> 127.0.0.1:$fport
Zertifikat: $cert
Einen bereits vorhandenen Eintrag fuer diesen Namen ersetzen?
<Ja> ersetzt ihn
<Nein> bricht ab, falls es ihn schon gibt" && upd=--update
ui_run "Proxy-Host anlegen" bash -c \
"cd '$PROJECT_DIR' && NO_COLOR=1 '$SELF' -y proxy add --domain '$dom' \
--forward-port '$fport' --cert '$cert' $upd"
# Die Vorgaben merken, damit der naechste Aufruf sie kennt
env_set PROXY_DOMAIN "$dom" 1 2>/dev/null || true
env_set PROXY_FORWARD_PORT "$fport" 2>/dev/null || true
load_env "${ENV_FILE:-$PROJECT_DIR/.env}"
}
gui_proxy_del() {
local f; f="$(mktemp)"
NO_COLOR=1 cmd_proxy list >"$f" 2>&1 || true
ui_text "Vorhandene Proxy-Hosts" "$f"; rm -f "$f"
local id
id="$(ui_input "Loeschen" "ID des zu loeschenden Proxy-Hosts:" "")" || return 0
[ -n "$id" ] || return 0
case "$id" in ''|*[!0-9]*) ui_msg "Ungueltig" "Bitte eine Zahl angeben."; return 0 ;; esac
ui_yesno "Loeschen" "Proxy-Host $id wirklich loeschen?" || return 0
ui_run "Proxy-Host loeschen" bash -c "cd '$PROJECT_DIR' && '$SELF' -y proxy del --id '$id'"
}
gui_cert() {
local domain alt days
domain="$(ui_input "Zertifikat" "FQDN / Common Name:" "${CERT_DOMAIN:-checkmk.example.local}")" || return 0
@@ -4059,6 +4484,7 @@ Backups : $BACKUP_DIR" \
manage "Backups verwalten (Liste/Details/Loeschen)" \
sites "Sites im Container verwalten" \
image "Checkmk-Image beschaffen/auswaehlen" \
proxy "Proxy-Hosts anlegen/verwalten (HTTPS fuer Checkmk)" \
browser "Terminal-Browser (Proxy Manager lokal bedienen)" \
cert "Selbstsigniertes Zertifikat erzeugen" \
config "Einstellungen (.env) - menuegefuehrt" \
@@ -4073,6 +4499,7 @@ Backups : $BACKUP_DIR" \
manage) gui_backups_menu || true ;;
sites) gui_sites_menu || true ;;
image) gui_image_menu || true ;;
proxy) gui_proxy_menu || true ;;
browser) gui_browser_menu || true ;;
cert) gui_cert || true ;;
config) gui_settings_menu || true ;;
@@ -4131,6 +4558,7 @@ main() {
browser) cmd_browser "$@" || true ;;
npm-port) cmd_npm_port "$@" ;;
npm-enable) cmd_npm_enable "$@" ;;
proxy) cmd_proxy "$@" ;;
config) cmd_config "$@" || true ;;
help|-h|--help) usage ;;
*) err "Unbekanntes Kommando: $cmd"; echo; usage; exit 1 ;;