La VPN funkcias, la interna panelo malfermiĝas en retumilo, kaj la Python-skripto ankoraŭ ĵetas proksian eraron. En tiu bildo nenio misas ĉe la tunelo: la interpretilo legas proksian adreson el sia propra medio kaj sendas la peton tien. Ĉi tiu gvidilo legas la medion, kiun la procezo efektive vidas, aplikas la plej mallarĝan ekskludon kaj nur poste konsideras eksplicitan seanpolitikon. Ĉiu paŝo finiĝas per komando, kies eligo decidas ĉu vi daŭrigu.

Legu la medion, kiun la procezo efektive vidas

Proksiaj agordoj de la labortablo, ŝelaj eksportoj kaj la linioj Environment= de systemd-unuo estas tri malsamaj fontoj, kaj Requests legas nur la lastan, kiun ĝi heredas. Rulu la diagnozon sube en la sama ŝelo, ujo aŭ unuo, kiu rulas la fiaskantan skripton, ne en via interaga terminalo. Variablo eksportita en via ensaluta ŝelo estas nevidebla por uja procezo, kaj tiu breĉo klarigas multajn raportojn pri proksio aperanta el nenie. La du komandoj presas la samajn datumojn je malsamaj niveloj de detalo.

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()]"

Legiĝas ambaŭ literumoj de ĉiu variablo, kaj duplikaj enskriboj aplikiĝas laŭ la ordo, en kiu la procezo ricevis ilin, do malnova HTTP_PROXY povas superregi la valoron, kiun vi ĵus eksportis. La CA-faskaj variabloj gravas ankaŭ ĉi tie, ĉar ili ŝanĝas al kio verify solviĝas sen aperi ie ajn en la kodo. Se la eligo estas malplena, la medio ne estas via problemo kaj vi povas ĉesi legi ĉi tiun sekcion. Se ĝi listigas proksion, kiun vi ne rekonas, trovu la dosieron aŭ union, kiu agordas ĝin, antaŭ ol vi ŝanĝos ion ajn.

Demandu al Requests, kion ĝi farus kun specifa URL. Ĉi tiu voko montras la kunfanditajn proksiajn, verify kaj cert valorojn por tiu peto sen sendi paketon.

python3 -c "import requests;s=requests.Session();print(s.merge_environment_settings('https://api.corp.example/status',{},None,None,None))"

Ne-malplena proxies-enskribo por la privata gastiganto estas via respondo, kaj la presita verify-valoro diras, kiun CA-faskon la peto fidus. Se ambaŭ aspektas ĝustaj, la fiasko estas pli poste en la stako kaj vi devus salti al la kontrolsekcio. Ne konjektu el la kodo: la kunfando okazas por ĉiu peto, tial unu seanco povas konduti malsame por du gastigantoj.

Ekskludu la privatan gastiganton antaŭ ol vi malŝaltos ion ajn

Kiam la proksio vere necesas por aliaj celoj, la mallarĝa ripeto estas ekskludo por ĉi tiu gastiganto. Aldonu al la ekzistanta listo anstataŭ anstataŭigi ĝin, ĉar forviŝi NO_PROXY rompas ĉiun alian internan celon, kiu dependis de ĝi. La komandoj sube aldonas la enskribon kaj poste demandas al Requests ĉu la pretervojo validas.

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))"

La kongruo estas laŭ gastiganta sufikso, do .corp.example kovras la tutan domajnon dum api.corp.example kovras unu nomon. Nuda asterisko malŝaltas proksian uzadon por ĉiu gastiganto kaj preskaŭ neniam estas tio, kion produktada tasko volas. Ĉu CIDR-enskribo estos honorata dependas de la versioj de Requests kaj urllib3 en la bildo, do testu la ĝustan enskribon anstataŭ supozi, ke ĝi funkcias. Kontrolu la rezulton de should_bypass_proxies por la reala URL, ne por gastigantnomo, kiun vi tajpis el memoro.

Tenu la du tavolojn aparte en la kapo. Preterpasi la HTTP-proksion ne preterpasas la VPN-on, ĉar la proksia decido okazas en la biblioteko kaj la tunela decido okazas en la enkursiga tabelo de la kerno.

Malŝaltu trust_env nur kiel konscian seanpolitikon

Se la tuta tasko devas ignori la ĉirkaŭan agordon, konstruu la seancsion eksplicite kaj registru la decidon en la kodo. Tio estas politiko, ne provizora solvo, kaj ĝi apartenas al diff, kiun recenzanto povas vidi. La ekzemplo sube konservas tempolimon, eksplicitan CA-vojon kaj statuskontrolon.

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()

Malŝalti trust_env ŝanĝas tri kondutojn samtempe, kaj nur unu el ili temas pri proksio. Requests ĉesas legi .netrc-akreditaĵojn, kaj la variabloj REQUESTS_CA_BUNDLE kaj CURL_CA_BUNDLE ĉesas influi verify, kiu tiam falas reen al la enpakita certifikata konservejo. Se via organizo finas TLS per sia propra CA, tiu retrofalo kaŭzas kontroleraron, kiu aspektas ne rilata al la ŝanĝo, kiun vi ĵus faris. Ĝuste la eksplicita transdono de verify tenas la du efikojn apartaj.

Kion vi ne devus fari estas agordi verify=False por silentigi la rezultan eraron. Tio interŝanĝas proksian misagordon kontraŭ nekontrolita konekto, kaj ĝi kaŝas la certifikatan problemon, kiun la ekskludo devis malkovri.

Kontrolu la fiaskantan tavolon kaj konservu retrovojon

Tri fiaskoj aspektas same en protokolo kaj havas nenion komunan: proksio, kiu ne povas atingi la celon, ĵetas ProxyError aŭ redonas 502, fida problemo ĵetas SSLError, kaj aplikada malakcepto redonas 401 aŭ 403. Reproduktu la peton ekster Requests por vidi, kiun vi havas. La komandoj sube forigas la proksion, testas la certifikatan ĉenon kaj poste ripetas la vokon tra la biblioteko.

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)"

Se la curl-voko sukcesas kaj la Python-voko malsukcesas, la medio ankoraŭ estas la diferenco. Se ambaŭ malsukcesas ĉe la TLS-etapo, la proksio neniam estis la problemo kaj la certifikata ĉeno estas. Se ambaŭ redonas 401, la peto atingis la aplikaĵon kaj la cetera laboro estas aŭtentigo. Registri, kiun el la tri vi observis, ŝparas horon al la sekva persono.

Retroiro estas unu linio en ambaŭ direktoj: forigu la ekskludon aŭ resaltu trust_env. Konservu la antaŭan NO_PROXY-valoron antaŭ ol aldoni al ĝi, kaj preferu ĉirkaŭan skripton aŭ unuanivelan Environment=-enskribon al eksporto, kiu vivas nur en via terminala historio. Ambaŭ ŝanĝoj estas videblaj en la proceza medio, do restarto kutime revenigas vin al la malnova konduto.

Finu konfirmante kvar aferojn: la kunfanditaj agordoj por la privata URL montras neniun proksion, la certifikato validiĝas kontraŭ la celita CA, la peto redonas la statuson, kiun vi atendas, kaj la ŝanĝo estas komitita ie ripetebla. Verda skripto kun neklarigita medio estas ripeto, kiu denove rompiĝos sur la sekva maŝino. La komandoj en ĉi tiu gvidilo estas tiuj, kiujn vi algluu en la bileton.

Rilataj artikoloj