VPN deluje, notranja nadzorna plošča se odpre v brskalniku, skript Python pa še vedno sproži napako proxyja. Na tej sliki s tunelom ni nič narobe: tolmač prebere naslov proxyja iz svojega okolja in tam pošlje zahtevo. Ta priročnik prebere okolje, ki ga proces resnično vidi, uporabi najožjo izključitev in šele nato razmisli o izrecni politiki seje. Vsak korak se konča z ukazom, katerega izhod odloči, ali nadaljujete.

Preberite okolje, ki ga proces resnično vidi

Nastavitve proxyja na namizju, izvozi v lupini in vrstice Environment= enote systemd so trije različni viri, Requests pa prebere le zadnjega, ki ga podeduje. Zaženite diagnozo spodaj v isti lupini, vsebniku ali enoti, ki izvaja skript, ki ne uspe, ne v svojem interaktivnem terminalu. Spremenljivka, izvožena v vaši prijavni lupini, je za proces v vsebniku nevidna, in ta vrzel pojasnjuje številna poročila o proxyju, ki se pojavi od nikoder. Oba ukaza izpišeta iste podatke na različnih ravneh 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()]"

Prebereta se oba zapisa vsake spremenljivke, podvojeni vnosi pa se uporabijo v vrstnem redu, v katerem jih je proces prejel, zato lahko zastarela HTTP_PROXY preglasi pravkar izvoženo vrednost. Tudi spremenljivke paketa CA so tu pomembne, ker spreminjajo, v kaj se verify razreši, ne da bi se kjer koli pojavile v kodi. Če je izhod prazen, okolje ni vaš problem in lahko prenehate brati ta razdelek. Če navaja proxy, ki ga ne poznate, poiščite datoteko ali enoto, ki ga nastavlja, preden karkoli spremenite.

Vprašajte Requests, kaj bi naredil z določenim URL-jem. Ta klic prikaže združene vrednosti proxy, verify in cert za to zahtevo, ne da bi poslal paket.

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

Neprazen vnos proxies za zasebnega gostitelja je vaš odgovor, izpisana vrednost verify pa pove, kateremu paketu CA bi zahteva zaupala. Če sta oba videti pravilna, je napaka pozneje v skladu in preiti morate na razdelek o preverjanju. Ne ugibajte iz kode: združevanje poteka za vsako zahtevo, zato se ena seja lahko obnaša drugače za dva gostitelja.

Izključite zasebnega gostitelja, preden kar koli onemogočite

Ko je proxy resnično potreben za druge cilje, je ozka rešitev izključitev tega gostitelja. Dodajajte na obstoječi seznam, namesto da bi ga zamenjali, ker brisanje NO_PROXY pokvari vsak drug notranji cilj, ki se je zanašal nanj. Ukazi spodaj dodajo vnos in nato vprašajo Requests, ali obhod velja.

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

Ujemanje poteka po priponi gostitelja, zato .corp.example pokriva celo domeno, api.corp.example pa eno ime. Gola zvezdica onemogoči proxy za vsakega gostitelja in skoraj nikoli ni tisto, kar želi produkcijska naloga. Ali bo vnos CIDR upoštevan, je odvisno od različic Requests in urllib3 v sliki, zato preizkusite natančen vnos, namesto da bi domnevali, da deluje. Preverite rezultat should_bypass_proxies za pravi URL, ne za ime gostitelja, vpisano po spominu.

Dve plasti imejte ločeni v glavi. Obhod proxyja HTTP ne obide VPN, ker se odločitev o proxyju sprejme v knjižnici, odločitev o tunelu pa v usmerjevalni tabeli jedra.

Onemogočite trust_env le kot namerno politiko seje

Če mora celotna naloga prezreti okoljsko konfiguracijo, zgradite sejo izrecno in odločitev zapišite v kodo. To je politika, ne obhod, in spada v diff, ki ga recenzent vidi. Spodnji primer ohrani časovno omejitev, izrecno pot CA in preverjanje stanja.

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

Izklop trust_env spremeni tri vedenja hkrati, in le eno od njih se nanaša na proxye. Requests preneha brati poverilnice .netrc, spremenljivki REQUESTS_CA_BUNDLE in CURL_CA_BUNDLE pa prenehata vplivati na verify, ki se nato vrne na vgrajeno shrambo potrdil. Če vaša organizacija konča TLS z lastno CA, to vračanje sproži napako preverjanja, ki je videti nepovezana s pravkar narejeno spremembo. Prav izrecno posredovanje verify ohrani oba učinka ločena.

Česar ne smete storiti, je nastavitev verify=False, da utišate nastalo napako. To zamenja napačno konfiguracijo proxyja za nepreverjeno povezavo in skrije težavo s potrdilom, ki naj bi jo izključitev razkrila.

Preverite plast, ki ne uspe, in ohranite možnost vrnitve

Tri okvare so v dnevniku videti enako in nimajo nič skupnega: proxy, ki ne doseže cilja, sproži ProxyError ali vrne 502, težava z zaupanjem sproži SSLError, zavrnitev aplikacije pa vrne 401 ali 403. Ponovite zahtevo zunaj Requestsa, da vidite, katero imate. Ukazi spodaj odstranijo proxy, preizkusijo verigo potrdil in nato ponovijo klic skozi knjižnico.

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

Če klic curl uspe in klic Python ne uspe, je razlika še vedno okolje. Če oba ne uspeta v fazi TLS, proxy nikoli ni bil težava in težava je veriga potrdil. Če oba vrneta 401, je zahteva dosegla aplikacijo in preostalo delo je overjanje. Zapis, katero od treh ste opazili, prihrani naslednji osebi uro.

Vrnitev je ena vrstica v obe smeri: odstranite izključitev ali obrnite trust_env nazaj. Shranite prejšnjo vrednost NO_PROXY, preden ji kaj dodate, in raje uporabite ovojni skript ali vnos Environment= na ravni enote kot izvoz, ki živi le v zgodovini vašega terminala. Obe spremembi sta vidni v okolju procesa, zato vas ponovni zagon običajno vrne k staremu vedenju.

Končajte s potrditvijo štirih stvari: združene nastavitve za zasebni URL ne kažejo proxyja, potrdilo se preveri proti predvideni CA, zahteva vrne stanje, ki ga pričakujete, in sprememba je shranjena na mestu, ki ga je mogoče ponoviti. Zelen skript z nerazloženim okoljem je popravek, ki se na naslednjem stroju znova pokvari. Ukazi v tem priročniku so tisti, ki jih prilepite v zahtevek.

Sorodni članki