From 4078a9c1a6133b3ef6bc61c9bbd2140c609bd64e Mon Sep 17 00:00:00 2001 From: duffyduck Date: Mon, 21 Sep 2026 00:08:53 +0200 Subject: [PATCH] Proxy-Umgehung ohne "--noproxy" - die Option ist nicht ueberall da Meldung vom Kundenlaptop: "curl kennt --noproxy nicht". Das war nicht nur ein Hinweis fuer eigene Tests, sondern ein echter Fehler: seit dem Umbau benutzten die eigenen API-Aufrufe genau diese Option. Wo curl sie nicht kennt, scheiterte der Aufruf daran - und zwar mit "Anmeldung fehlgeschlagen", also wieder mit einer Meldung, die woanders hinzeigt. Die Option gibt es erst ab curl 7.19.4, und was auf manchen Rechnern "curl" heisst, ist etwas ganz anderes (unter Windows ein Alias auf Invoke-WebRequest). Deshalb wird der Proxy jetzt umgangen, indem die Umgebungsvariablen fuer den Aufruf entfernt werden - das braucht von curl gar nichts. Nachgemessen: mit gesetztem http_proxy meldet curl danach "Trying 127.0.0.1" statt "Uses proxy env variable". "--noproxy" kommt zusaetzlich dazu, wenn dieses curl es kennt; nur so laesst sich auch ein in ~/.curlrc eingetragener Proxy uebergehen. Die Erkennung laeuft einmal ueber den Hilfetext. Gegen eine curl-Attrappe geprueft, die die Option mit "is unknown" ablehnt: die Erkennung meldet "kennt es nicht", der Aufruf geht trotzdem am Proxy vorbei, und "proxy status" meldet sich mit gesetztem Zwangsproxy erfolgreich an. "noproxy" zeigt jetzt oben, welche curl-Fassung im Einsatz ist und ob sie die Option kennt. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 14 +++++++---- README_en.md | 12 ++++++--- scripts/cmk-manage.sh | 58 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 2dc6668..c21c5d4 100644 --- a/README.md +++ b/README.md @@ -2803,11 +2803,15 @@ große), hängt die lokalen Adressen hinten an und wirft Doppelte heraus: Ein zweiter Aufruf schreibt nichts doppelt. In der Oberfläche liegt das unter **Einstellungen → Runtime und Zeitzone → Lokale Verbindungen prüfen**. -> **Die eigenen Aufrufe dieses Werkzeugs sind davon unabhängig.** Anfragen an -> lokale Adressen laufen grundsätzlich mit `curl --noproxy`, Anfragen ins -> Internet (Registry, Downloadportal) weiterhin über den Proxy. Der Befehl ist -> für alles andere da: eigene `curl`-Tests, der Terminal-Browser, andere -> Skripte. +> **Die eigenen Aufrufe dieses Werkzeugs sind davon unabhängig.** Bei Anfragen +> an lokale Adressen werden die Proxy-Variablen für den Aufruf entfernt – +> bewusst *nicht* über `curl --noproxy`, denn die Option gibt es erst ab curl +> 7.19.4, und was auf manchen Rechnern `curl` heißt, ist etwas ganz anderes. +> Kennt das vorhandene curl die Option, kommt sie zusätzlich dazu; nur so lässt +> sich auch ein in `~/.curlrc` eingetragener Proxy übergehen. Anfragen ins +> Internet (Registry, Downloadportal) laufen weiterhin über den Proxy. Welche +> curl-Fassung im Einsatz ist und ob sie die Option kennt, zeigt `noproxy` +> ganz oben an. > **Kleine Eigenheit von curl:** `no_proxy`/`NO_PROXY` und > `https_proxy`/`HTTPS_PROXY` gelten in beiden Schreibweisen, `HTTP_PROXY` in diff --git a/README_en.md b/README_en.md index 641fe56..c114985 100644 --- a/README_en.md +++ b/README_en.md @@ -2784,10 +2784,14 @@ one), appends the local addresses and drops duplicates: A second call writes nothing twice. The GUI has it under **Einstellungen → Runtime und Zeitzone → Lokale Verbindungen prüfen**. -> **This tool's own calls are unaffected.** Requests to local addresses always -> use `curl --noproxy`, requests to the internet (registry, download portal) -> keep using the proxy. The command exists for everything else: your own `curl` -> tests, the terminal browser, other scripts. +> **This tool's own calls are unaffected.** For requests to local addresses the +> proxy variables are removed for that call – deliberately *not* via +> `curl --noproxy`, because that option only exists from curl 7.19.4 on, and +> what is called `curl` on some machines is something else entirely. If the +> curl at hand knows the option, it is added as well; only that also overrides +> a proxy configured in `~/.curlrc`. Requests to the internet (registry, +> download portal) keep using the proxy. Which curl is in use and whether it +> knows the option is shown at the top of `noproxy`. > **A curl quirk:** `no_proxy`/`NO_PROXY` and `https_proxy`/`HTTPS_PROXY` are > honoured in both spellings, uppercase `HTTP_PROXY` is **not** – curl ignores diff --git a/scripts/cmk-manage.sh b/scripts/cmk-manage.sh index 182d007..f6268e1 100755 --- a/scripts/cmk-manage.sh +++ b/scripts/cmk-manage.sh @@ -1005,9 +1005,39 @@ url_is_local() { # url return 1 } +# curl ohne Proxy aufrufen - ohne sich auf "--noproxy" zu verlassen +# +# Die Option gibt es erst ab curl 7.19.4, und was auf manchen Rechnern +# "curl" heisst, ist etwas ganz anderes (unter Windows z.B. ein Alias +# auf Invoke-WebRequest). Das Entfernen der Umgebungsvariablen wirkt +# genauso und braucht von curl gar nichts - nachgemessen: mit gesetztem +# http_proxy meldet curl danach "Trying 127.0.0.1" statt "Uses proxy env +# variable". +# +# "--noproxy" kommt zusaetzlich dazu, wenn dieses curl es kennt: nur so +# laesst sich auch ein in ~/.curlrc eingetragener Proxy uebergehen. +CURL_HAS_NOPROXY="" + +curl_supports_noproxy() { + if [ -z "$CURL_HAS_NOPROXY" ]; then + local h; h="$( { curl --help all; curl --help; } 2>&1 || true )" + case "$h" in *--noproxy*) CURL_HAS_NOPROXY=yes ;; *) CURL_HAS_NOPROXY=no ;; esac + fi + [ "$CURL_HAS_NOPROXY" = yes ] +} + +curl_noproxy() { # curl-argumente... + local -a extra=() + if curl_supports_noproxy; then extra=(--noproxy '*'); fi + ( + unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY + curl ${extra[@]+"${extra[@]}"} "$@" + ) +} + # Argumente fuer curl, damit eine lokale Anfrage nicht ueber den Proxy geht curl_local_args() { # url - if url_is_local "$1"; then printf -- '--noproxy\n*\n'; fi + if url_is_local "$1" && curl_supports_noproxy; then printf -- '--noproxy\n*\n'; fi } curl_auth() { # user pass curl-argumente... @@ -1026,7 +1056,14 @@ http_code() { # url [user] [pass] [extra-header] if [ -n "$hdr" ]; then a+=(-H "$hdr"); fi local np; while IFS= read -r np; do [ -n "$np" ] && a+=("$np"); done < <(curl_local_args "$url") local code - code="$(curl_auth "$u" "$p" "${a[@]}" "$url" 2>/dev/null)" || code=000 + if url_is_local "$url"; then + # Lokale Ziele grundsaetzlich ohne Proxy - auch dann, wenn dieses + # curl "--noproxy" gar nicht kennt. + code="$( ( unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY + curl_auth "$u" "$p" "${a[@]}" "$url" ) 2>/dev/null )" || code=000 + else + code="$(curl_auth "$u" "$p" "${a[@]}" "$url" 2>/dev/null)" || code=000 + fi printf '%s\n' "${code:-000}" } @@ -3774,7 +3811,7 @@ EOF # es lag, und genau das ist hier der haeufigste Zeitfresser. local body code cerr hdrf rc=0 cerr="$(mktemp)"; hdrf="$(mktemp)" - body="$(curl -sS --max-time 20 --noproxy '*' -w '\n%{http_code}' -D "$hdrf" \ + body="$(curl_noproxy -sS --max-time 20 -w '\n%{http_code}' -D "$hdrf" \ -X POST "$base/api/tokens" \ -H 'Content-Type: application/json' \ -d "{\"identity\":\"$NPM_ADMIN_EMAIL\",\"secret\":\"$NPM_ADMIN_PASSWORD\"}" \ @@ -3939,9 +3976,9 @@ npm_api() { local method="$1" path="$2" data="${3:-}" local base; base="$(npm_api_base)" local -a a=(-sS --max-time 60 -X "$method" -H "Authorization: Bearer $NPM_TOKEN" - --noproxy '*' -w '\n%{http_code}') + -w '\n%{http_code}') [ -n "$data" ] && a+=(-H 'Content-Type: application/json' -d "$data") - local out; out="$(curl "${a[@]}" "$base$path" 2>/dev/null)" || out=$'\n000' + local out; out="$(curl_noproxy "${a[@]}" "$base$path" 2>/dev/null)" || out=$'\n000' NPM_CODE="${out##*$'\n'}" # Wird npm_api in einer Kommandoersetzung aufgerufen - und das ist der # Regelfall, weil die Antwort gebraucht wird -, laeuft sie in einer @@ -3996,7 +4033,7 @@ npm_cert_selfsigned() { # domain fi log "Lade Schluessel und Zertifikat hoch (ID $id) ..." >&2 local up - up="$(curl -sS --max-time 60 --noproxy '*' -X POST "$(npm_api_base)/api/nginx/certificates/$id/upload" \ + up="$(curl_noproxy -sS --max-time 60 -X POST "$(npm_api_base)/api/nginx/certificates/$id/upload" \ -H "Authorization: Bearer $NPM_TOKEN" \ -F "certificate=@$dir/fullchain.pem" \ -F "certificate_key=@$dir/privkey.pem" 2>/dev/null)" || true @@ -8375,6 +8412,15 @@ EOF return 0 fi + printf '\n%sWerkzeug%s\n' "$C_BLD" "$C_RST" + printf ' %s\n' "$(curl --version 2>/dev/null | head -1 | cut -c1-70)" + if curl_supports_noproxy; then + printf ' kennt --noproxy: ja\n' + else + printf ' kennt --noproxy: nein - die Umgehung laeuft dann ueber das + Entfernen der Umgebungsvariablen, das wirkt genauso\n' + 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.