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) <noreply@anthropic.com>
This commit is contained in:
2026-09-21 00:08:53 +02:00
co-authored by Claude Opus 5
parent 20c773c9c4
commit 4078a9c1a6
3 changed files with 69 additions and 15 deletions
+52 -6
View File
@@ -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.