Două căderi diferite tipăresc aceeași urmă pip, iar reparația potrivită pentru una o înrăutățește pe cealaltă. Un client prea vechi ca să numească o gazdă tunelată are nevoie de o actualizare. Un proxy care re-semnează traficul are nevoie de un certificat rădăcină de încredere, nu de o retrogradare. Stabiliți care dintre cele două îl aveți înainte de a edita o variabilă de proxy, fiindcă traseele merg în direcții opuse.

Citiți ultimele cadre înainte de a atinge setările

Locul unde se termină urma vă spune care strat a cedat. Dacă cadrele finale stau în codul TLS al urllib3 inclus cu pip și textul se plânge de un nume de gazdă, biblioteca client nu a putut încheia un pas de verificare, iar asta este o problemă de versiune mult mai des decât o problemă de certificat. Dacă textul raportează în schimb o conexiune refuzată, un nume de proxy nerezolvat sau o eroare HTTP 407, punctul final al tunelului este vinovat și nicio actualizare nu va schimba asta.

Capturați versiunea pip și variabilele de proxy în același shell care eșuează. Un shell deschis înainte ca tunelul să pornească are valori diferite de unul deschis după, iar diferența dintre ele este adesea întregul diagnostic.

python3 -m pip --version
env | grep -i -E 'proxy|no_proxy'

Când clientul este mai vechi decât tunelul

Versiunile mai vechi de pip includeau o stivă HTTPS care pierdea numele gazdei de destinație odată ce socketul era înfășurat de un tunel. Mesajul check_hostname este ceea ce emite acea stivă când ajunge la verificare fără un nume cu care să compare. O actualizare elimină defectul pentru că clientul mai nou păstrează numele pe parcursul strângerii de mână, iar schimbarea este suficient de ieftină încât să fie încercată prima ori de câte ori cadrele finale indică cod TLS inclus.

Dacă indexul nu poate fi atins de pe mașina care eșuează, obțineți un wheel actual pe o gazdă care poate și instalați din fișier. Folosiți numele fișierului pe care l-ați descărcat efectiv, nu o versiune copiată dintr-o postare de blog.

python3 -m pip install --upgrade pip
python3 -m pip install ./pip-24.2-py3-none-any.whl

Când proxy-ul re-semnează traficul

Un proxy care termină TLS și reemite certificate sub o rădăcină corporativă produce o altă eroare: certificate verify failed, nu o plângere despre numele gazdei. Acea diferență este indiciul, fiindcă clientul a ajuns la un server și apoi a respins identitatea care i-a fost arătată. Reparația este să aveți încredere explicită în acea rădăcină, fie pentru o singură comandă, fie prin variabila PIP_CERT, ca clientul să poată construi un lanț până la ce prezintă proxy-ul. Adăugarea rădăcinii în depozitul de încredere al sistemului funcționează și ea, dar schimbă încrederea pentru fiecare program de pe mașină, iar asta este o decizie mai mare decât repararea unei singure instalări de pachet.

Păstrați --trusted-host ca diagnostic, niciodată ca stare permanentă. Dezactivează verificarea pe care încercați să o păstrați, așa că un certificat cu adevărat greșit pare sănătos după aceea. Dacă l-ați folosit pentru a instala un pachet, scoateți-l și reparați lanțul înainte de următoarea versiune.

Propriul dumneavoastră cod Python ignoră complet configurația pip. Un apel requests are nevoie de proxy și de pachet transmise acolo unde acea sesiune le poate vedea, de aceea blocul de mai jos le pune pe amândouă pe obiectul sesiunii.

pip install --cert /usr/local/share/ca-certificates/corp-root.crt requests
export PIP_CERT=/usr/local/share/ca-certificates/corp-root.crt
s = requests.Session()
s.proxies = {"https": "http://10.20.30.40:8080"}
s.verify = "/usr/local/share/ca-certificates/corp-root.crt"
s.get("https://pypi.org/simple/", timeout=15)

Când punctul final sau portul sunt greșite

Un client de tunel rescrie adesea proxy-ul sistemului în timp ce se conectează, ceea ce poate lăsa pip îndreptat spre o gazdă care nu răspunde niciodată pe acel port. Testați punctul final cu un client care nu este pip înainte de a schimba orice setare pip. Dacă curl eșuează cu același argument de proxy, defectul este deasupra pip și nicio configurație din interiorul pip nu va ajuta.

Indicatorul comenzii și variabilele de mediu spun același lucru unor domenii diferite: indicatorul se aplică unei invocări, variabilele fiecărui proces pornit după aceea. Adăugați NO_PROXY pentru un index intern, ca traficul privat de pachete să sară ocolul prin tunel.

curl -x http://proxy.corp.internal:8080 --head https://pypi.org/simple/
pip install --proxy http://proxy.corp.internal:8080 requests

Persistați setarea și demonstrați că traseul funcționează

Stocați proxy-ul în configurația proprie a pip când trebuie să supraviețuiască shell-ului curent, apoi citiți înapoi ce va folosi pip cu adevărat. Ieșirea debug numește fișierul și variabila din spatele fiecărei valori, ceea ce lămurește disputele despre precedență mai repede decât citirea documentației.

Verificarea folosește intenționat doi clienți. Cererea din biblioteca standard dovedește ruta și lanțul de încredere, în timp ce descărcarea dovedește că configurația proprie a pip este de acord cu ele. Când prima reușește și a doua eșuează, diferența este în interiorul pip, nu în rețea.

pip config set global.proxy http://proxy.corp.internal:8080
pip config debug
python3 -c "import urllib.request as r; print(r.urlopen('https://pypi.org/simple/').status)"
pip download --no-deps -d /tmp/wheelcheck requests
What you seeFirst commandRepair
hostname message inside vendored TLS framespython3 -m pip --versionupgrade the client
certificate verify failed after the tunnelcurl -x http://proxy.corp.internal:8080 --head https://pypi.org/simple/trust the corporate root
connection refused or HTTP 407env | grep -i -E 'proxy|no_proxy'correct host, port or credentials

Articole similare