From e7eb1c3be9c1e29ca80c10c697b13f2b87179d12 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 20 Sep 2026 17:56:04 +0200 Subject: [PATCH] Mehrere Dienste hinter einem Port: Pfade statt Domainnamen Hintergrund aus der Praxis: nach aussen ist nur ein Port frei, auf dem Server laufen aber Checkmk und Grafana und noch ein Dienst. Die Frage war, ob sich statt eines Domainnamens auch /irgendeinname nutzen laesst. Ja - der Proxy Manager kennt dafuer "Custom locations", und die API nimmt sie als locations-Array entgegen. Geprueft am Schema von v2.15.1 (components/proxy-host-object.json) und an der Vorlage _location.conf, aus der nginx den location-Block erzeugt. proxy add --domain 10.0.0.5 --forward-port 5000 --cert self \ --location /grafana=127.0.0.1:3000 \ --location /sonstwas=127.0.0.1:8080 --location ist mehrfach angebbar, versteht /pfad=host:port, wahlweise mit Schema (https://) und mit einem Pfad, der beim Ziel vorangestellt wird (/alt=host:3000/basis). Ungueltige Angaben werden abgewiesen. Ebenfalls geprueft: als --domain ist eine IP-Adresse zulaessig, ein DNS-Name ist nicht noetig (das Muster im Schema laesst alles ausser einer Handvoll Sonderzeichen zu). Neu dazu "proxy show --domain X | --id N", das den Eintrag samt allen Pfaden auflistet - noetig, weil --update den Eintrag vollstaendig ersetzt und man die bestehenden Pfade wieder mitgeben muss. Im Assistenten fragt die Oberflaeche nach dem Zertifikat, ob weitere Dienste unter demselben Namen liegen sollen, und nimmt dann Pfad und Ziel im Wechsel auf, bis ein Feld leer bleibt. Dokumentiert als Abschnitt 10.3 in beiden Sprachfassungen, mit dem Fallstrick, der sonst Stunden kostet: ein Dienst hinter einem Unterpfad muss seinen Basispfad kennen. Fuer Grafana sind das root_url und serve_from_sub_path; ohne die bleibt die Seite weiss, weil das JavaScript unter /public statt /grafana/public gesucht wird. Checkmk ist nicht betroffen, es liegt ohnehin unter //. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 106 ++++++++++++++++++++++++++++++-- README_en.md | 104 ++++++++++++++++++++++++++++++-- scripts/cmk-manage.sh | 136 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 329 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 957446c..f0d9182 100644 --- a/README.md +++ b/README.md @@ -1104,6 +1104,7 @@ erzwingen, HTTP/2 und Websockets einschalten und den empfohlenen | `proxy list` | vorhandene Proxy-Hosts | | `proxy certs` | vorhandene Zertifikate mit Ablaufdatum | | `proxy add …` | Proxy-Host anlegen (`--update` ersetzt einen vorhandenen) | +| `proxy show --domain X` | Einzelheiten samt zusätzlicher Pfade | | `proxy del --id N` | Proxy-Host löschen | Optionen von `proxy add`: @@ -1117,6 +1118,7 @@ Optionen von `proxy add`: | `--cert self\|letsencrypt\|none` | `self` | Zertifikat | | `--update` | – | vorhandenen Eintrag ersetzen | | `--advanced TEXT` | siehe unten | eigener nginx-Abschnitt | +| `--location /P=HOST:PORT` | – | weiterer Dienst unter einem Pfad, mehrfach angebbar – siehe [10.3](#103-mehrere-dienste-hinter-einem-port-pfade-statt-namen) | | `--no-force-ssl`, `--no-http2`, `--no-websockets`, `--no-block-exploits` | – | Abschalter | #### Der `advanced_config`-Abschnitt @@ -1160,7 +1162,101 @@ Manager → „>> Proxy-Hosts anlegen/verwalten"**. > **wiederverwendet** statt jedes Mal neu angelegt – sonst sammeln sich im > Proxy Manager Dutzende Einträge gleichen Namens an. -### 10.3 Wenn doch die Weboberfläche +### 10.3 Mehrere Dienste hinter einem Port (Pfade statt Namen) + +Der typische Fall: von außen ist **nur ein Port** erreichbar, auf dem Server +laufen aber mehrere Oberflächen – Checkmk, Grafana, vielleicht noch etwas. Statt +für jeden Dienst einen eigenen Namen zu brauchen, lassen sie sich über den +**Pfad** unterscheiden: + +``` +https://10.0.0.5/cmk/ -> Checkmk (127.0.0.1:5000) +https://10.0.0.5/grafana -> Grafana (127.0.0.1:3000) +https://10.0.0.5/sonstwas -> ein weiterer Dienst +``` + +Genau dafür ist der Proxy Manager da. In einem Aufruf: + +```bash +sudo ./scripts/cmk-manage.sh proxy add \ + --domain 10.0.0.5 \ + --forward-port 5000 \ + --cert self \ + --location /grafana=127.0.0.1:3000 \ + --location /sonstwas=127.0.0.1:8080 +``` + +* `--domain` darf eine **IP-Adresse** sein – ein DNS-Name ist nicht nötig. + (Die Schnittstelle akzeptiert alles außer einer Handvoll Sonderzeichen.) +* `--forward-port` ist das Ziel für alles, was **nicht** von einem Pfad + abgedeckt ist – hier Checkmk. +* `--location` ist beliebig oft angebbar. Schreibweise + `/pfad=host:port`, wahlweise mit Schema (`https://host:port`) und mit einem + Pfad, der beim Ziel vorangestellt wird (`/alt=host:3000/basis`). + +Anzeigen lässt sich das Ergebnis mit: + +```bash +./scripts/cmk-manage.sh proxy show --domain 10.0.0.5 +``` + +In der Oberfläche fragt der Assistent nach dem Zertifikat, ob weitere Dienste +unter demselben Namen liegen sollen, und nimmt dann Pfad und Ziel im Wechsel +auf, bis man ein Feld leer lässt. + +> **Die Pfadliste ist vollständig zu verstehen.** `proxy add --update` +> ersetzt den Eintrag mitsamt allen Pfaden. Wer später einen Pfad ergänzt, gibt +> die bereits vorhandenen also wieder mit an – `proxy show` zeigt, welche das +> sind. + +#### Was die Dienste selbst wissen müssen + +Ein Dienst hinter einem Unterpfad erzeugt sonst Verweise auf `/`, die ins Leere +gehen. **Checkmk** ist davon nicht betroffen – es liegt ohnehin unter +`//`. Andere brauchen eine Einstellung: + +**Grafana** (`/etc/grafana/grafana.ini` bzw. `GF_*`-Umgebungsvariablen): + +```ini +[server] +domain = 10.0.0.5 +root_url = %(protocol)s://%(domain)s/grafana/ +serve_from_sub_path = true +``` + +Als Container: + +```yaml +environment: + GF_SERVER_ROOT_URL: https://10.0.0.5/grafana/ + GF_SERVER_SERVE_FROM_SUB_PATH: "true" +``` + +Bleibt das aus, lädt Grafana zwar, sucht sein JavaScript aber unter +`https://10.0.0.5/public/...` statt `/grafana/public/...` – die Seite bleibt +weiß. Dasselbe gilt sinngemäß für jeden anderen Dienst: er muss seinen +Basispfad kennen. + +#### Warum überhaupt der Proxy Manager + +Alle Container laufen im Host-Netzwerk, die Dienste hören also direkt auf ihren +Ports (Checkmk 5000, Grafana 3000, …). Nach außen geben Sie davon **keinen** +frei – nur 443. Der Proxy Manager verteilt dahinter nach Pfad und erledigt +zugleich die HTTPS-Terminierung mit einem Zertifikat für alle Dienste. + +``` + Internet / LAN + | + :443 (einziger offener Port) + | + NGINX Proxy Manager + | | | + /cmk/ /grafana /sonstwas + | | | + :5000 :3000 :8080 (nur auf localhost) +``` + +### 10.4 Wenn doch die Weboberfläche 1. `http://:81` aufrufen – bzw. den in `NPM_ADMIN_PORT` gesetzten Port (siehe [Kapitel 12](#12-adminoberfläche-auf-einen-anderen-port-legen)); @@ -1168,7 +1264,7 @@ Manager → „>> Proxy-Hosts anlegen/verwalten"**. [Kapitel 11](#11-proxy-manager-lokal-einrichten-terminal-browser) 2. Anmelden mit `NPM_ADMIN_EMAIL` / `NPM_ADMIN_PASSWORD` -### 10.4 Proxy-Host im Browser anlegen +### 10.5 Proxy-Host im Browser anlegen **Hosts → Proxy Hosts → Add Proxy Host** @@ -1191,7 +1287,7 @@ proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ``` -### 10.5 Variante A – Let's Encrypt (öffentlich erreichbarer Server) +### 10.6 Variante A – Let's Encrypt (öffentlich erreichbarer Server) Voraussetzungen: der DNS-Name zeigt öffentlich auf diesen Server und **Port 80 ist aus dem Internet erreichbar** (HTTP-01-Challenge). @@ -1211,7 +1307,7 @@ gesichert. Bei interner DNS-Zone ohne öffentlichen Zugang: **DNS-Challenge** verwenden (SSL → *Use a DNS Challenge* → Provider auswählen, API-Token hinterlegen). -### 10.6 Variante B – Selbstsigniertes Zertifikat (interne Umgebung) +### 10.7 Variante B – Selbstsigniertes Zertifikat (interne Umgebung) Erzeugen: @@ -1361,7 +1457,7 @@ ausgefüllt), aber das Hochladen eines **selbstsignierten Zertifikats** (*SSL Certificates → Custom*) funktioniert so nicht zuverlässig. Für genau diesen Fall führt der Weg über die REST-Schnittstelle des Proxy -Managers. Zertifikat wie in [Kapitel 10.6](#106-variante-b--selbstsigniertes-zertifikat-interne-umgebung) +Managers. Zertifikat wie in [Kapitel 10.7](#107-variante-b--selbstsigniertes-zertifikat-interne-umgebung) erzeugen, dann: ```bash diff --git a/README_en.md b/README_en.md index 9ecca35..73b189e 100644 --- a/README_en.md +++ b/README_en.md @@ -1106,6 +1106,7 @@ HTTPS, enables HTTP/2 and websockets, and sets the recommended | `proxy list` | existing proxy hosts | | `proxy certs` | existing certificates with expiry date | | `proxy add …` | create a proxy host (`--update` replaces an existing one) | +| `proxy show --domain X` | details including additional paths | | `proxy del --id N` | delete a proxy host | Options for `proxy add`: @@ -1119,6 +1120,7 @@ Options for `proxy add`: | `--cert self\|letsencrypt\|none` | `self` | certificate | | `--update` | – | replace an existing entry | | `--advanced TEXT` | see below | custom nginx block | +| `--location /P=HOST:PORT` | – | another service under a path, repeatable – see [10.3](#103-several-services-behind-one-port-paths-instead-of-names) | | `--no-force-ssl`, `--no-http2`, `--no-websockets`, `--no-block-exploits` | – | switches | #### The `advanced_config` block @@ -1162,7 +1164,99 @@ Manager → ">> Proxy-Hosts anlegen/verwalten"**. > created anew each time – otherwise dozens of entries with the same name pile > up in the Proxy Manager. -### 10.3 If you do want the web interface +### 10.3 Several services behind one port (paths instead of names) + +The typical situation: only **one port** is reachable from outside, but the +server runs several interfaces – Checkmk, Grafana, maybe something else. +Instead of needing a separate name per service, they can be told apart by +**path**: + +``` +https://10.0.0.5/cmk/ -> Checkmk (127.0.0.1:5000) +https://10.0.0.5/grafana -> Grafana (127.0.0.1:3000) +https://10.0.0.5/other -> another service +``` + +This is exactly what the Proxy Manager is for. In one call: + +```bash +sudo ./scripts/cmk-manage.sh proxy add \ + --domain 10.0.0.5 \ + --forward-port 5000 \ + --cert self \ + --location /grafana=127.0.0.1:3000 \ + --location /other=127.0.0.1:8080 +``` + +* `--domain` may be an **IP address** – a DNS name is not required. (The + interface accepts anything except a handful of special characters.) +* `--forward-port` is the target for everything **not** covered by a path – + Checkmk here. +* `--location` can be given any number of times. Syntax `/path=host:port`, + optionally with a scheme (`https://host:port`) and with a path prefixed at + the target (`/alt=host:3000/base`). + +Inspect the result with: + +```bash +./scripts/cmk-manage.sh proxy show --domain 10.0.0.5 +``` + +In the interface the wizard asks about the certificate, whether further +services should live under the same name, and then takes path and target in +turn until you leave a field empty. + +> **The path list is absolute.** `proxy add --update` replaces the entry +> including all paths. So when adding a path later, pass the existing ones +> again – `proxy show` tells you which those are. + +#### What the services themselves need to know + +A service behind a sub-path otherwise generates links to `/` that lead nowhere. +**Checkmk** is unaffected – it lives under `//` anyway. Others need a +setting: + +**Grafana** (`/etc/grafana/grafana.ini` or `GF_*` environment variables): + +```ini +[server] +domain = 10.0.0.5 +root_url = %(protocol)s://%(domain)s/grafana/ +serve_from_sub_path = true +``` + +As a container: + +```yaml +environment: + GF_SERVER_ROOT_URL: https://10.0.0.5/grafana/ + GF_SERVER_SERVE_FROM_SUB_PATH: "true" +``` + +Without it Grafana loads but looks for its JavaScript under +`https://10.0.0.5/public/...` instead of `/grafana/public/...` – the page stays +blank. The same applies to any other service: it has to know its base path. + +#### Why the Proxy Manager at all + +All containers run on the host network, so the services listen directly on +their ports (Checkmk 5000, Grafana 3000, …). You expose **none** of them – +only 443. Behind it the Proxy Manager distributes by path and handles HTTPS +termination with one certificate for all services. + +``` + Internet / LAN + | + :443 (the only open port) + | + NGINX Proxy Manager + | | | + /cmk/ /grafana /other + | | | + :5000 :3000 :8080 (localhost only) +``` + +### 10.4 If you do want the web interface 1. open `http://:81` – or whichever port is set in `NPM_ADMIN_PORT` (see [chapter 12](#12-moving-the-admin-interface-to-a-different-port)); if @@ -1170,7 +1264,7 @@ Manager → ">> Proxy-Hosts anlegen/verwalten"**. [chapter 11](#11-configuring-the-proxy-manager-locally-terminal-browser) 2. log in with `NPM_ADMIN_EMAIL` / `NPM_ADMIN_PASSWORD` -### 10.4 Creating a proxy host in the browser +### 10.5 Creating a proxy host in the browser **Hosts → Proxy Hosts → Add Proxy Host** @@ -1193,7 +1287,7 @@ proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ``` -### 10.5 Option A – Let's Encrypt (publicly reachable server) +### 10.6 Option A – Let's Encrypt (publicly reachable server) Prerequisites: the DNS name resolves publicly to this server and **port 80 is reachable from the internet** (HTTP-01 challenge). @@ -1213,7 +1307,7 @@ project directory. For an internal DNS zone without public access, use the **DNS challenge** (SSL → *Use a DNS Challenge* → select provider, store the API token). -### 10.6 Option B – self-signed certificate (internal environment) +### 10.7 Option B – self-signed certificate (internal environment) Creating one: @@ -1366,7 +1460,7 @@ work reliably this way. For exactly this case, use the Proxy Manager's REST interface. Create the certificate as described in -[chapter 10.6](#106-option-b--self-signed-certificate-internal-environment), then: +[chapter 10.7](#107-option-b--self-signed-certificate-internal-environment), then: ```bash NPM=http://127.0.0.1:81 diff --git a/scripts/cmk-manage.sh b/scripts/cmk-manage.sh index ac939c9..6fd2a99 100755 --- a/scripts/cmk-manage.sh +++ b/scripts/cmk-manage.sh @@ -180,7 +180,12 @@ KOMMANDOS - Proxy-Hosts (ueber die API des Proxy Managers) --cert self|letsencrypt|none (Vorgabe self) --update vorhandenen Host ersetzen --advanced TEXT eigener nginx-Abschnitt + --location /P=HOST:PORT weiterer Pfad auf demselben Namen, + mehrfach angebbar. Damit lassen sich mehrere + Dienste hinter EINEM Port unterscheiden: + --location /grafana=127.0.0.1:3000 --no-force-ssl --no-http2 --no-websockets --no-block-exploits + proxy show --domain X | --id N Einzelheiten samt Pfaden anzeigen proxy del --id N Proxy-Host loeschen KOMMANDOS - Zertifikat @@ -3182,6 +3187,36 @@ EOF printf '%s' "$id" } +# Einen --location-Eintrag in ein JSON-Objekt umsetzen. +# /grafana=127.0.0.1:3000 +# /grafana=http://127.0.0.1:3000 +# /alt=127.0.0.1:3000/basis (Pfad, der beim Ziel vorangestellt wird) +proxy_location_json() { # spec -> JSON-Objekt auf stdout + local spec="$1" path target scheme=http host port fwd="" + case "$spec" in + *=*) path="${spec%%=*}"; target="${spec#*=}" ;; + *) err "Ungueltige Angabe: '$spec'" + printf ' Erwartet: /pfad=host:port z.B. /grafana=127.0.0.1:3000\n' >&2 + return 1 ;; + esac + case "$path" in /*) : ;; *) path="/$path" ;; esac + case "$target" in + http://*) scheme=http; target="${target#http://}" ;; + https://*) scheme=https; target="${target#https://}" ;; + esac + host="${target%%:*}" + local rest="${target#*:}" + if [ "$rest" = "$target" ]; then + err "Im Ziel '$target' fehlt der Port (erwartet host:port)."; return 1 + fi + port="${rest%%/*}" + case "$rest" in */*) fwd="/${rest#*/}" ;; esac + valid_port "$port" || { err "'$port' ist keine gueltige Portnummer."; return 1; } + [ -n "$host" ] || { err "Im Ziel '$target' fehlt der Host."; return 1; } + printf '{"path":"%s","forward_scheme":"%s","forward_host":"%s","forward_port":%s,"forward_path":"%s","advanced_config":""}' \ + "$path" "$scheme" "$host" "$port" "$fwd" +} + # --- Proxy-Hosts --------------------------------------------------------- cmd_proxy() { local sub="${1:-list}"; [ $# -gt 0 ] && shift || true @@ -3234,6 +3269,39 @@ cmd_proxy() { [ "$n" -eq 0 ] && echo "(noch kein Zertifikat vorhanden)" return 0 ;; + show) + local pid="" dom="" + while [ $# -gt 0 ]; do + case "$1" in --id) pid="$2"; shift 2 ;; --domain) dom="$2"; shift 2 ;; *) pid="$1"; shift ;; esac + done + npm_require_running || return 1 + NPM_TOKEN="$(npm_api_token)" || return 1 + if [ -z "$pid" ]; then + [ -n "$dom" ] || die "--id oder --domain angeben." + local all; all="$(npm_api GET /api/nginx/proxy-hosts)" + local i + for i in $(json_ids "$all"); do + if npm_api GET "/api/nginx/proxy-hosts/$i" | grep -qF "\"$dom\""; then pid="$i"; break; fi + done + [ -n "$pid" ] || die "Kein Proxy-Host fuer '$dom' gefunden." + fi + local o; o="$(npm_api GET "/api/nginx/proxy-hosts/$pid")" + printf '\n%sProxy-Host %s%s\n' "$C_BLD" "$pid" "$C_RST" + printf ' Domains : %s\n' "$(printf '%s' "$o" | sed -n 's/.*"domain_names"[[:space:]]*:[[:space:]]*\[\([^]]*\)\].*/\1/p' | tr -d '"' || true)" + printf ' Ziel : %s://%s:%s\n' "$(json_str "$o" forward_scheme)" "$(json_str "$o" forward_host)" "$(json_num "$o" forward_port)" + printf ' Zertifikat : %s\n' "$(json_num "$o" certificate_id)" + printf '\n %sZusaetzliche Pfade%s\n' "$C_BLD" "$C_RST" + local n + n="$(printf '%s' "$o" | grep -o '"path":"[^"]*"' | wc -l || true)" + if [ "${n:-0}" -eq 0 ]; then + printf ' (keine - alles geht an das Ziel oben)\n' + else + printf '%s' "$o" | tr '}' '\n' \ + | sed -n 's/.*"path":"\([^"]*\)".*"forward_host":"\([^"]*\)","forward_port":\([0-9]*\).*/ \1 -> \2:\3/p' + fi + echo + return 0 ;; + del|delete|rm) local pid="" while [ $# -gt 0 ]; do @@ -3252,7 +3320,7 @@ cmd_proxy() { 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="" + local adv_set="" locs="" while [ $# -gt 0 ]; do case "$1" in --domain) domain="$2"; shift 2 ;; @@ -3261,6 +3329,10 @@ cmd_proxy() { --scheme) scheme="$2"; shift 2 ;; --cert) cert="$2"; shift 2 ;; --advanced) adv="$2"; adv_set=1; shift 2 ;; + --location) local lj + lj="$(proxy_location_json "$2")" || return 1 + if [ -n "$locs" ]; then locs="$locs,$lj"; else locs="$lj"; fi + shift 2 ;; --update) update=1; shift ;; --no-force-ssl) force_ssl=false; shift ;; --no-http2) http2=false; shift ;; @@ -3298,7 +3370,7 @@ cmd_proxy() { 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\":{}}" + 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\",\"locations\":[$locs],\"enabled\":true,\"meta\":{}}" local body if [ -n "$exid" ]; then @@ -3316,6 +3388,10 @@ cmd_proxy() { return 1 fi ok "Proxy-Host $newid angelegt: $domain -> $scheme://$fhost:$fport" + if [ -n "$locs" ]; then + printf ' Zusaetzliche Pfade:\n' + printf '%s' "$locs" | tr ',' '\n' | sed -n 's/.*"path":"\([^"]*\)".*"forward_host":"\([^"]*\)","forward_port":\([0-9]*\).*/ \1 -> \2:\3/p' + fi cat <} Ziel : ${PROXY_FORWARD_HOST:-127.0.0.1}:${PROXY_FORWARD_PORT:-5000}" \ anlegen "Proxy-Host anlegen (Assistent)" \ list "Vorhandene Proxy-Hosts anzeigen" \ + show "Einzelheiten eines Proxy-Hosts (mit Pfaden)" \ certs "Vorhandene Zertifikate anzeigen" \ del "Proxy-Host loeschen" \ status "Anmeldung pruefen" \ @@ -4371,6 +4448,11 @@ Ziel : ${PROXY_FORWARD_HOST:-127.0.0.1}:${PROXY_FORWARD_PORT:-5000}" \ 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" ;; + show) local d3; d3="$(ui_input "Einzelheiten" "Name oder ID des Proxy-Hosts:" "${PROXY_DOMAIN:-}")" || continue + [ -n "$d3" ] || continue + local f3; f3="$(mktemp)" + NO_COLOR=1 cmd_proxy show --domain "$d3" >"$f3" 2>&1 || true + ui_text "Proxy-Host $d3" "$f3"; rm -f "$f3" ;; 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 ;; @@ -4426,19 +4508,59 @@ Womit soll HTTPS abgesichert werden?" \ letsencrypt "Let's Encrypt (Port 80 muss aus dem Internet erreichbar sein)" \ none "Ohne HTTPS (nur Port 80)")" || return 0 + # --- weitere Dienste unter demselben Namen, nach Pfad getrennt ---- + local -a locopt=() + local loclist="" + if ui_yesno "Weitere Dienste?" \ +"Sollen unter demselben Namen noch andere Dienste erreichbar sein, +unterschieden nach dem Pfad? + + https://$dom/ -> Checkmk (das Ziel von eben) + https://$dom/grafana -> Grafana + https://$dom/sonstwas -> ein weiterer Dienst + +Das ist der Weg, wenn nur EIN Port nach aussen frei ist."; then + while :; do + local lpath ltarget + lpath="$(ui_input "Pfad" \ +"Unter welchem Pfad soll der Dienst liegen? + +Leer lassen beendet die Eingabe." "")" || break + [ -n "$lpath" ] || break + ltarget="$(ui_input "Ziel fuer $lpath" \ +"Wohin soll $lpath weitergeleitet werden? + +Schreibweise: host:port z.B. 127.0.0.1:3000 + https://host:port fuer verschluesselte Ziele" "127.0.0.1:3000")" || break + [ -n "$ltarget" ] || break + if ! proxy_location_json "$lpath=$ltarget" >/dev/null 2>&1; then + ui_msg "Ungueltig" "'$lpath=$ltarget' konnte nicht gelesen werden.\n\nErwartet: /pfad und host:port" + continue + fi + locopt+=(--location "$lpath=$ltarget") + loclist="$loclist + $lpath -> $ltarget" + ui_yesno "Noch einer?" "Bisher:$loclist + +Einen weiteren Pfad hinzufuegen?" || break + done + fi + local upd="" - ui_yesno "Anlegen" \ + if ui_yesno "Anlegen" \ "$dom -> 127.0.0.1:$fport -Zertifikat: $cert +Zertifikat: $cert${loclist:+ + +Zusaetzliche Pfade:$loclist} Einen bereits vorhandenen Eintrag fuer diesen Namen ersetzen? ersetzt ihn - bricht ab, falls es ihn schon gibt" && upd=--update + bricht ab, falls es ihn schon gibt"; then upd=--update; fi 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" + --forward-port '$fport' --cert '$cert' $upd ${locopt[*]+${locopt[*]}}" # Die Vorgaben merken, damit der naechste Aufruf sie kennt env_set PROXY_DOMAIN "$dom" 1 2>/dev/null || true