noproxy: sofort wirksam machen, und Ziele fuer Dienste

Zwei Luecken im vorherigen Stand.

Erstens war der Eintrag erst in einer neuen Sitzung wirksam. Ein
Programm kann die Umgebung seiner Elternshell nicht aendern - dafuer
gibt es jetzt "noproxy --export", das nur die beiden Zeilen ausgibt:

  eval "$(cmk-manage.sh noproxy --export)"

Danach gilt es sofort; nachgemessen mit curl -v (vorher "Uses proxy env
variable http_proxy", danach "Trying 127.0.0.1"). Der Wert wird dabei
aus denselben Regeln gebildet wie beim Schreiben in eine Datei -
Vorhandenes zuerst, unsere Adressen dahinter, ohne Doppelte.

Zweitens lesen Systemdienste weder profile.d noch .bashrc noch
/etc/environment. Dafuer gibt es zwei weitere Ziele:

  noproxy --fix --environment   ergaenzt /etc/environment, ohne die
                                uebrigen Zeilen anzuruehren
  noproxy --fix --service       schreibt eine Ergaenzung der systemd-Unit
                                des Stacks; der Proxy selbst kommt mit
                                hinein, sonst kaeme der Dienst beim Holen
                                von Images nicht mehr ins Internet

Findet sich keine passende Unit, zeigt der Befehl den Abschnitt zum
Einfuegen von Hand. Die Schreibpfade sind ueber NOPROXY_ENV_FILE und
NOPROXY_UNIT_DIR ueberschreibbar - damit liessen sie sich pruefen, ohne
/etc dieses Rechners anzufassen.

In der Oberflaeche stehen alle vier Ziele zur Auswahl, dazu der
Menuepunkt fuer die laufende Sitzung, der den eval-Befehl zum Kopieren
zeigt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-20 23:20:56 +02:00
co-authored by Claude Opus 5
parent 467796e23a
commit 20eceda183
3 changed files with 223 additions and 32 deletions
+34 -6
View File
@@ -2569,6 +2569,7 @@ Eine Dateiauswahl mit Verzeichnisnavigation ist eingebaut.
| `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 |
| `noproxy [--export\|--fix]` | prüfen, ob lokale Adressen am HTTP-Proxy vorbeigehen; eintragen in profile.d, `.bashrc`, `/etc/environment` oder die systemd-Unit |
Globale Optionen: `--env-file DATEI`, `-y/--yes` (keine Rückfragen, z. B. für
Cronjobs), `-v/--verbose`.
@@ -2664,13 +2665,40 @@ Erkannt wird das nicht geraten, sondern an dem, was `curl -v` selbst sagt
(`Uses proxy env variable http_proxy == …`) – dafür muss auf der Zieladresse
nichts laufen.
Dauerhaft eintragen:
**In der laufenden Sitzung** – ein Programm kann die Umgebung seiner Elternshell
nicht ändern, deshalb der Umweg über `eval`:
```bash
sudo ./scripts/cmk-manage.sh noproxy --fix # /etc/profile.d/cmk-noproxy.sh
./scripts/cmk-manage.sh noproxy --fix --user # ~/.bashrc
eval "$(./scripts/cmk-manage.sh noproxy --export)"
```
**Dauerhaft** – die Ziele schließen einander nicht aus, je nach Rechner braucht
es mehrere:
| Befehl | wirkt für |
|---|---|
| `sudo … noproxy --fix` | Anmeldeshells (`/etc/profile.d/cmk-noproxy.sh`) |
| `… noproxy --fix --user` | nur diesen Benutzer (`~/.bashrc`) |
| `sudo … noproxy --fix --environment` | Anmeldungen ohne Shell (`/etc/environment`) |
| `sudo … noproxy --fix --service` | **Systemdienste** – Ergänzung der systemd-Unit |
Der letzte Punkt ist der, den man leicht übersieht: **Systemdienste lesen weder
`profile.d` noch `.bashrc` noch `/etc/environment`.** Läuft der Stack über
systemd, schreibt `--service` eine Ergänzung nach
`/etc/systemd/system/checkmk-stack.service.d/cmk-noproxy.conf`:
```ini
[Service]
Environment=no_proxy=localhost,127.0.0.1,::1,checkmk-host,172.0.250.82
Environment=NO_PROXY=localhost,127.0.0.1,::1,checkmk-host,172.0.250.82
Environment=http_proxy=http://proxy.kunde.local:3128
Environment=https_proxy=http://proxy.kunde.local:3128
```
Der Proxy selbst kommt dabei mit hinein – ohne ihn käme der Dienst beim Holen
von Images nicht ins Internet. Gibt es keine passende Unit, zeigt der Befehl
den Abschnitt zum Einfügen von Hand.
**Was schon dasteht, bleibt – und zwar vorn.** Der Eintrag sammelt beide
Schreibweisen ein (`no_proxy` *und* `NO_PROXY`; manche Systeme setzen nur die
große), hängt die lokalen Adressen hinten an und wirft Doppelte heraus:
@@ -2698,9 +2726,9 @@ Ein zweiter Aufruf schreibt nichts doppelt. In der Oberfläche liegt das unter
> CGI-Umgebungen eine eingehende Kopfzeile `Proxy:` sie setzen könnte. Der
> Bericht weist darauf hin, wenn nur diese gesetzt ist.
> **Dienste lesen keine Profildateien.** Läuft der Stack über systemd und steht
> dort ein Proxy, gehört die Ausnahme zusätzlich nach `/etc/environment` oder
> in die Unit: `Environment=no_proxy=localhost,127.0.0.1,…`
> **Reihenfolge:** Erst `noproxy` zum Nachsehen, dann eintragen, dann mit
> `eval "$(… noproxy --export)"` in der laufenden Sitzung wirksam machen –
> sonst wundert man sich, warum sich nichts ändert.
---
+34 -6
View File
@@ -2551,6 +2551,7 @@ A file chooser with directory navigation is built in.
| `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 |
| `noproxy [--export\|--fix]` | check whether local addresses bypass the HTTP proxy; write it to profile.d, `.bashrc`, `/etc/environment` or the systemd unit |
Global options: `--env-file FILE`, `-y/--yes` (no prompts, e.g. for cron jobs),
`-v/--verbose`.
@@ -2648,13 +2649,40 @@ This is not guessed but read from what `curl -v` reports itself
(`Uses proxy env variable http_proxy == …`) – nothing needs to be listening on
the target address for that.
To make it permanent:
**In the running session** – a program cannot change its parent shell's
environment, hence the detour via `eval`:
```bash
sudo ./scripts/cmk-manage.sh noproxy --fix # /etc/profile.d/cmk-noproxy.sh
./scripts/cmk-manage.sh noproxy --fix --user # ~/.bashrc
eval "$(./scripts/cmk-manage.sh noproxy --export)"
```
**Permanently** – the targets are not mutually exclusive; depending on the
machine you need several:
| Command | takes effect for |
|---|---|
| `sudo … noproxy --fix` | login shells (`/etc/profile.d/cmk-noproxy.sh`) |
| `… noproxy --fix --user` | this user only (`~/.bashrc`) |
| `sudo … noproxy --fix --environment` | logins without a shell (`/etc/environment`) |
| `sudo … noproxy --fix --service` | **system services** – systemd unit drop-in |
The last one is easily overlooked: **system services read neither `profile.d`
nor `.bashrc` nor `/etc/environment`.** If the stack runs under systemd,
`--service` writes a drop-in to
`/etc/systemd/system/checkmk-stack.service.d/cmk-noproxy.conf`:
```ini
[Service]
Environment=no_proxy=localhost,127.0.0.1,::1,checkmk-host,172.0.250.82
Environment=NO_PROXY=localhost,127.0.0.1,::1,checkmk-host,172.0.250.82
Environment=http_proxy=http://proxy.customer.local:3128
Environment=https_proxy=http://proxy.customer.local:3128
```
The proxy itself is carried over – without it the service could not reach the
internet to pull images. If no matching unit exists, the command prints the
section to paste by hand.
**Whatever is already there stays – and stays first.** The entry collects both
spellings (`no_proxy` *and* `NO_PROXY`; some systems only set the uppercase
one), appends the local addresses and drops duplicates:
@@ -2680,9 +2708,9 @@ Runtime und Zeitzone → Lokale Verbindungen prüfen**.
> it deliberately, because in CGI environments an incoming `Proxy:` header
> could set it. The report points this out when only that one is set.
> **Services do not read profile files.** If the stack runs under systemd and a
> proxy is configured there, the exception also belongs in `/etc/environment`
> or in the unit: `Environment=no_proxy=localhost,127.0.0.1,…`
> **Order of operations:** first `noproxy` to look, then write it, then apply it
> to the running session with `eval "$(… noproxy --export)"` – otherwise you
> will wonder why nothing changed.
---
+155 -20
View File
@@ -7191,17 +7191,39 @@ Die Ausnahme jetzt dauerhaft eintragen?" || return 0
local sel
sel="$(ui_menu "Wohin eintragen?" \
"Fuer alle Benutzer braucht es root-Rechte. Dienste (systemd, cron)
lesen weder das eine noch das andere - dort gehoert die Ausnahme in
die Unit bzw. nach /etc/environment." \
system "Fuer alle: /etc/profile.d/cmk-noproxy.sh" \
user "Nur fuer mich: ~/.bashrc" \
back "zurueck")" || return 0
case "$sel" in back) return 0 ;; esac
"Die Ziele schliessen einander nicht aus - je nachdem, was auf diesem
Rechner laeuft, braucht es mehrere.
Anmeldeshells lesen profile.d und .bashrc, Anmeldungen ohne Shell die
Datei /etc/environment, und Systemdienste lesen NICHTS davon - fuer die
gibt es die Ergaenzung der Unit." \
system "Anmeldeshells: /etc/profile.d/cmk-noproxy.sh (root)" \
user "Nur fuer mich: ~/.bashrc" \
environment "Anmeldungen ohne Shell: /etc/environment (root)" \
service "Systemdienste: Ergaenzung der Unit (root)" \
jetzt "Nur in dieser Sitzung - Befehl zum Kopieren zeigen" \
back "zurueck")" || return 0
case "$sel" in
back) return 0 ;;
jetzt) local ex; ex="$( ( NO_COLOR=1 cmd_noproxy --export ) 2>/dev/null )"
ui_msg "Sofort setzen" "Ein Programm kann die Umgebung seiner Elternshell nicht
aendern. In der laufenden Shell hilft deshalb:
eval \"\$($SELF noproxy --export)\"
Das setzt:
$ex"
return 0 ;;
esac
local -a a=(noproxy --fix)
case "$sel" in
user) a+=(--user) ;;
environment) a+=(--environment) ;;
service) a+=(--service) ;;
esac
if [ "$sel" = user ]; then
a+=(--user)
local f2; f2="$(mktemp)"
( NO_COLOR=1 cmd_noproxy --fix --user ) >"$f2" 2>&1 || true
ui_text "Eingetragen" "$f2"; rm -f "$f2"
@@ -8116,7 +8138,11 @@ cmd_firewall() {
# stimmen. Genau das prueft und richtet dieser Befehl ein.
# =====================================================================
NOPROXY_FILE="/etc/profile.d/cmk-noproxy.sh"
NOPROXY_FILE="${NOPROXY_FILE:-/etc/profile.d/cmk-noproxy.sh}"
# Ueberschreibbar, damit sich die Schreibwege pruefen lassen, ohne /etc
# dieses Rechners anzufassen.
NOPROXY_ENV_FILE="${NOPROXY_ENV_FILE:-/etc/environment}"
NOPROXY_UNIT_DIR="${NOPROXY_UNIT_DIR:-/etc/systemd/system}"
# Welche Adressen gehoeren in no_proxy?
noproxy_list() {
@@ -8129,6 +8155,21 @@ noproxy_list() {
printf '%s' "$l"
}
# Vorhandenes zuerst, dann unsere Adressen, ohne Doppelte
noproxy_merge() { # alt-klein alt-gross
local all e out=""
all="$1"
if [ -n "${2:-}" ]; then all="${all:+${all},}$2"; fi
all="${all:+${all},}$(noproxy_list)"
for e in $(printf '%s' "$all" | tr ',' ' '); do
case ",$out," in
*",$e,"*) ;;
*) out="${out:+${out},}$e" ;;
esac
done
printf '%s' "$out"
}
# Wuerde curl fuer diese Adresse den Proxy benutzen?
noproxy_would_use_proxy() { # url
local out
@@ -8140,20 +8181,34 @@ noproxy_would_use_proxy() { # url
}
cmd_noproxy() {
local fix="" scope=system
local fix="" scope=system export_only=""
while [ $# -gt 0 ]; do
case "$1" in
--fix) fix=1; shift ;;
--user) scope=user; shift ;;
--fix) fix=1; shift ;;
--export) export_only=1; shift ;;
--user) scope=user; shift ;;
--system) scope=system; shift ;;
--environment) scope=environment; shift ;;
--service) scope=service; shift ;;
--help|-h)
cat <<EOF
Pruefen, ob lokale Adressen am HTTP-Proxy vorbeigehen.
$SELF noproxy nachsehen
sudo $SELF noproxy --fix dauerhaft eintragen ($NOPROXY_FILE)
$SELF noproxy --fix --user nur fuer den eigenen Benutzer (~/.bashrc)
$SELF noproxy nachsehen
eval "\$($SELF noproxy --export)" sofort in DIESER Sitzung setzen
Dauerhaft eintragen - die Ziele schliessen einander nicht aus:
sudo $SELF noproxy --fix Anmeldeshells ($NOPROXY_FILE)
$SELF noproxy --fix --user nur dieser Benutzer (~/.bashrc)
sudo $SELF noproxy --fix --environment /etc/environment (auch fuer
Anmeldungen ohne Shell)
sudo $SELF noproxy --fix --service systemd-Unit des Stacks
(Dienste lesen die Dateien oben
NICHT)
Ein Programm kann die Umgebung seiner Elternshell nicht aendern -
deshalb der Umweg ueber "eval" fuer das Sofort-Setzen.
Steht in der Umgebung ein HTTP-Proxy und nimmt no_proxy die lokalen
Adressen nicht aus, laufen selbst Anfragen an 127.0.0.1 ueber ihn. Der
@@ -8167,6 +8222,13 @@ EOF
local url="http://127.0.0.1:${NPM_ADMIN_PORT:-81}/"
# Nur die Zeilen zum Auswerten - fuer: eval "$(... noproxy --export)"
if [ -n "$export_only" ]; then
local merged; merged="$(noproxy_merge "${no_proxy:-}" "${NO_PROXY:-}")"
printf "export no_proxy='%s' NO_PROXY='%s'\n" "$merged" "$merged"
return 0
fi
printf '\n%sHTTP-Proxy in der Umgebung%s\n' "$C_BLD" "$C_RST"
# HTTP_PROXY in Grossschreibung beachtet curl absichtlich NICHT - eine
# Kopfzeile "Proxy:" wuerde sie in CGI-Umgebungen sonst setzen koennen.
@@ -8223,6 +8285,77 @@ EOF
return 1
fi
# --- /etc/environment ---------------------------------------------
# Keine Shell-Datei: schlichte KEY=WERT-Zeilen, von PAM gelesen. Der
# Wert muss deshalb hier fertig zusammengesetzt werden.
if [ "$scope" = environment ]; then
local ef="$NOPROXY_ENV_FILE"
[ "$(id -u)" -eq 0 ] || die "Zum Schreiben von $ef werden root-Rechte benoetigt."
local alt_k alt_g merged
alt_k="$(sed -n 's/^no_proxy=//p' "$ef" 2>/dev/null | tail -1 | tr -d '"')"
alt_g="$(sed -n 's/^NO_PROXY=//p' "$ef" 2>/dev/null | tail -1 | tr -d '"')"
merged="$(noproxy_merge "${alt_k:-${no_proxy:-}}" "${alt_g:-${NO_PROXY:-}}")"
local t2; t2="$(mktemp)"
{ grep -vE '^(no_proxy|NO_PROXY)=' "$ef" 2>/dev/null || true
printf 'no_proxy="%s"\n' "$merged"
printf 'NO_PROXY="%s"\n' "$merged"
} >"$t2"
install -m 0644 "$t2" "$ef"; rm -f "$t2"
ok "Eingetragen in $ef"
log "Gilt fuer neue Anmeldungen. Systemdienste lesen diese Datei NICHT -
dafuer: $SELF noproxy --fix --service"
return 0
fi
# --- systemd-Unit des Stacks --------------------------------------
if [ "$scope" = service ]; then
[ "$(id -u)" -eq 0 ] || die "Zum Schreiben einer Unit-Ergaenzung werden root-Rechte benoetigt."
command -v systemctl >/dev/null 2>&1 || die "systemd ist hier nicht im Einsatz."
local merged; merged="$(noproxy_merge "${no_proxy:-}" "${NO_PROXY:-}")"
local -a units=() u
local lst
lst="$(systemctl list-unit-files --no-legend 2>/dev/null || true)"
for u in checkmk-stack.service checkmk.service nginx-proxy-manager.service; do
case "$lst" in
"$u"*|*"
$u"*) units+=("$u") ;;
esac
done
if [ "${#units[@]}" -eq 0 ]; then
err "Keine Unit des Stacks gefunden."
printf ' Angelegt werden sie von: ./install.sh --with-systemd bzw. --quadlet
Von Hand waere es eine Ergaenzung mit diesem Inhalt:
[Service]
Environment=no_proxy=%s
Environment=NO_PROXY=%s
\n' "$merged" "$merged" >&2
return 1
fi
for u in "${units[@]}"; do
local d="$NOPROXY_UNIT_DIR/$u.d"
mkdir -p "$d"
{
printf '# Lokale Adressen nicht ueber den HTTP-Proxy leiten.\n'
printf '# Erzeugt von cmk-manage.sh noproxy --fix --service\n'
printf '[Service]\n'
printf 'Environment=no_proxy=%s\n' "$merged"
printf 'Environment=NO_PROXY=%s\n' "$merged"
# Der Proxy selbst gehoert mit hinein: ohne ihn kommt der
# Dienst beim Holen von Images nicht ins Internet.
if [ -n "${http_proxy:-}" ]; then printf 'Environment=http_proxy=%s\n' "$http_proxy"; fi
if [ -n "${https_proxy:-}" ]; then printf 'Environment=https_proxy=%s\n' "$https_proxy"; fi
if [ -n "${https_proxy:-}" ]; then printf 'Environment=HTTPS_PROXY=%s\n' "$https_proxy"; fi
} > "$d/cmk-noproxy.conf"
ok "Ergaenzung geschrieben: $d/cmk-noproxy.conf"
done
if [ "$NOPROXY_UNIT_DIR" = /etc/systemd/system ]; then
systemctl daemon-reload && ok "systemd hat die Units neu eingelesen."
fi
log "Wirksam beim naechsten Start der Unit: systemctl restart ${units[0]}"
return 0
fi
local target
if [ "$scope" = user ]; then
target="$HOME/.bashrc"
@@ -8280,15 +8413,17 @@ EOF
ok "Eingetragen in $target"
log "Vorhandene Eintraege bleiben erhalten und stehen vorn - ergaenzt wird
nur, was fehlt (beide Schreibweisen, no_proxy und NO_PROXY)."
log "Wirksam in neuen Sitzungen. Sofort:
log "Wirksam in neuen Sitzungen. In DIESER Sitzung sofort:
eval \"\$($SELF noproxy --export)\"
(ein Programm kann die Umgebung seiner Elternshell nicht aendern)"
log "Alter Weg, gleichwertig:
export no_proxy='$liste' NO_PROXY='$liste'"
cat <<EOF
${C_BLD}Was damit NICHT erledigt ist${C_RST}
Dienste lesen keine Profildateien. Laeuft der Stack ueber systemd und
steht dort ein Proxy, gehoert die Ausnahme zusaetzlich nach
/etc/environment oder in eine Unit-Datei:
Environment=no_proxy=$liste
Dienste lesen keine Profildateien. Dafuer gibt es zwei weitere Ziele:
sudo $SELF noproxy --fix --environment /etc/environment
sudo $SELF noproxy --fix --service Ergaenzung der systemd-Unit
EOF
return 0