From 08271a04cfadf053b99650f1306f44dc91b2c75e Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 20 Sep 2026 21:08:08 +0200 Subject: [PATCH] firewall close: den Adminport des Proxy Managers mit anbieten Der Adminport war als "noetig" eingestuft und blieb deshalb offen, obwohl er gerade der Port ist, der im Netz nichts verloren hat. Die Oberflaeche ist auch ueber 127.0.0.1 zu erreichen - per Terminal-Browser im Container oder ueber einen SSH-Tunnel -, der Port ist also kein Pflichtport. Er wird jetzt zum Schliessen angeboten, mit dem Hinweis, was das bedeutet; --keep-admin laesst ihn offen, und in der Oberflaeche wird gefragt, sobald er betroffen ist. Welcher Port es ist, kommt aus NPM_ADMIN_PORT - wer auf 10443 verlegt hat, bekommt 10443 angeboten. Die Vorgabe 81 steht zusaetzlich immer im Katalog: nach einem Portwechsel bliebe sie sonst offen, ohne dass sie noch jemand nennt. Genau dieser Fall - 81 und 10443 beide offen, konfiguriert ist 10443 - ist der Testfall. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 24 +++++++++++++++- README_en.md | 24 +++++++++++++++- scripts/cmk-manage.sh | 67 ++++++++++++++++++++++++++++++++++++------- 3 files changed, 103 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 90930db..c16f3ae 100644 --- a/README.md +++ b/README.md @@ -2023,6 +2023,28 @@ Drei Sicherungen sind eingebaut: | **Fremde Freigaben bleiben** | Wer 3306 für seine Datenbank offen hat, behält sie – geschlossen wird nur, was dieser Aufbau kennt | | **Sammelregeln bleiben** | Eine Regel wie `80,443/tcp` deckt mehrere Ports ab; sie wird nicht angefasst, sondern gemeldet | +**Der Adminport des Proxy Managers wird mit angeboten.** Er ist kein +Pflichtport: die Oberfläche ist auch über `127.0.0.1` erreichbar – per +Terminal-Browser im Container oder über einen SSH-Tunnel. Offen im Netz hat sie +nichts verloren, und genau deshalb steht sie hier zur Disposition: + +``` + PORT GEHOERT ZU ZUSTAND + 10443/tcp Adminoberflaeche des Proxy Managers kann zu - Zugang dann nur lokal + 81/tcp Adminoberflaeche - alter Vorgabeport kann zu +``` + +Welcher Port das ist, kommt aus `NPM_ADMIN_PORT` – wer ihn auf 10443 verlegt +hat, bekommt 10443 angeboten. Die Vorgabe **81 steht zusätzlich immer im +Katalog**: nach einem Portwechsel bliebe sie sonst offen, ohne dass sie noch +jemand nennt. Soll der Adminzugang aus dem Netz erhalten bleiben: + +```bash +sudo ./scripts/cmk-manage.sh firewall close --apply --keep-admin +``` + +In der Oberfläche wird danach gefragt, sobald ein Adminport betroffen ist. + Bei ufw wird dabei bewusst **nicht** nach Regelnummern gelöscht: die verschieben sich beim ersten Löschen, der nächste Aufruf träfe die falsche Regel. Stattdessen wird über die Regelangabe gelöscht @@ -2296,7 +2318,7 @@ Eine Dateiauswahl mit Verzeichnisnavigation ist eingebaut. | `npm-reset` | Datenbank beiseitelegen, damit das Konto neu entsteht | | `proxy status\|list\|certs\|add\|del` | Proxy-Hosts über die API anlegen und verwalten | | `cert …` | selbstsigniertes Zertifikat erzeugen | -| `firewall [check\|open\|close]` | prüfen, öffnen und nicht mehr Benötigtes wieder schließen (firewalld, ufw, nftables, iptables) | +| `firewall [check\|open\|close]` | prüfen, öffnen und nicht mehr Benötigtes wieder schließen (firewalld, ufw, nftables, iptables); `close --keep-admin` lässt den Adminport offen | | `shell` | Root-Shell im Checkmk-Container | | `omd …` | beliebiges `omd`-Kommando im Container | diff --git a/README_en.md b/README_en.md index f8c6112..e1d79fb 100644 --- a/README_en.md +++ b/README_en.md @@ -2012,6 +2012,28 @@ Three safeguards are built in: | **Foreign rules stay** | if you have 3306 open for your database, you keep it – only what this setup knows about is closed | | **Collective rules stay** | a rule like `80,443/tcp` covers several ports; it is reported instead of deleted | +**The Proxy Manager's admin port is offered as well.** It is not a mandatory +port: the interface is reachable through `127.0.0.1` too – via the terminal +browser in the container or through an SSH tunnel. Exposed to the network it +has no business being open, which is exactly why it is up for discussion here: + +``` + PORT GEHOERT ZU ZUSTAND + 10443/tcp Adminoberflaeche des Proxy Managers kann zu - Zugang dann nur lokal + 81/tcp Adminoberflaeche - alter Vorgabeport kann zu +``` + +Which port that is comes from `NPM_ADMIN_PORT` – move it to 10443 and 10443 is +what gets offered. The default **81 is always in the catalogue as well**: after +moving the port it would otherwise stay open with nobody naming it any more. To +keep admin access from the network: + +```bash +sudo ./scripts/cmk-manage.sh firewall close --apply --keep-admin +``` + +The GUI asks about it as soon as an admin port is affected. + With ufw the rules are deliberately **not** deleted by number: those shift on the first deletion, and the next call would hit the wrong rule. Deletion goes by rule specification instead (`ufw delete allow 514/udp`), with nftables by @@ -2285,7 +2307,7 @@ A file chooser with directory navigation is built in. | `npm-reset` | move the database aside so the account is recreated | | `proxy status\|list\|certs\|add\|del` | create and manage proxy hosts through the API | | `cert …` | create a self-signed certificate | -| `firewall [check\|open\|close]` | check, open, and close again what is no longer needed (firewalld, ufw, nftables, iptables) | +| `firewall [check\|open\|close]` | check, open, and close again what is no longer needed (firewalld, ufw, nftables, iptables); `close --keep-admin` keeps the admin port open | | `shell` | root shell in the Checkmk container | | `omd …` | any `omd` command inside the container | diff --git a/scripts/cmk-manage.sh b/scripts/cmk-manage.sh index a103ef3..fd8e130 100755 --- a/scripts/cmk-manage.sh +++ b/scripts/cmk-manage.sh @@ -56,7 +56,9 @@ KOMMANDOS - Stack Firewall pruefen: welche Ports der Stack braucht und ob sie offen sind (firewalld, ufw, nftables, iptables). "close" schliesst wieder, was nicht mehr gebraucht wird - - SSH niemals, fremde Freigaben bleiben unberuehrt + - SSH niemals, fremde Freigaben bleiben unberuehrt. + Der Adminport des Proxy Managers wird mit + angeboten; --keep-admin laesst ihn offen selftest Skripte auf bekannte Fallstricke pruefen tui-check Testzeilen fuer die Rahmendarstellung ausgeben (hilft bei q/x/l/m statt Linien, etwa in PuTTY) @@ -6094,10 +6096,11 @@ Bitte als root erneut aufrufen." # Nicht mehr benoetigte Ports wieder schliessen gui_firewall_close() { - local tmp rc=0 hat="" + local tmp rc=0 hat="" adminfall="" tmp="$(mktemp)" cmd_firewall close >"$tmp" 2>&1 || rc=$? if ( set +o pipefail; grep -q 'Zum Schliessen' "$tmp" ); then hat=1; fi + if ( set +o pipefail; grep -q 'Zugang dann nur lokal' "$tmp" ); then adminfall=1; fi ui_text "Nicht mehr benoetigte Ports" "$tmp" rm -f "$tmp" [ -n "$hat" ] || return 0 @@ -6109,6 +6112,17 @@ Port dieser Sitzung. Freigaben fuer fremde Dienste werden nicht angeruehrt." || return 0 local -a a=(firewall close --apply --yes) + # Ist der Adminport dabei, ist das eine bewusste Entscheidung + if [ -n "$adminfall" ]; then + if ui_yesno "Adminoberflaeche" "Der Adminport ${NPM_ADMIN_PORT:-81} des Proxy Managers ist dabei. + +Soll er offen bleiben? + +Ja = Adminoberflaeche bleibt aus dem Netz erreichbar +Nein = nur noch lokal (Terminal-Browser oder SSH-Tunnel)"; then + a+=(--keep-admin) + fi + fi if [ "$(id -u)" -eq 0 ]; then ui_run "Ports schliessen" "$SELF" "${a[@]}" || true elif command -v sudo >/dev/null 2>&1; then @@ -6513,6 +6527,9 @@ fw_known_ports() { printf '80/tcp|HTTP\n' printf '443/tcp|HTTPS\n' printf '%s/tcp|Adminoberflaeche des Proxy Managers\n' "${NPM_ADMIN_PORT:-81}" + # Auch die Vorgabe 81 - wer den Adminport spaeter verlegt hat, haette + # den alten sonst weiter offen, ohne dass ihn noch jemand nennt. + printf '81/tcp|Adminoberflaeche - alter Vorgabeport\n' printf '5000/tcp|Checkmk direkt\n' printf '8000/tcp|Agent-Receiver\n' printf '6557/tcp|Livestatus\n' @@ -6691,16 +6708,26 @@ fw_close_cmds() { # backend port proto # Welche Ports sind offen, gehoeren zu diesem Aufbau, werden aber nicht # mehr gebraucht? -fw_close_report() { # backend apply - local be="$1" apply="${2:-}" +fw_close_report() { # backend apply keep_admin + local be="$1" apply="${2:-}" keep_admin="${3:-}" local spec need port proto desc local -a todo=() - # Was gebraucht wird, darf nicht weg - local noetig="" + # Was gebraucht wird, darf nicht weg. Der Adminport des Proxy + # Managers gehoert NICHT dazu: die Oberflaeche ist auch ueber + # 127.0.0.1 und den Terminal-Browser zu erreichen, und offen im Netz + # hat sie nichts verloren. Wer ihn behalten will: --keep-admin. + local noetig="" adminports="" while IFS='|' read -r spec desc need; do [ -n "$spec" ] || continue - case "$need" in ja|admin) noetig="$noetig$spec"$'\n' ;; esac + case "$need" in + ja) noetig="$noetig$spec"$'\n' ;; + admin) if [ -n "$keep_admin" ]; then + noetig="$noetig$spec"$'\n' + else + adminports="$adminports$spec"$'\n' + fi ;; + esac done < <(fw_required_ports) local geschuetzt; geschuetzt="$(fw_protected_ports | sed '/^$/d' | sort -u)" @@ -6722,7 +6749,12 @@ fw_close_report() { # backend apply continue fi todo+=("$spec") - printf ' %-10s %-44s %b\n' "$spec" "$desc" "${C_YEL}kann zu${C_RST}" + if ( set +o pipefail; printf '%s' "$adminports" | grep -qxF "$spec" ); then + printf ' %-10s %-44s %b\n' "$spec" "$desc" \ + "${C_YEL}kann zu - Zugang dann nur lokal${C_RST}" + else + printf ' %-10s %-44s %b\n' "$spec" "$desc" "${C_YEL}kann zu${C_RST}" + fi done < <(fw_known_ports) if [ "${#todo[@]}" -eq 0 ]; then @@ -6733,6 +6765,20 @@ fw_close_report() { # backend apply return 0 fi + # Betrifft es den Adminport, gehoert dazu gesagt, was das bedeutet + local t2 + for t2 in "${todo[@]}"; do + if ( set +o pipefail; printf '%s' "$adminports" | grep -qxF "$t2" ); then + printf '\n Der Adminport %s des Proxy Managers ist dabei. Die Oberflaeche ist + danach nur noch lokal erreichbar: + %s browser (Terminal-Browser im Container) + ssh -L %s:127.0.0.1:%s ... (Tunnel vom Arbeitsplatz) + Soll er offen bleiben: %s firewall close --keep-admin\n' \ + "${t2%/*}" "$SELF" "${t2%/*}" "${t2%/*}" "$SELF" + break + fi + done + printf '\n%sZum Schliessen%s\n' "$C_BLD" "$C_RST" local t c n=0 for t in "${todo[@]}"; do @@ -6786,12 +6832,13 @@ fw_close_report() { # backend apply cmd_firewall() { local sub="${1:-check}"; [ $# -gt 0 ] && shift || true case "$sub" in check|open|close) : ;; *) die "Unbekannt: firewall $sub (check|open|close)" ;; esac - local apply="" src="" + local apply="" src="" keep_admin="" while [ $# -gt 0 ]; do case "$1" in --apply) apply=1; shift ;; --yes|-y) ASSUME_YES=1; shift ;; --source) src="$2"; shift 2 ;; + --keep-admin) keep_admin=1; shift ;; *) die "Unbekannte Option fuer 'firewall': $1" ;; esac done @@ -6829,7 +6876,7 @@ cmd_firewall() { echo; warn "Ohne erkannte Firewall gibt es nichts zu schliessen."; echo return 0 fi - fw_close_report "$be" "$apply" + fw_close_report "$be" "$apply" "$keep_admin" return $? fi