Chyba ProxyError v Requests na súkromnom API? Najprv skontrolujte prostredie
Requests spája nastavenia proxy, overovania a CA z prostredia. Prečítajte si, čo proces vidí, vylúčte súkromného hostiteľa a ponechajte overovanie TLS zapnuté.
VPN beží, interný panel sa v prehliadači otvorí, a skript v Pythone napriek tomu hlási chybu proxy. Na tomto obrázku nie je s tunelom nič zlé: interpret číta adresu proxy zo svojho vlastného prostredia a posiela tam požiadavku. Tento sprievodca číta prostredie, ktoré proces skutočne vidí, uplatní najužšie vylúčenie a až potom zvažuje výslovnú politiku relácie. Každý krok sa končí príkazom, ktorého výstup rozhoduje, či budete pokračovať.
Prečítajte si prostredie, ktoré proces skutočne vidí
Nastavenia proxy na ploche, exporty v shelli a riadky Environment= jednotky systemd sú tri rôzne zdroje a Requests číta len posledný, ktorý zdedí. Spustite diagnostiku nižšie v tom istom shelli, kontajneri alebo jednotke, ktorá spúšťa zlyhávajúci skript, nie vo svojom interaktívnom termináli. Premenná exportovaná v prihlasovacom shelli je pre proces v kontajneri neviditeľná a táto medzera vysvetľuje mnohé hlásenia o proxy, ktorý sa objaví odnikiaľ. Oba príkazy vypisujú tie isté údaje na rôznej úrovni podrobnosti.
env | grep -i -E 'proxy|requests_ca_bundle|curl_ca_bundle'
python3 -c "import os;[print(k,'=',v) for k,v in sorted(os.environ.items()) if 'proxy' in k.lower()]"
Čítajú sa oba zápisy každej premennej a duplicitné položky sa uplatnia v poradí, v akom ich proces prijal, takže zastaraná HTTP_PROXY môže prepísať práve exportovanú hodnotu. Premenné balíka CA tu tiež hrajú rolu, pretože menia, na čo sa verify prekladá, bez toho, aby sa kdekoľvek v kóde objavili. Ak je výstup prázdny, prostredie nie je váš problém a môžete prestať čítať túto časť. Ak uvádza proxy, ktorú nepoznáte, nájdite súbor alebo jednotku, ktorá ju nastavuje, skôr než čokoľvek zmeníte.
Opýtajte sa Requestsu, čo by urobil s konkrétnou URL. Toto volanie zobrazí zlúčené hodnoty proxy, verify a cert pre danú požiadavku bez odoslania paketu.
python3 -c "import requests;s=requests.Session();print(s.merge_environment_settings('https://api.corp.example/status',{},None,None,None))"
Neprázdna položka proxies pre súkromného hostiteľa je vaša odpoveď a vypísaná hodnota verify hovorí, ktorému balíku CA by požiadavka dôverovala. Ak obe vyzerajú správne, porucha je ďalej v zásobníku a mali by ste prejsť na časť o overovaní. Nehádajte z kódu: zlučovanie prebieha pre každú požiadavku, preto sa jedna relácia môže správať inak pre dvoch hostiteľov.
Vylúčte súkromného hostiteľa, skôr než čokoľvek vypnete
Keď je proxy naozaj potrebná pre iné ciele, úzkym riešením je vylúčenie tohto hostiteľa. Pridávajte do existujúceho zoznamu namiesto jeho nahradenia, pretože vymazanie NO_PROXY pokazí každý ďalší interný cieľ, ktorý sa naň spoliehal. Príkazy nižšie položku pridajú a potom sa Requestsu opýtajú, či sa obchádzanie uplatní.
export NO_PROXY="${NO_PROXY:+$NO_PROXY,}api.corp.example,.corp.example"
python3 -c "import requests;print(requests.utils.should_bypass_proxies('https://api.corp.example/status',None))"
Zhoda je podľa prípony hostiteľa, takže .corp.example pokrýva celú doménu, zatiaľ čo api.corp.example jedno meno. Samotná hviezdička vypne proxy pre každého hostiteľa a takmer nikdy to nie je to, čo produkčná úloha chce. Či sa položka CIDR bude rešpektovať, závisí od verzií Requestsu a urllib3 v obraze, preto otestujte presnú položku, namiesto toho, aby ste predpokladali, že funguje. Skontrolujte výsledok should_bypass_proxies pre skutočnú URL, nie pre názov hostiteľa napísaný z pamäti.
Držte obe vrstvy v hlave oddelené. Obchádzanie HTTP proxy neobchádza VPN, pretože rozhodnutie o proxy sa deje v knižnici a rozhodnutie o tuneli v smerovacej tabuľke jadra.
Vypínajte trust_env len ako zámernú politiku relácie
Ak má celá úloha ignorovať konfiguráciu okolia, zostavte reláciu explicitne a rozhodnutie zaznamenajte v kóde. To je politika, nie obchvat, a patrí do diffu, ktorý recenzent uvidí. Príklad nižšie zachováva časový limit, explicitnú cestu k CA a kontrolu stavu.
import requests
with requests.Session() as session:
session.trust_env = False
response = session.get(
"https://api.corp.example/status",
timeout=(5, 20),
verify="/etc/ssl/certs/corp-ca.pem",
)
response.raise_for_status()
Vypnutie trust_env mení tri správania naraz a len jedno z nich sa týka proxy. Requests prestane čítať prihlasovacie údaje z .netrc a premenné REQUESTS_CA_BUNDLE a CURL_CA_BUNDLE prestanú ovplyvňovať verify, ktorý sa potom vráti k vstavanému úložisku certifikátov. Ak vaša organizácia ukončuje TLS vlastnou CA, toto vrátenie vyvolá chybu overenia, ktorá vyzerá nesúvisiaca s práve vykonanou zmenou. Práve výslovné odovzdanie verify drží oba efekty oddelené.
Čo by ste robiť nemali, je nastaviť verify=False, aby ste výslednú chybu utíšili. To vymení nesprávnu konfiguráciu proxy za neoverené spojenie a skryje problém s certifikátom, ktorý malo vylúčenie odhaliť.
Overte zlyhávajúcu vrstvu a ponechajte si možnosť vrátenia
Tri poruchy vyzerajú v logu rovnako a nemajú nič spoločné: proxy, ktorá nedosiahne cieľ, vyvolá ProxyError alebo vráti 502, problém s dôverou vyvolá SSLError a odmietnutie aplikácie vráti 401 alebo 403. Reprodukujte požiadavku mimo Requestsu, aby ste zistili, ktorú máte. Príkazy nižšie odstránia proxy, otestujú reťaz certifikátov a potom volanie zopakujú cez knižnicu.
curl -sv --noproxy '*' https://api.corp.example/status -o /dev/null
openssl s_client -connect api.corp.example:443 -servername api.corp.example </dev/null
python3 -c "import requests;r=requests.get('https://api.corp.example/status',timeout=10);print(r.status_code)"
Ak volanie curl uspeje a volanie v Pythone zlyhá, rozdielom je stále prostredie. Ak obe zlyhajú vo fáze TLS, proxy nikdy nebola problémom a problémom je reťaz certifikátov. Ak obe vrátia 401, požiadavka sa dostala do aplikácie a zostávajúcou prácou je autentizácia. Zaznamenanie, ktorú z troch ste pozorovali, ušetrí ďalšiemu človeku hodinu.
Vrátenie je jeden riadok oboma smermi: odstráňte vylúčenie alebo prepnite trust_env späť. Uložte predchádzajúcu hodnotu NO_PROXY, skôr než k nej niečo pridáte, a uprednostnite obalový skript alebo položku Environment= na úrovni jednotky pred exportom, ktorý žije len v histórii vášho terminálu. Obe zmeny sú viditeľné v prostredí procesu, takže reštart vás zvyčajne vráti k starému správaniu.
Skončite potvrdením štyroch vecí: zlúčené nastavenia pre súkromnú URL neukazujú žiadnu proxy, certifikát sa overuje proti zamýšľanej CA, požiadavka vracia stav, ktorý očakávate, a zmena je commitnutá na mieste, ktoré sa dá reprodukovať. Zelený skript s nevysvetleným prostredím je oprava, ktorá sa na ďalšom stroji znova pokazí. Príkazy v tomto sprievodcovi sú tie, ktoré vložíte do tiketu.