Firewall-Pruefung: welche Ports offen sein muessen - und welche nicht

Auf RHEL ist firewalld ab Werk aktiv und gibt in aller Regel nur SSH
frei. Der Stack laeuft dann sauber, ist aber von aussen nicht zu
erreichen: die Agents kommen nicht durch den Receiver auf 8000, und im
Browser passiert nichts. Das war bisher nur eine Handvoll statischer
Beispielzeilen in der README und in install.sh.

Neu ist "cmk-manage.sh firewall". Erkannt werden firewalld, ufw,
nftables und iptables; welche Ports noetig sind, ergibt sich aus der
Konfiguration statt aus einer festen Liste:

  - ohne Proxy Manager wird 5000 zum Pflichtport, mit ihm soll es zu
    bleiben - offenes 5000 wird deshalb ausdruecklich angemerkt
  - der Admin-Port kommt aus NPM_ADMIN_PORT, nicht fest aus 81
  - FW_ROLE unterscheidet single/central/remote: eine Remote-Site
    braucht 6557 eingehend, die Zentrale baut die Verbindungen selbst
    auf und braucht dafuer nichts. Steht FW_ROLE=remote bei
    CMK_LIVESTATUS_TCP=off, ist der Port zwar offen, es lauscht aber
    niemand - auch darauf weist der Bericht hin.
  - Event Console ueber FW_EC_SYSLOG / FW_EC_SNMPTRAP / FW_EC_TCP,
    Agent dieses Hosts ueber FW_AGENT, alles Weitere (Grafana, NSCA)
    ueber FW_EXTRA_PORTS

Syslog und SNMP-Traps laufen ueber UDP, eine TCP-Freigabe nuetzt ihnen
nichts. Ports werden deshalb durchweg als nummer/protokoll gefuehrt -
beim Pruefen wie beim Erzeugen der Regeln. Bestehende Regeln werden
entsprechend gelesen: Portbereiche (6556-6558 bzw. 6556:6558) werden
aufgeloest, firewalld-Dienstnamen und Rich Rules zaehlen mit, bei
firewalld alle aktiven Zonen statt nur der Standardzone, und eine
ufw-Regel ohne Protokoll zaehlt fuer TCP und UDP - so wie ufw sie
anlegt.

"firewall open" zeigt die passenden Kommandos, --apply setzt sie nach
Rueckfrage, --source begrenzt sie auf ein Quellnetz (fuer Port 80 mit
Warnung, weil Lets Encrypt von aussen prueft). Ohne Befund ist der
Rueckgabewert 1, damit sich das auswerten laesst. In der Oberflaeche
steckt derselbe Bericht unter "Firewall pruefen".

Nebenbei: env_set hat Werte mit Leerzeichen samt Anfuehrungszeichen in
die laufende Umgebung exportiert. In der Datei gehoeren sie hin, im
Wert nicht - das fiel erst mit den Beschreibungen in FW_EXTRA_PORTS auf.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-20 19:46:33 +02:00
co-authored by Claude Opus 5
parent d06ecb2704
commit b912578f27
6 changed files with 722 additions and 28 deletions
+445 -1
View File
@@ -51,6 +51,9 @@ KOMMANDOS - Stack
pull Images aktualisieren
status Status von Containern und Sites anzeigen
logs [-f] [DIENST] Logs anzeigen
firewall [check|open [--apply] [--source CIDR]]
Firewall pruefen: welche Ports der Stack braucht und
ob sie offen sind (firewalld, ufw, nftables, iptables)
selftest Skripte auf bekannte Fallstricke pruefen
tui-check Testzeilen fuer die Rahmendarstellung ausgeben
(hilft bei q/x/l/m statt Linien, etwa in PuTTY)
@@ -2963,6 +2966,12 @@ cert|CERT_DOMAIN|text|FQDN fuer selbstsignierte Zertifikate||
cert|CERT_DAYS|int|Gueltigkeit in Tagen||
cert|CERT_COUNTRY|text|Laenderkuerzel||
cert|CERT_ORG|text|Organisation||
firewall|FW_ROLE|choice|Rolle im verteilten Monitoring|single:central:remote|
firewall|FW_EC_SYSLOG|choice|Event Console: Syslog annehmen (514)|off:udp:tcp:beide|
firewall|FW_EC_SNMPTRAP|choice|Event Console: SNMP-Traps (162/udp)|off:on|
firewall|FW_EC_TCP|choice|Event Console: Status ueber TCP (6558)|off:on|
firewall|FW_AGENT|choice|Checkmk-Agent auf diesem Host (6556)|off:on|
firewall|FW_EXTRA_PORTS|text|Weitere Ports (3000/tcp=Grafana,...)||1
EOF
}
@@ -2976,6 +2985,7 @@ browser|Terminal-Browser
paths|Verzeichnisse
cert|Selbstsignierte Zertifikate
backup|Backup-Automatik
firewall|Firewall: was offen sein muss
EOF
}
@@ -3025,6 +3035,23 @@ settings_validate_key() {
*[!a-zA-Z0-9_]*) echo "Ein Site-Name darf nur Buchstaben, Ziffern und _ enthalten."; return 1 ;;
esac
[ "${#val}" -le 16 ] || { echo "Ein Site-Name darf hoechstens 16 Zeichen lang sein."; return 1; } ;;
FW_EXTRA_PORTS)
[ -z "$val" ] && return 0
local e pp
while IFS= read -r e; do
e="$(printf '%s' "$e" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
[ -n "$e" ] || continue
pp="${e%%=*}"
case "$pp" in
[0-9]*/tcp|[0-9]*/udp|[0-9]*) : ;;
*) echo "'$pp' ist kein Port. Erwartet wird 3000/tcp=Grafana,5667/tcp=NSCA"
return 1 ;;
esac
case "${pp%/*}" in
*[!0-9]*) echo "'$pp' ist keine Portnummer."; return 1 ;;
esac
done < <(printf '%s\n' "$val" | tr ',' '\n')
;;
CMK_IMAGE|NPM_IMAGE|BROWSH_IMAGE|CARBONYL_IMAGE)
if [ -n "$val" ] && image_is_short_name "$val"; then
echo "Bitte vollqualifiziert angeben (z.B. docker.io/...) - Podman
@@ -5091,6 +5118,43 @@ gui_cert() {
ui_run "Zertifikat erzeugen" bash -c "cd '$PROJECT_DIR' && '$SELF' cert --domain '$domain' --days '$days' ${a[*]+${a[*]}}"
}
gui_firewall() {
local tmp rc=0
tmp="$(mktemp)"
cmd_firewall check >"$tmp" 2>&1 || rc=$?
if [ "$rc" -eq 0 ]; then
ui_text "Firewall - alles offen, was gebraucht wird" "$tmp"
rm -f "$tmp"; return 0
fi
ui_text "Firewall - es fehlen Freigaben" "$tmp"
rm -f "$tmp"
ui_yesno "Firewall" "Es fehlen Freigaben.
Sollen die benoetigten Ports jetzt geoeffnet werden?
Die Regeln werden dauerhaft gesetzt." || return 0
local src=""
if ui_yesno "Firewall" "Nur fuer ein bestimmtes Quellnetz freigeben?
Ja = nur dieses Netz darf zugreifen
Nein = Freigabe fuer alle Quellen"; then
src="$(ui_input "Firewall" "Quellnetz in CIDR-Schreibweise:" "$(primary_ip | sed 's/\.[0-9]*$/.0\/24/')")" || src=""
fi
local -a a=(firewall open --apply --yes)
if [ -n "$src" ]; then a+=(--source "$src"); fi
if [ "$(id -u)" -eq 0 ]; then
ui_run "Firewall freigeben" "$SELF" "${a[@]}" || true
elif command -v sudo >/dev/null 2>&1; then
gui_run_interactive sudo -- "$SELF" "${a[@]}"
else
ui_msg "Firewall" "Dafuer werden root-Rechte benoetigt.
Bitte als root erneut aufrufen."
fi
return 0
}
gui_main() {
ui_require
while :; do
@@ -5110,6 +5174,7 @@ Backups : $BACKUP_DIR" \
proxy "Proxy-Hosts anlegen/verwalten (HTTPS fuer Checkmk)" \
browser "Terminal-Browser (Proxy Manager lokal bedienen)" \
cert "Selbstsigniertes Zertifikat erzeugen" \
firewall "Firewall pruefen (welche Ports muessen offen sein)" \
config "Einstellungen (.env) - menuegefuehrt" \
shell "Root-Shell im Checkmk-Container" \
quit "Beenden")" || break
@@ -5124,7 +5189,8 @@ Backups : $BACKUP_DIR" \
image) gui_image_menu || true ;;
proxy) gui_proxy_menu || true ;;
browser) gui_browser_menu || true ;;
cert) gui_cert || true ;;
cert) gui_cert || true ;;
firewall) gui_firewall || true ;;
config) gui_settings_menu || true ;;
shell) gui_need_container || continue
gui_run_interactive cmd_shell ;;
@@ -5205,6 +5271,383 @@ ${C_BLD}Auswertung${C_RST}
EOF
}
# =====================================================================
# Firewall
#
# RHEL und Rocky haben firewalld ab Werk aktiv, und dort ist in aller
# Regel nur SSH freigegeben. Der Agent-Receiver auf 8000 und HTTPS auf
# 443 waeren damit dicht - die Agents kaemen nicht durch, ohne dass es
# am Stack selbst laege.
#
# Geprueft werden firewalld, ufw, nftables und iptables. Welche Ports
# noetig sind, haengt von der Konfiguration ab: ohne Proxy Manager
# braucht der externe Proxy Zugriff auf 5000, als Remote-Site einer
# verteilten Ueberwachung kommt Livestatus dazu, mit Event Console
# Syslog und SNMP-Traps - und die laufen ueber UDP. Ports werden
# deshalb durchweg als "nummer/protokoll" gefuehrt.
# =====================================================================
fw_lc() { printf '%s' "${1:-}" | tr 'A-Z' 'a-z'; }
fw_on() { # Wert -> 0, wenn eingeschaltet
case "$(fw_lc "${1:-}")" in on|true|1|yes|ja) return 0 ;; esac
return 1
}
fw_detect() {
if command -v firewall-cmd >/dev/null 2>&1 \
&& firewall-cmd --state >/dev/null 2>&1; then
printf 'firewalld\n'; return 0
fi
if command -v ufw >/dev/null 2>&1 \
&& ( set +o pipefail; ufw status 2>/dev/null | grep -qi '^Status: active' ); then
printf 'ufw\n'; return 0
fi
if command -v nft >/dev/null 2>&1 && [ -n "$(nft list ruleset 2>/dev/null)" ]; then
printf 'nftables\n'; return 0
fi
if command -v iptables >/dev/null 2>&1 \
&& [ "$(iptables -S 2>/dev/null | wc -l)" -gt 3 ]; then
printf 'iptables\n'; return 0
fi
printf 'keine\n'
}
# firewalld kennt Zonen. Hat der Rechner mehrere Netzwerkkarten, haengen
# sie oft in verschiedenen Zonen - dann sagt die Standardzone allein
# nichts darueber aus, ob ein Port erreichbar ist.
fw_zones() {
local z
z="$(firewall-cmd --get-active-zones 2>/dev/null | grep -v '^[[:space:]]' || true)"
if [ -z "$z" ]; then z="$(firewall-cmd --get-default-zone 2>/dev/null || true)"; fi
printf '%s\n' "$z" | sed '/^$/d'
}
# Dienstnamen von firewalld auf port/protokoll abbilden
fw_service_port() {
case "$1" in
ssh) printf '22/tcp\n' ;;
http) printf '80/tcp\n' ;;
https) printf '443/tcp\n' ;;
cockpit) printf '9090/tcp\n' ;;
syslog) printf '514/udp\n514/tcp\n' ;;
syslog-tls) printf '6514/tcp\n' ;;
snmptrap) printf '162/udp\n' ;;
snmp) printf '161/udp\n' ;;
*) : ;;
esac
}
# ---------------------------------------------------------------------
# Welche Ports braucht der Stack in dieser Konfiguration?
# port/proto|zweck|noetig (noetig: ja | nein | admin)
# ---------------------------------------------------------------------
fw_required_ports() {
local role; role="$(fw_lc "${FW_ROLE:-single}")"
case "$role" in central|remote) : ;; *) role=single ;; esac
if npm_enabled; then
printf '80/tcp|HTTP und Lets-Encrypt-Pruefung|ja\n'
printf '443/tcp|HTTPS (Checkmk, Zentrale, weitere Dienste)|ja\n'
printf '%s/tcp|Adminoberflaeche des Proxy Managers|admin\n' "${NPM_ADMIN_PORT:-81}"
printf '5000/tcp|Checkmk direkt - gehoert hinter den Proxy|nein\n'
else
printf '5000/tcp|Checkmk direkt - Ziel des externen Proxys|ja\n'
fi
printf '8000/tcp|Agent-Receiver (registrierte Agents)|ja\n'
# --- Verteilte Ueberwachung ---------------------------------------
# Als Remote-Site fragt die Zentrale Livestatus ab. Die Zentrale
# selbst baut nur Verbindungen auf und braucht dafuer nichts offen.
if [ "$role" = remote ]; then
printf '6557/tcp|Livestatus - die Zentrale fragt diese Site ab|ja\n'
elif fw_on "${CMK_LIVESTATUS_TCP:-off}"; then
printf '6557/tcp|Livestatus ueber TCP|ja\n'
else
printf '6557/tcp|Livestatus - aus (CMK_LIVESTATUS_TCP=off)|nein\n'
fi
# --- Event Console -------------------------------------------------
case "$(fw_lc "${FW_EC_SYSLOG:-off}")" in
udp) printf '514/udp|Event Console: Syslog|ja\n' ;;
tcp) printf '514/tcp|Event Console: Syslog ueber TCP|ja\n' ;;
beide|both|on)
printf '514/udp|Event Console: Syslog|ja\n'
printf '514/tcp|Event Console: Syslog ueber TCP|ja\n' ;;
esac
if fw_on "${FW_EC_SNMPTRAP:-off}"; then
printf '162/udp|Event Console: SNMP-Traps|ja\n'
fi
if fw_on "${FW_EC_TCP:-off}"; then
printf '6558/tcp|Event Console: Status und Ereignisse ueber TCP|ja\n'
fi
# --- Agent auf diesem Host ----------------------------------------
if fw_on "${FW_AGENT:-off}"; then
printf '6556/tcp|Checkmk-Agent dieses Hosts (Pull-Betrieb)|ja\n'
fi
# --- Frei eingetragene Ports ---------------------------------------
# Form: 3000/tcp=Grafana,5667/tcp=NSCA
local e pp d
while IFS= read -r e; do
e="$(printf '%s' "$e" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//')"
[ -n "$e" ] || continue
pp="${e%%=*}"; d="${e#*=}"
if [ "$d" = "$e" ] || [ -z "$d" ]; then d="zusaetzlich freigegeben"; fi
case "$pp" in */tcp|*/udp) : ;; *) pp="$pp/tcp" ;; esac
printf '%s|%s|ja\n' "$pp" "$d"
done < <(printf '%s\n' "${FW_EXTRA_PORTS:-}" | tr ',' '\n')
}
# ---------------------------------------------------------------------
# Offene Ports der erkannten Firewall einsammeln, "nummer/proto" je Zeile.
# Bereiche (6000-6010 bzw. 6000:6010) bleiben stehen und werden beim
# Vergleich aufgeloest.
# ---------------------------------------------------------------------
fw_open_ports() { # backend
case "$1" in
firewalld)
{ local zone svc
while IFS= read -r zone; do
[ -n "$zone" ] || continue
firewall-cmd --zone="$zone" --list-ports 2>/dev/null | tr ' ' '\n'
firewall-cmd --zone="$zone" --list-services 2>/dev/null | tr ' ' '\n' \
| while IFS= read -r svc; do
if [ -n "$svc" ]; then fw_service_port "$svc"; fi
done
firewall-cmd --zone="$zone" --list-rich-rules 2>/dev/null \
| sed -n 's/.*port port="\([0-9:-]*\)" protocol="\([a-z]*\)".*/\1\/\2/p'
done < <(fw_zones)
} | sed '/^$/d' | sort -u ;;
ufw)
local spec ports proto pp
ufw status 2>/dev/null | awk 'NR>3 {print $1}' \
| while IFS= read -r spec; do
case "$spec" in *[0-9]*) : ;; *) continue ;; esac
proto=""; ports="$spec"
case "$spec" in
*/tcp|*/udp) proto="${spec##*/}"; ports="${spec%/*}" ;;
esac
for pp in $(printf '%s' "$ports" | tr ',' ' '); do
case "$pp" in *[!0-9:-]*) continue ;; esac
if [ -n "$proto" ]; then
printf '%s/%s\n' "$pp" "$proto"
else
printf '%s/tcp\n%s/udp\n' "$pp" "$pp"
fi
done
done | sort -u ;;
nftables)
local proto rest pp
nft list ruleset 2>/dev/null \
| grep -oE '(tcp|udp) dport[[:space:]]*(\{[^}]*\}|[0-9]+(-[0-9]+)?)' \
| sed 's/dport//; s/[{}]//g' \
| while read -r proto rest; do
for pp in $(printf '%s' "$rest" | tr ',' ' '); do
printf '%s/%s\n' "$pp" "$proto"
done
done | sort -u ;;
iptables)
local line proto ports pp
iptables -S 2>/dev/null | grep -E ' -j (ACCEPT|accept)$' \
| while IFS= read -r line; do
proto="$(printf '%s' "$line" | sed -n 's/.* -p \([a-z0-9]*\).*/\1/p')"
case "$proto" in tcp|udp) : ;; *) continue ;; esac
ports="$(printf '%s' "$line" \
| grep -oE '\-\-(dport|dports) [0-9,:]+' \
| sed 's/--dports\? //')"
[ -n "$ports" ] || continue
for pp in $(printf '%s' "$ports" | tr ',' ' '); do
printf '%s/%s\n' "$pp" "$proto"
done
done | sort -u ;;
*) : ;;
esac
}
# Steht port/proto in der Liste der offenen? Bereiche werden aufgeloest.
fw_port_open() { # port proto (Liste in _FW_OPEN, eine je Zeile)
local port="$1" proto="$2" e ep epr lo hi
while IFS= read -r e; do
[ -n "$e" ] || continue
ep="${e%/*}"; epr="${e##*/}"
[ "$epr" = "$proto" ] || continue
case "$ep" in
*[-:]*)
lo="${ep%%[-:]*}"; hi="${ep##*[-:]}"
case "$lo$hi" in *[!0-9]*) continue ;; esac
if [ "$port" -ge "$lo" ] && [ "$port" -le "$hi" ]; then return 0; fi ;;
*) if [ "$ep" = "$port" ]; then return 0; fi ;;
esac
done <<<"${_FW_OPEN:-}"
return 1
}
# Vorschlaege zum Oeffnen
fw_open_cmds() { # backend port proto [quelle]
local be="$1" port="$2" proto="$3" src="${4:-}" z
case "$be" in
firewalld)
z="$(fw_zones | head -n1)"
if [ -n "$src" ]; then
printf "firewall-cmd --permanent --zone=%s --add-rich-rule='rule family=ipv4 source address=%s port port=%s protocol=%s accept'\n" \
"${z:-public}" "$src" "$port" "$proto"
else
printf 'firewall-cmd --permanent --zone=%s --add-port=%s/%s\n' "${z:-public}" "$port" "$proto"
fi ;;
ufw)
if [ -n "$src" ]; then
printf 'ufw allow from %s to any port %s proto %s\n' "$src" "$port" "$proto"
else
printf 'ufw allow %s/%s\n' "$port" "$proto"
fi ;;
nftables)
if [ -n "$src" ]; then
printf 'nft add rule inet filter input ip saddr %s %s dport %s accept\n' "$src" "$proto" "$port"
else
printf 'nft add rule inet filter input %s dport %s accept\n' "$proto" "$port"
fi ;;
iptables)
if [ -n "$src" ]; then
printf 'iptables -I INPUT -s %s -p %s --dport %s -j ACCEPT\n' "$src" "$proto" "$port"
else
printf 'iptables -I INPUT -p %s --dport %s -j ACCEPT\n' "$proto" "$port"
fi ;;
esac
}
cmd_firewall() {
local sub="${1:-check}"; [ $# -gt 0 ] && shift || true
case "$sub" in check|open) : ;; *) die "Unbekannt: firewall $sub (check|open)" ;; esac
local apply="" src=""
while [ $# -gt 0 ]; do
case "$1" in
--apply) apply=1; shift ;;
--yes|-y) ASSUME_YES=1; shift ;;
--source) src="$2"; shift 2 ;;
*) die "Unbekannte Option fuer 'firewall': $1" ;;
esac
done
local be role; be="$(fw_detect)"
role="$(fw_lc "${FW_ROLE:-single}")"
case "$role" in central|remote) : ;; *) role=single ;; esac
printf '\n%sFirewall%s\n' "$C_BLD" "$C_RST"
case "$be" in
keine)
test_result warn "Keine aktive Firewall erkannt"
printf ' Entweder ist keine eingerichtet, oder die Pruefung braucht
root-Rechte. Mit sudo erneut aufrufen.\n' ;;
*) test_result ok "Erkannt: $be"
if [ "$be" = firewalld ]; then
printf ' Aktive Zonen: %s\n' "$(fw_zones | tr '\n' ' ' | sed 's/ $//')"
fi ;;
esac
case "$role" in
central) printf ' Rolle: Zentrale einer verteilten Ueberwachung\n' ;;
remote) printf ' Rolle: Remote-Site einer verteilten Ueberwachung\n' ;;
esac
_FW_OPEN=""
if [ "$be" != keine ]; then
_FW_OPEN="$(fw_open_ports "$be")"
printf ' Offene Ports: %s\n' "$(printf '%s' "$_FW_OPEN" | tr '\n' ' ' | sed 's/ $//')"
fi
printf '\n%sWas dieser Stack braucht%s\n' "$C_BLD" "$C_RST"
printf ' %-10s %-48s %-7s %s\n' "PORT" "ZWECK" "NOETIG" "ZUSTAND"
local spec zweck need zustand port proto ist fehlend=0
local -a todo=()
while IFS='|' read -r spec zweck need; do
[ -n "$spec" ] || continue
port="${spec%/*}"; proto="${spec##*/}"
ist=nein
if [ "$be" != keine ] && fw_port_open "$port" "$proto"; then ist=ja; fi
case "$need:$ist" in
ja:ja) zustand="${C_GRN}offen${C_RST}" ;;
ja:nein) zustand="${C_RED}GESCHLOSSEN${C_RST}"; fehlend=$((fehlend+1)); todo+=("$spec") ;;
admin:ja) zustand="offen - besser auf das Adminnetz begrenzen" ;;
admin:nein) zustand="geschlossen" ;;
nein:ja) zustand="${C_YEL}offen - sollte zu sein${C_RST}" ;;
nein:nein) zustand="zu (richtig)" ;;
esac
if [ "$be" = keine ]; then zustand="nicht pruefbar"; fi
printf ' %-10s %-48s %-7s %b\n' "$spec" "$zweck" "$need" "$zustand"
done < <(fw_required_ports)
# Hinweise, die sich aus der Konfiguration ergeben
local -a hinweise=()
if [ "$role" = remote ] && ! fw_on "${CMK_LIVESTATUS_TCP:-off}"; then
hinweise+=("Rolle 'remote', aber CMK_LIVESTATUS_TCP=off - dann lauscht auf 6557 nichts.
Einschalten mit: $SELF config set CMK_LIVESTATUS_TCP on (danach 'up')")
fi
if [ "$role" = central ]; then
hinweise+=("Als Zentrale baut diese Site die Verbindungen selbst auf: nach aussen
muessen 6557/tcp und 443/tcp zu den Remote-Sites erlaubt sein. Eingehend
braucht die Zentrale dafuer nichts - ausser dem, was oben steht.")
fi
if [ "${#hinweise[@]}" -gt 0 ]; then
printf '\n%sHinweise%s\n' "$C_BLD" "$C_RST"
local h; for h in "${hinweise[@]}"; do printf ' %s\n' "$h"; done
fi
if [ "$be" = keine ]; then echo; return 0; fi
echo
if [ "$fehlend" -eq 0 ]; then
ok "Alle benoetigten Ports sind offen."
echo; return 0
fi
err "$fehlend benoetigte(r) Port(s) sind geschlossen."
printf '\n%sZum Oeffnen%s\n' "$C_BLD" "$C_RST"
local t
for t in "${todo[@]}"; do
printf ' %s\n' "$(fw_open_cmds "$be" "${t%/*}" "${t##*/}" "$src")"
done
case "$be" in
firewalld) printf ' firewall-cmd --reload\n' ;;
iptables) printf ' # dauerhaft machen: iptables-save bzw. das Paket iptables-persistent\n' ;;
nftables) printf ' # dauerhaft machen: in /etc/nftables.conf uebernehmen\n' ;;
esac
if [ -n "$src" ]; then
case " ${todo[*]} " in
*" 80/tcp "*|*" 443/tcp "*)
printf '\n Achtung: Lets Encrypt prueft die Domain von aussen ueber Port 80.
Wird 80 auf ein Quellnetz begrenzt, schlaegt die Ausstellung fehl.\n' ;;
esac
fi
if [ -n "$apply" ]; then
echo
if [ "$(id -u)" -ne 0 ]; then
die "Dafuer werden root-Rechte benoetigt - bitte mit sudo erneut aufrufen."
fi
confirm "Diese Regeln jetzt setzen?" || die "Abgebrochen."
local c
for t in "${todo[@]}"; do
c="$(fw_open_cmds "$be" "${t%/*}" "${t##*/}" "$src")"
log "$c"
eval "$c" || warn "Fehlgeschlagen: $c"
done
if [ "$be" = firewalld ]; then
firewall-cmd --reload >/dev/null 2>&1 && ok "firewalld neu geladen." \
|| warn "Neuladen fehlgeschlagen."
fi
ok "Regeln gesetzt."
else
printf '\n Automatisch setzen: %s firewall open --apply\n' "$SELF"
printf ' Nur fuer ein Netz : %s firewall open --apply --source 10.0.0.0/24\n' "$SELF"
fi
echo
return 1
}
# =====================================================================
# Selbstpruefung
#
@@ -5393,6 +5836,7 @@ main() {
config) cmd_config "$@" || true ;;
selftest) cmd_selftest ;;
tui-check) cmd_tui_check ;;
firewall) cmd_firewall "$@" ;;
help|-h|--help) usage ;;
*) err "Unbekanntes Kommando: $cmd"; echo; usage; exit 1 ;;
esac
+6 -4
View File
@@ -73,14 +73,16 @@ env_set() {
*$'\n'*) die "Ungueltiger Wert fuer '$key' (mehrzeilig)." ;;
esac
[ -n "$val" ] || [ -n "$allow_empty" ] || die "Leerer Wert fuer '$key' - abgebrochen."
# Werte mit Leerzeichen in Anfuehrungszeichen setzen
# Werte mit Leerzeichen gehoeren in der Datei in Anfuehrungszeichen -
# in der Umgebung aber ohne, sonst stecken die Zeichen spaeter im Wert
local quoted="$val"
case "$val" in
*" "*) case "$val" in \"*\") : ;; *) val="\"$val\"" ;; esac ;;
*" "*) case "$val" in \"*\") : ;; *) quoted="\"$val\"" ;; esac ;;
esac
if grep -qE "^[#[:space:]]*${key}=" "$f"; then
sed -i -E "s|^[#[:space:]]*${key}=.*|${key}=${val}|" "$f"
sed -i -E "s|^[#[:space:]]*${key}=.*|${key}=${quoted}|" "$f"
else
printf '%s=%s\n' "$key" "$val" >>"$f"
printf '%s=%s\n' "$key" "$quoted" >>"$f"
fi
export "$key=$val"
}