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