Gabim ProxyError i Requests në një API private? Kontrollo më parë mjedisin
Requests bashkon cilësimet e proxy-t, autentikimit dhe CA-së nga mjedisi. Lexo çfarë sheh procesi, përjashto hostin privat dhe mbaj verifikimin TLS të aktivizuar.
VPN-ja është aktive, paneli i brendshëm hapet në shfletues, dhe skripti Python vazhdon të nxjerrë një gabim proxy. Në atë pamje nuk ka asgjë të gabuar me tunelin: interpretuesi lexon një adresë proxy nga mjedisi i vet dhe e dërgon kërkesën atje. Ky manual lexon mjedisin që procesi sheh vërtet, zbaton përjashtimin më të ngushtë dhe vetëm pas kësaj shqyrton një politikë sesioni të qartë. Çdo hap përfundon me një komandë, dalja e së cilës vendos nëse vazhdon.
Lexo mjedisin që procesi sheh vërtet
Cilësimet e proxy-t të desktopit, eksportet e shell-it dhe rreshtat Environment= të një njësie systemd janë tre burime të ndryshme, dhe Requests lexon vetëm të fundit që trashëgon. Ekzekuto diagnostikimin më poshtë në të njëjtin shell, kontejner ose njësi që ekzekuton skriptin që dështon, jo në terminalin tënd interaktiv. Një ndryshore e eksportuar në shell-in e hyrjes është e padukshme për një proces kontejneri, dhe ai boshllëk shpjegon shumë raportime për një proxy që shfaqet nga asgjëja. Të dy komandat shtypin të njëjtat të dhëna në nivele të ndryshme detajesh.
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()]"
Lexohen të dyja shkrimet e çdo ndryshoreje, dhe hyrjet e dyfishta zbatohen sipas rendit në të cilin procesi i mori, kështu që një HTTP_PROXY i vjetëruar mund të mbivendosë vlerën që sapo eksportove. Ndryshoret e paketës CA kanë rëndësi edhe këtu, sepse ndryshojnë se në çfarë zgjidhet verify pa u shfaqur askund në kod. Nëse dalja është bosh, mjedisi nuk është problemi yt dhe mund të ndalosh së lexuari këtë seksion. Nëse rendit një proxy që nuk e njeh, gjej skedarin ose njësinë që e vendos përpara se të ndryshosh ndonjë gjë.
Pyet Requests se çfarë do të bënte me një URL të caktuar. Ky thirrje tregon vlerat e bashkuara të proxy, verify dhe cert për atë kërkesë pa dërguar një paketë.
python3 -c "import requests;s=requests.Session();print(s.merge_environment_settings('https://api.corp.example/status',{},None,None,None))"
Një hyrje proxies jo bosh për hostin privat është përgjigja jote, dhe vlera verify e shtypur të tregon se cilës paketë CA do t'i besonte kërkesa. Nëse të dyja duken të sakta, defekti është më tej në stack dhe duhet të kalosh në seksionin e verifikimit. Mos hamendëso nga kodi: bashkimi ndodh për çdo kërkesë, prandaj një sesion mund të sillet ndryshe për dy hoste.
Përjashto hostin privat përpara se të çaktivizosh ndonjë gjë
Kur proxy-t i duhet vërtet për destinacione të tjera, rregullimi i ngushtë është një përjashtim për këtë host. Shto në listën ekzistuese në vend që ta zëvendësosh, sepse fshirja e NO_PROXY prish çdo destinacion tjetër të brendshëm që mbështetej tek ai. Komandat më poshtë shtojnë hyrjen dhe pastaj pyesin Requests nëse anashkalimi zbatohet.
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))"
Përputhja bëhet sipas prapashtesës së hostit, kështu që .corp.example mbulon të gjithë domenin ndërsa api.corp.example mbulon një emër të vetëm. Një yll i pastër çaktivizon proxy-n për çdo host dhe pothuajse kurrë nuk është ajo që kërkon një punë prodhimi. Nëse një hyrje CIDR respektohet varet nga versionet e Requests dhe urllib3 në imazh, prandaj testo hyrjen e saktë në vend që të supozosh se funksionon. Kontrollo rezultatin e should_bypass_proxies për URL-në reale, jo për një emër hosti të shkruar nga kujtesa.
Mbaji dy shtresat të ndara në mendje. Anashkalimi i proxy-t HTTP nuk anashkalon VPN-në, sepse vendimi për proxy-n merret në bibliotekë dhe vendimi për tunelin në tabelën e rrugëtimit të kernelit.
Çaktivizo trust_env vetëm si politikë sesioni e qëllimshme
Nëse e gjithë puna duhet të injorojë konfigurimin e mjedisit, ndërto sesionin në mënyrë eksplicite dhe regjistro vendimin në kod. Kjo është një politikë, jo një anashkalim, dhe i përket një diff që një rishikues mund ta shohë. Shembulli më poshtë mban një afat kohor, një rrugë CA eksplicite dhe një kontroll statusi.
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()
Çaktivizimi i trust_env ndryshon tre sjellje njëherësh, dhe vetëm njëra prej tyre ka të bëjë me proxy-t. Requests ndalon së lexuari kredencialet .netrc, dhe ndryshoret REQUESTS_CA_BUNDLE dhe CURL_CA_BUNDLE ndalojnë së ndikuari verify, i cili atëherë kthehet te depoja e certifikatave e përfshirë. Nëse organizata jote përfundon TLS me CA-në e vet, ajo kthim prodhon një gabim verifikimi që duket i palidhur me ndryshimin që sapo bëre. Është kalimi eksplicit i verify ai që i mban dy efektet të ndara.
Ajo që nuk duhet të bësh është të vendosësh verify=False për të heshtur gabimin që rezulton. Kjo shkëmben një konfigurim të gabuar proxy me një lidhje të paverifikuar, dhe fsheh problemin e certifikatës që përjashtimi duhej të zbulonte.
Verifiko shtresën që dështon dhe mbaj një mundësi kthimi
Tre dështime duken njësoj në një regjistër dhe nuk kanë asgjë të përbashkët: një proxy që nuk arrin destinacionin hedh ProxyError ose kthen 502, një problem besimi hedh SSLError, dhe një refuzim i aplikacionit kthen 401 ose 403. Riprodho kërkesën jashtë Requests për të parë cilën ke. Komandat më poshtë heqin proxy-n, testojnë zinxhirin e certifikatave dhe pastaj përsërisin thirrjen përmes bibliotekës.
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)"
Nëse thirrja curl ka sukses dhe thirrja Python dështon, mjedisi është ende diferenca. Nëse të dyja dështojnë në fazën TLS, proxy-ja nuk ishte kurrë problemi dhe zinxhiri i certifikatave është. Nëse të dyja kthejnë 401, kërkesa arriti aplikacionin dhe puna e mbetur është autentikimi. Regjistrimi i cilës prej treve vëzhgove i kursen një ore personit tjetër.
Kthimi është një rresht në të dy drejtimet: hiq përjashtimin ose kthe trust_env mbrapsht. Ruaj vlerën e mëparshme të NO_PROXY përpara se të shtosh diçka, dhe prefero një skript mbështjellës ose një hyrje Environment= në nivel njësie në vend të një eksporti që jeton vetëm në historikun e terminalit tënd. Të dy ndryshimet janë të dukshme në mjedisin e procesit, kështu që një rindezje zakonisht të kthen te sjellja e vjetër.
Përfundo duke konfirmuar katër gjëra: cilësimet e bashkuara për URL-në private nuk tregojnë asnjë proxy, certifikata verifikohet kundrejt CA-së së synuar, kërkesa kthen statusin që pret, dhe ndryshimi është kryer në një vend që mund të riprodhohet. Një skript i gjelbër me një mjedis të pashpjeguar është një rregullim që prishet përsëri në makinën tjetër. Komandat në këtë manual janë ato që duhen ngjitur në tiketë.