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
+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