Twee verschillende storingen drukken dezelfde pip-traceback af, en de reparatie die bij de een past maakt de ander erger. Een client die te oud is om een getunnelde host te benoemen, heeft een upgrade nodig. Een proxy die verkeer opnieuw ondertekent, heeft een vertrouwd wortelcertificaat nodig, geen downgrade. Bepaal welke van de twee u hebt voordat u een proxyvariabele bewerkt, want de paden wijzen in tegengestelde richtingen.

Lees de laatste frames voordat u instellingen aanraakt

Waar de traceback eindigt, vertelt u welke laag het opgaf. Als de slotframes in de meegeleverde urllib3-TLS-code van pip zitten en de tekst klaagt over een hostnaam, kon de clientbibliotheek een verificatiestap niet afmaken, en dat is veel vaker een versieprobleem dan een certificaatprobleem. Als de tekst in plaats daarvan een geweigerde verbinding, een onopgeloste proxynaam of een HTTP 407 meldt, is het tunneleindpunt de schuldige en geen enkele upgrade zal dat veranderen.

Leg de pip-versie en de proxyvariabelen vast in dezelfde shell die faalt. Een shell die werd geopend voordat de tunnel opkwam, draagt andere waarden dan een die daarna werd geopend, en het verschil ertussen is vaak de hele diagnose.

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

Wanneer de client ouder is dan de tunnel

Oudere pip-versies bundelden een HTTPS-stack die de bestemmingshostnaam kwijtraakte zodra de socket door een tunnel werd omhuld. Het check_hostname-bericht is wat die stack uitstuurt wanneer hij de verificatie bereikt zonder een naam om mee te vergelijken. Een upgrade verwijdert de fout omdat de nieuwere client de naam gedurende de handshake behoudt, en de wijziging is goedkoop genoeg om eerst te proberen wanneer de slotframes op meegeleverde TLS-code wijzen.

Als de index niet bereikbaar is vanaf de falende machine, haal dan een actuele wheel op een host die dat wel kan en installeer vanuit het bestand. Gebruik de bestandsnaam die u werkelijk hebt gedownload, niet een versie die uit een blogpost is gekopieerd.

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

Wanneer de proxy verkeer opnieuw ondertekent

Een proxy die TLS beëindigt en certificaten opnieuw uitgeeft onder een bedrijfswortel, produceert een andere fout: certificate verify failed, geen klacht over een hostnaam. Dat verschil is de aanwijzing, want de client bereikte een server en wees vervolgens de identiteit af die hem werd getoond. De reparatie is die wortel expliciet te vertrouwen, hetzij voor één opdracht of via de variabele PIP_CERT, zodat de client een keten kan opbouwen naar wat de proxy presenteert. De wortel toevoegen aan de vertrouwensopslag van het systeem werkt ook, maar dat verandert het vertrouwen voor elk programma op de machine, en dat is een grotere beslissing dan één pakketinstallatie repareren.

Houd --trusted-host als diagnose, nooit als blijvende toestand. Het schakelt de controle uit die u probeerde te behouden, dus een werkelijk verkeerd certificaat ziet er daarna gezond uit. Als u het gebruikte om één pakket te installeren, verwijder het dan en herstel de keten voor de volgende release.

Uw eigen Python-code negeert de pip-configuratie volledig. Een requests-aanroep heeft de proxy en de bundel nodig op de plek waar die sessie ze kan zien, daarom zet het blok hieronder beide op het sessieobject.

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)

Wanneer het eindpunt of de poort verkeerd is

Een tunnelclient herschrijft vaak de systeemproxy terwijl hij verbindt, waardoor pip op een host kan blijven wijzen die nooit op die poort antwoordt. Test het eindpunt met een client die geen pip is voordat u een pip-instelling wijzigt. Als curl faalt met hetzelfde proxyargument, zit de fout boven pip en geen enkele configuratie binnen pip zal helpen.

De opdrachtvlag en de omgevingsvariabelen zeggen hetzelfde voor verschillende bereiken: de vlag geldt voor één aanroep, de variabelen voor elk proces dat daarna start. Voeg NO_PROXY toe voor een interne index zodat privé-pakketverkeer de omweg door de tunnel overslaat.

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

Maak de instelling blijvend en bewijs dat het pad werkt

Sla de proxy op in de eigen configuratie van pip wanneer die de huidige shell moet overleven, en lees daarna terug wat pip werkelijk zal gebruiken. De debug-uitvoer noemt het bestand en de variabele achter elke waarde, wat discussies over voorrang sneller beslecht dan de documentatie lezen.

De verificatie gebruikt bewust twee clients. De aanvraag uit de standaardbibliotheek bewijst de route en de vertrouwensketen, terwijl de download bewijst dat de eigen configuratie van pip het daarmee eens is. Wanneer de eerste slaagt en de tweede faalt, zit het verschil in pip en niet in het netwerk.

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

Gerelateerde artikelen