VPN er oppe, det interne dashbordet opnar i ein nettlesar, og Python-skriptet kastar framleis ein proxyfeil. Det er ingenting gale med tunnelen i det bildet: tolken les ein proxyadresse frå sitt eige miljø og sender førespurnaden dit. Denne runboka les miljøet prosessen faktisk ser, brukar den smalaste utelukkinga og vurderer først deretter ein eksplisitt sesjonspolicy. Kvart steg endar med ein kommando der utdata avgjer om du held fram.

Les miljøet prosessen faktisk ser

Proxyinnstillingar på skrivebordet, shell-eksportar og Environment=-linjene i ei systemd-eining er tre ulike kjelder, og Requests les berre den siste han arvar. Køyr diagnosen nedanfor i same shell, container eller eining som køyrer skriptet som feilar, ikkje i den interaktive terminalen din. Ein variabel som er eksportert i innloggingsskalet ditt, er usynleg for ein containerprosess, og det gapet forklarer mange rapportar om ein proxy som dukkar opp frå ingenting. Dei to kommandoane skriv ut dei same dataa på ulike detaljnivå.

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

Begge skrivemåtane for kvar variabel blir lesne, og dupliserte oppføringar blir brukte i den rekkjefølgja prosessen fekk dei, så ein utdatert HTTP_PROXY kan overstyre verdien du nettopp eksporterte. CA-bundle-variablane har noko å seie her òg, fordi dei endrar kva verify blir løyst til utan å visast nokon stad i koden. Er utdataa tomme, er ikkje miljøet problemet ditt, og du kan slutte å lese dette avsnittet. Viser dei ein proxy du ikkje kjenner att, finn fila eller eininga som set han før du endrar noko.

Spør Requests kva han ville gjere med ein bestemd URL. Dette kallet viser dei samanslegne proxy-, verify- og cert-verdiane for den førespurnaden utan å sende ein pakke.

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

Ei ikkje-tom proxies-oppføring for den private verten er svaret ditt, og den utskrivne verify-verdien fortel kva CA-bundle førespurnaden ville stole på. Ser begge riktige ut, er feilen lenger nede i stakken, og du bør hoppe til verifiseringsavsnittet. Ikkje gjett frå koden: samanslåinga skjer per førespurnad, og difor kan éin sesjon oppføre seg ulikt for to vertar.

Utelukk den private verten før du deaktiverer noko

Når proxyen verkeleg er nødvendig for andre destinasjonar, er den smale rettinga ei utelukking for denne verten. Legg til i den eksisterande lista i staden for å erstatte ho, fordi sletting av NO_PROXY øydelegg kvar annan intern destinasjon som stole på han. Kommandoane nedanfor legg til oppføringa og spør deretter Requests om omvegen gjeld.

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

Samsvaret er etter vertssuffiks, så .corp.example dekkjer heile domenet medan api.corp.example dekkjer eitt namn. Ei bar stjerne slår av proxy for kvar vert og er nesten aldri det ein produksjonsjobb vil ha. Om ei CIDR-oppføring blir respektert, avheng av Requests- og urllib3-versjonane i imaget, så test den nøyaktige oppføringa i staden for å anta at ho verkar. Kontroller resultatet av should_bypass_proxies for den ekte URL-en, ikkje for eit vertsnamn du skreiv frå minnet.

Hald dei to laga frå kvarandre i hovudet. Å omgå HTTP-proxyen omgår ikkje VPN-en, fordi proxyavgjerda blir teken i biblioteket og tunnelavgjerda i rutetabellen til kjernen.

Deaktiver trust_env berre som ein medviten sesjonspolicy

Om heile jobben skal ignorere den omkringliggjande konfigurasjonen, bygg sesjonen eksplisitt og registrer avgjerda i koden. Det er ein policy, ikkje ein omveg, og han høyrer heime i ein diff ein gjennomlesar kan sjå. Dømet nedanfor held på ein timeout, ein eksplisitt CA-sti og ein statussjekk.

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

Å slå av trust_env endrar tre åtferder på ein gong, og berre éi av dei handlar om proxyar. Requests sluttar å lese .netrc-legitimasjon, og variablane REQUESTS_CA_BUNDLE og CURL_CA_BUNDLE sluttar å påverke verify, som då fell tilbake til det medfølgjande sertifikatlageret. Om organisasjonen din avsluttar TLS med sin eigen CA, gjev denne tilbakefallinga ein verifiseringsfeil som ser ut til å ikkje ha noko med endringa du nettopp gjorde å gjere. Det er den eksplisitte vidareføringa av verify som held dei to effektane frå kvarandre.

Det du ikkje bør gjere, er å setje verify=False for å dempe feilen som oppstår. Det byter ein feilkonfigurert proxy mot ei uverifisert tilkopling, og det skjuler sertifikatproblemet som utelukkinga skulle avdekkje.

Verifiser laget som feilar, og hald på ein tilbakerulling

Tre feil ser like ut i ein logg og har ingenting til felles: ein proxy som ikkje når destinasjonen, kastar ProxyError eller returnerer 502, eit tillitsproblem kastar SSLError, og ei avvising frå applikasjonen returnerer 401 eller 403. Gjenskap førespurnaden utanfor Requests for å sjå kva for ein du har. Kommandoane nedanfor fjernar proxyen, testar sertifikatkjeda og gjer deretter kallet på nytt gjennom biblioteket.

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

Om curl-kallet lukkast og Python-kallet feilar, er miljøet framleis skilnaden. Om begge feilar i TLS-fasen, var proxyen aldri problemet, og sertifikatkjeda er det. Om begge returnerer 401, nådde førespurnaden applikasjonen, og det som står att er autentisering. Å notere kva for ein av dei tre du såg, sparer neste person ein time.

Tilbakerulling er éi linje i båe retningar: fjern utelukkinga, eller snu trust_env tilbake. Lagre den førre NO_PROXY-verdien før du legg til noko, og føretrekk eit wrapper-skript eller ei Environment=-oppføring på einingnivå framfor ein eksport som berre lever i terminalhistorikken din. Båe endringane er synlege i prosessmiljøet, så ein omstart bringer deg vanlegvis tilbake til den gamle åtferda.

Avslutt med å stadfeste fire ting: dei samanslegne innstillingane for den private URL-en viser ingen proxy, sertifikatet validerer mot den tiltenkte CA-en, førespurnaden returnerer statusen du ventar, og endringa er committa på ein stad som kan gjerast om att. Eit grønt skript med eit uforklart miljø er ei retting som går i stykker igjen på neste maskin. Kommandoane i denne runboka er dei du skal lime inn i billetten.

Relaterte artiklar