"ports": wer belegt 80/443/5000 - und lokales Checkmk stilllegen
Auf einem Rechner, auf dem Checkmk vorher direkt installiert war, haelt die alte Instanz Port 5000 weiter besetzt, ein Apache aus der Grundinstallation gern 80 und 443. Der Container startet dann nicht, und die Suche ist muehsam: "ss" zeigt den Prozessnamen nur mit root-Rechten. "ports" beantwortet beides. Den Prozess findet es ueber ss, netstat oder lsof; die zugehoerige systemd-Unit liest es aus /proc/<pid>/cgroup - die Datei ist ohne root lesbar, damit steht auch ohne sudo da, welcher Dienst es ist. Nachgestellt mit eigenen Lauschern auf 5000 und 8000: Programm und Scope werden korrekt genannt. "ports --free" schlaegt vor, was sich stilllegen laesst, "--apply" fuehrt es nach Rueckfrage aus: omd stop alt omd config alt set AUTOSTART off systemctl disable --now httpd.service Geloescht wird NICHTS. "omd stop" haelt die Site nur an, AUTOSTART=off verhindert den Start nach einem Neustart; /omd/sites bleibt unangetastet und laesst sich weiterhin importieren - genau darum ging es. Drei Sicherungen: gestoppt wird nur, was laeuft; ein .scope (etwa eine Login-Sitzung) wird nie angeboten, weil sich daran nichts abschalten laesst; und Container-Dienste bleiben aussen vor, sonst legte man sich den eigenen Stack still. Beim Testen ein Abbruch gefunden: fehlt die site.conf, liefert sed 2 und unter "set -e" war mitten in der Ausgabe Schluss - die Liste der Sites erschien gar nicht erst. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -64,6 +64,8 @@ KOMMANDOS - Stack
|
||||
- SSH niemals, fremde Freigaben bleiben unberuehrt.
|
||||
Der Adminport des Proxy Managers wird mit
|
||||
angeboten; --keep-admin laesst ihn offen
|
||||
ports [--free] wer belegt 80/443/5000/8000? Direkt installiertes
|
||||
Checkmk stilllegen, ohne Daten zu loeschen
|
||||
noproxy [--fix] pruefen, ob lokale Adressen am HTTP-Proxy vorbeigehen
|
||||
(Zwangsproxy: sonst laufen selbst Anfragen an
|
||||
127.0.0.1 dorthin - sichtbar als "API-Fehler")
|
||||
@@ -7327,6 +7329,43 @@ gui_cert_self() {
|
||||
}
|
||||
|
||||
# Bericht anzeigen; fehlt etwas, das Uebernehmen anbieten
|
||||
# Wer belegt die Ports - und Angebot, es stillzulegen
|
||||
gui_ports() {
|
||||
local f rc=0
|
||||
f="$(mktemp)"
|
||||
( NO_COLOR=1 cmd_ports ) >"$f" 2>&1 || rc=$?
|
||||
ui_text "Belegte Ports" "$f"; rm -f "$f"
|
||||
|
||||
local vorschlag rc2=0
|
||||
vorschlag="$(mktemp)"
|
||||
( NO_COLOR=1 cmd_ports --free ) >"$vorschlag" 2>&1 || rc2=$?
|
||||
if ! ( set +o pipefail; grep -q '^ omd \|^ systemctl ' "$vorschlag" ); then
|
||||
rm -f "$vorschlag"; return 0
|
||||
fi
|
||||
ui_text "Was stillgelegt werden koennte" "$vorschlag"; rm -f "$vorschlag"
|
||||
|
||||
ui_yesno "Stilllegen" "Die gezeigten Dienste jetzt stilllegen?
|
||||
|
||||
Es wird NICHTS geloescht. Eine direkt installierte Site wird nur
|
||||
gestoppt und vom automatischen Start genommen - ihre Daten bleiben
|
||||
und lassen sich weiterhin importieren." || return 0
|
||||
|
||||
local -a a=(ports --free --apply --yes)
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
ui_run "Stilllegen" "$SELF" ${SELF_ENV_ARR[@]+"${SELF_ENV_ARR[@]}"} "${a[@]}" || true
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
gui_run_interactive sudo -- "$SELF" ${SELF_ENV_ARR[@]+"${SELF_ENV_ARR[@]}"} "${a[@]}"
|
||||
else
|
||||
ui_msg "Rechte" "Dafuer werden root-Rechte benoetigt."
|
||||
return 0
|
||||
fi
|
||||
|
||||
f="$(mktemp)"
|
||||
( NO_COLOR=1 cmd_ports ) >"$f" 2>&1 || true
|
||||
ui_text "Belegte Ports - Stand danach" "$f"; rm -f "$f"
|
||||
return 0
|
||||
}
|
||||
|
||||
gui_firewall() {
|
||||
local tmp rc=0
|
||||
tmp="$(mktemp)"
|
||||
@@ -7518,6 +7557,7 @@ Backups : $BACKUP_DIR" \
|
||||
browser "Terminal-Browser (Proxy Manager lokal bedienen)" \
|
||||
cert "Selbstsigniertes Zertifikat erzeugen" \
|
||||
firewall "Firewall pruefen (welche Ports muessen offen sein)" \
|
||||
ports "Belegte Ports - lokales Checkmk/Apache stilllegen" \
|
||||
config "Einstellungen (.env) - menuegefuehrt" \
|
||||
shell "Root-Shell im Checkmk-Container" \
|
||||
quit "Beenden")" || break
|
||||
@@ -7534,6 +7574,7 @@ Backups : $BACKUP_DIR" \
|
||||
browser) gui_browser_menu || true ;;
|
||||
cert) gui_cert || true ;;
|
||||
firewall) gui_firewall || true ;;
|
||||
ports) gui_ports || true ;;
|
||||
config) gui_settings_menu || true ;;
|
||||
shell) gui_need_container || continue
|
||||
gui_run_interactive cmd_shell ;;
|
||||
@@ -7614,6 +7655,192 @@ ${C_BLD}Auswertung${C_RST}
|
||||
EOF
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
# Wer belegt die Ports, und wie legt man ihn stumm?
|
||||
#
|
||||
# Auf einem Rechner, auf dem Checkmk vorher direkt installiert war,
|
||||
# haelt die alte Instanz Port 5000 weiter besetzt - und ein Apache aus
|
||||
# der Grundinstallation gern 80 und 443. Der Container startet dann
|
||||
# nicht, und die Suche nach dem Schuldigen ist muehsam, weil "ss" den
|
||||
# Prozessnamen nur mit root-Rechten zeigt.
|
||||
#
|
||||
# Geloescht wird hier NICHTS. Eine direkt installierte Site enthaelt
|
||||
# Daten, die man spaeter importieren will - sie wird nur gestoppt und
|
||||
# vom automatischen Start genommen.
|
||||
# =====================================================================
|
||||
|
||||
# Wer lauscht auf diesem Port? -> "pid|programm|unit"
|
||||
port_owner() { # port
|
||||
local port="$1" line pid prog unit=""
|
||||
line=""
|
||||
if command -v ss >/dev/null 2>&1; then
|
||||
line="$(ss -ltnpH "sport = :$port" 2>/dev/null | head -1)"
|
||||
fi
|
||||
if [ -z "$line" ] && command -v netstat >/dev/null 2>&1; then
|
||||
line="$(netstat -ltnp 2>/dev/null | awk -v p=":$port\$" '$4 ~ p {print; exit}')"
|
||||
fi
|
||||
[ -n "$line" ] || return 1
|
||||
|
||||
pid="$(printf '%s' "$line" | sed -n 's/.*pid=\([0-9]*\).*/\1/p')"
|
||||
if [ -z "$pid" ]; then
|
||||
pid="$(printf '%s' "$line" | sed -n 's|.*[[:space:]]\([0-9]\{1,\}\)/.*|\1|p')"
|
||||
fi
|
||||
if [ -z "$pid" ] && command -v lsof >/dev/null 2>&1; then
|
||||
pid="$(lsof -tiTCP:"$port" -sTCP:LISTEN 2>/dev/null | head -1)"
|
||||
fi
|
||||
|
||||
if [ -n "$pid" ] && [ -r "/proc/$pid/comm" ]; then
|
||||
prog="$(cat "/proc/$pid/comm" 2>/dev/null)"
|
||||
else
|
||||
prog="$(printf '%s' "$line" | sed -n 's/.*users:((\"\([^\"]*\)\".*/\1/p')"
|
||||
fi
|
||||
|
||||
# Die systemd-Unit steht in der cgroup-Zeile - dafuer braucht es
|
||||
# keine root-Rechte, anders als fuer den Prozessnamen aus ss.
|
||||
if [ -n "$pid" ] && [ -r "/proc/$pid/cgroup" ]; then
|
||||
unit="$(sed -n 's|.*/\([^/]*\.service\)$|\1|p' "/proc/$pid/cgroup" 2>/dev/null | head -1)"
|
||||
if [ -z "$unit" ]; then
|
||||
unit="$(sed -n 's|.*/\([^/]*\.scope\)$|\1|p' "/proc/$pid/cgroup" 2>/dev/null | head -1)"
|
||||
fi
|
||||
fi
|
||||
printf '%s|%s|%s\n' "${pid:-?}" "${prog:-unbekannt}" "$unit"
|
||||
}
|
||||
|
||||
# Sites einer direkt installierten Checkmk-Instanz
|
||||
local_omd_sites() {
|
||||
command -v omd >/dev/null 2>&1 || return 0
|
||||
omd sites 2>/dev/null | awk 'NR>1 && $1 != "" {print $1}'
|
||||
}
|
||||
|
||||
local_omd_running() { # site
|
||||
( set +o pipefail; omd status "$1" 2>/dev/null | grep -qE '^Overall state:[[:space:]]*running' )
|
||||
}
|
||||
|
||||
cmd_ports() {
|
||||
local free="" apply=""
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--free) free=1; shift ;;
|
||||
--apply) apply=1; free=1; shift ;;
|
||||
--yes|-y) ASSUME_YES=1; shift ;;
|
||||
--help|-h)
|
||||
cat <<EOF
|
||||
|
||||
Nachsehen, wer die Ports dieses Aufbaus belegt.
|
||||
|
||||
$SELF ports nur anzeigen
|
||||
sudo $SELF ports --free anbieten, die Belegung aufzuloesen
|
||||
sudo $SELF ports --free --apply
|
||||
|
||||
Typischer Fall: auf dem Rechner war Checkmk frueher direkt installiert.
|
||||
Die alte Site haelt Port 5000, ein Apache aus der Grundinstallation
|
||||
haelt 80 und 443 - der Container startet dann nicht.
|
||||
|
||||
Geloescht wird nichts. Eine direkt installierte Site wird gestoppt und
|
||||
vom automatischen Start genommen; ihre Daten bleiben unangetastet und
|
||||
lassen sich weiterhin importieren.
|
||||
EOF
|
||||
return 0 ;;
|
||||
*) die "Unbekannte Option fuer 'ports': $1" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf '\n%sBelegte Ports%s\n' "$C_BLD" "$C_RST"
|
||||
printf ' %-6s %-34s %-16s %s\n' "PORT" "ZWECK" "PROGRAMM" "UNIT/SCOPE"
|
||||
|
||||
local spec desc need port proto owner pid prog unit belegt=0
|
||||
local -a units=()
|
||||
while IFS='|' read -r spec desc need; do
|
||||
[ -n "$spec" ] || continue
|
||||
port="${spec%/*}"; proto="${spec##*/}"
|
||||
[ "$proto" = tcp ] || continue
|
||||
desc="$(printf '%s' "$desc" | cut -c1-33)"
|
||||
owner="$(port_owner "$port")" || { printf ' %-6s %-34s %s\n' "$port" "$desc" "frei"; continue; }
|
||||
pid="${owner%%|*}"; owner="${owner#*|}"
|
||||
prog="${owner%%|*}"; unit="${owner##*|}"
|
||||
# Unsere eigenen Container zaehlen nicht als Problem
|
||||
case "$prog" in
|
||||
conmon|podman|docker-proxy|dockerd|nginx|openresty|apache2|httpd|*) : ;;
|
||||
esac
|
||||
printf ' %-6s %-34s %-16s %s\n' "$port" "$desc" "$(printf '%s' "$prog" | cut -c1-16)" \
|
||||
"$(printf '%s' "${unit:-–}" | cut -c1-30)"
|
||||
belegt=$((belegt+1))
|
||||
if [ -n "$unit" ]; then
|
||||
case " ${units[*]-} " in *" $unit "*) : ;; *) units+=("$unit") ;; esac
|
||||
fi
|
||||
done < <(fw_required_ports)
|
||||
|
||||
# --- Direkt installiertes Checkmk --------------------------------
|
||||
local -a sites=(); mapfile -t sites < <(local_omd_sites)
|
||||
if [ "${#sites[@]}" -gt 0 ]; then
|
||||
printf '\n%sDirekt installiertes Checkmk%s\n' "$C_BLD" "$C_RST"
|
||||
printf ' Version : %s\n' "$(omd version 2>/dev/null | sed 's/.*: *//' || true)"
|
||||
local st auto
|
||||
for st in "${sites[@]}"; do
|
||||
# Fehlt die Datei, liefert sed 2 - unter "set -e" waere hier
|
||||
# sonst Schluss, mitten in der Ausgabe.
|
||||
auto="$(sed -n "s/^CONFIG_AUTOSTART='\(.*\)'$/\1/p" \
|
||||
"/omd/sites/$st/etc/omd/site.conf" 2>/dev/null || true)"
|
||||
printf ' %-16s %-12s Autostart: %s\n' "$st" \
|
||||
"$(local_omd_running "$st" && echo laeuft || echo 'gestoppt')" "${auto:-?}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$belegt" -eq 0 ] && [ "${#sites[@]}" -eq 0 ]; then
|
||||
echo; ok "Kein Port belegt, keine direkt installierte Instanz."; echo
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "$free" ]; then
|
||||
printf '\n Aufloesen: sudo %s ports --free\n\n' "$SELF"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# --- Vorschlaege --------------------------------------------------
|
||||
printf '\n%sVorschlag%s\n' "$C_BLD" "$C_RST"
|
||||
local -a cmds=()
|
||||
for st in ${sites[@]+"${sites[@]}"}; do
|
||||
if local_omd_running "$st"; then cmds+=("omd stop $st"); fi
|
||||
cmds+=("omd config $st set AUTOSTART off")
|
||||
done
|
||||
local u
|
||||
for u in ${units[@]+"${units[@]}"}; do
|
||||
case "$u" in
|
||||
*.scope) continue ;; # kein Dienst, nichts abzuschalten
|
||||
docker.service|containerd.service|podman.service|podman.socket) continue ;;
|
||||
esac
|
||||
cmds+=("systemctl disable --now $u")
|
||||
done
|
||||
if [ "${#cmds[@]}" -eq 0 ]; then
|
||||
warn "Nichts gefunden, das sich gefahrlos stilllegen liesse."
|
||||
printf ' Die Belegung kommt vermutlich von den eigenen Containern.\n\n'
|
||||
return 0
|
||||
fi
|
||||
local c
|
||||
for c in "${cmds[@]}"; do printf ' %s\n' "$c"; done
|
||||
printf '
|
||||
%sDie Daten bleiben.%s "omd stop" haelt die Site nur an, AUTOSTART=off
|
||||
verhindert den Start nach einem Neustart. Nichts wird geloescht - ein
|
||||
Import ist weiterhin moeglich:
|
||||
%s import --file <bundle>\n' "$C_BLD" "$C_RST" "$SELF"
|
||||
|
||||
if [ -z "$apply" ]; then
|
||||
printf '\n Ausfuehren mit: sudo %s ports --free --apply\n\n' "$SELF"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo
|
||||
[ "$(id -u)" -eq 0 ] || die "Dafuer werden root-Rechte benoetigt."
|
||||
confirm "Diese Befehle jetzt ausfuehren?" || die "Abgebrochen."
|
||||
for c in "${cmds[@]}"; do
|
||||
log "$c"
|
||||
eval "$c" >/dev/null 2>&1 || warn "Fehlgeschlagen: $c"
|
||||
done
|
||||
ok "Erledigt. Danach pruefen: $SELF ports"
|
||||
echo
|
||||
return 0
|
||||
}
|
||||
|
||||
# =====================================================================
|
||||
# Firewall
|
||||
#
|
||||
@@ -8876,6 +9103,7 @@ main() {
|
||||
selftest) cmd_selftest ;;
|
||||
tui-check) cmd_tui_check ;;
|
||||
firewall) cmd_firewall "$@" ;;
|
||||
ports) cmd_ports "$@" ;;
|
||||
noproxy) cmd_noproxy "$@" ;;
|
||||
help|-h|--help) usage ;;
|
||||
*) err "Unbekanntes Kommando: $cmd"; echo; usage; exit 1 ;;
|
||||
|
||||
Reference in New Issue
Block a user