Två olika fel skriver ut samma pip-spårning, och reparationen som passar den ena gör den andra värre. En klient som är för gammal för att namnge en tunnlad värd behöver en uppgradering. En proxy som signerar om trafiken behöver ett betrott rotcertifikat, inte en nedgradering. Ta reda på vilken av de två du har innan du redigerar en proxyvariabel, eftersom vägarna går i motsatta riktningar.

Läs de sista ramarna innan du rör inställningarna

Var spårningen slutar berättar vilket lager som gav upp. Om de avslutande ramarna ligger i pips medföljande urllib3-TLS-kod och texten klagar på ett värdnamn kunde klientbiblioteket inte slutföra ett verifieringssteg, och det är ett versionsproblem långt oftare än ett certifikatproblem. Om texten i stället rapporterar en avvisad anslutning, ett olöst proxynamn eller en HTTP 407 ligger felet vid tunnelns ändpunkt och ingen uppgradering ändrar det.

Fånga pip-versionen och proxyvariablerna i samma skal som misslyckas. Ett skal som öppnades innan tunneln kom upp bär andra värden än ett som öppnades efteråt, och skillnaden mellan dem är ofta hela diagnosen.

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

När klienten är äldre än tunneln

Äldre pip-versioner innehöll en HTTPS-stack som tappade målvärdnamnet när socketen hade lindats av en tunnel. check_hostname-meddelandet är det som den stacken skickar ut när den når verifieringen utan ett namn att jämföra med. En uppgradering tar bort felet eftersom den nyare klienten behåller namnet genom handskakningen, och ändringen är billig nog att prova först när de avslutande ramarna pekar på medföljande TLS-kod.

Om indexet inte kan nås från maskinen som misslyckas, hämta ett aktuellt wheel på en värd som kan och installera från filen. Använd filnamnet du faktiskt laddade ned, inte en version kopierad från ett blogginlägg.

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

När proxyn signerar om trafiken

En proxy som avslutar TLS och utfärdar certifikat på nytt under en företagsrot producerar ett annat fel: certificate verify failed, inte en klagan på värdnamn. Den skillnaden är ledtråden, eftersom klienten nådde en server och sedan avvisade identiteten den visades. Reparationen är att lita på den roten uttryckligen, antingen för ett enda kommando eller via variabeln PIP_CERT, så att klienten kan bygga en kedja till det proxyn presenterar. Att lägga roten i systemets förtroendelager fungerar också, men det ändrar förtroendet för varje program på maskinen, och det är ett större beslut än att laga en paketinstallation.

Behåll --trusted-host som diagnostik, aldrig som ett bestående tillstånd. Det stänger av kontrollen du försökte behålla, så ett verkligen felaktigt certifikat ser friskt ut efteråt. Om du använde det för att installera ett paket, ta bort det och reparera kedjan före nästa version.

Din egen Python-kod ignorerar pips konfiguration helt. Ett requests-anrop behöver proxyn och paketet skickade dit den sessionen kan se dem, och därför sätter blocket nedan båda på sessionsobjektet.

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)

När ändpunkten eller porten är fel

En tunnelklient skriver ofta om systemproxyn medan den ansluter, vilket kan lämna pip pekande på en värd som aldrig svarar på den porten. Testa ändpunkten med en klient som inte är pip innan du ändrar någon pip-inställning. Om curl misslyckas med samma proxyargument sitter felet ovanför pip och ingen konfiguration inne i pip hjälper.

Kommandoflaggan och miljövariablerna säger samma sak till olika omfång: flaggan gäller för ett anrop, variablerna för varje process som startas efteråt. Lägg till NO_PROXY för ett internt index så att privat pakettrafik hoppar över omvägen genom tunneln.

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

Gör inställningen beständig och bevisa att vägen fungerar

Lagra proxyn i pips egen konfiguration när den ska överleva det aktuella skalet, och läs sedan tillbaka vad pip verkligen kommer att använda. Debug-utdata namnger filen och variabeln bakom varje värde, vilket avgör diskussioner om prioritet snabbare än att läsa dokumentationen.

Verifieringen använder medvetet två klienter. Begäran från standardbiblioteket bevisar rutten och förtroendekedjan, medan nedladdningen bevisar att pips egen konfiguration stämmer med dem. När den första lyckas och den andra misslyckas ligger skillnaden inne i pip och inte i nätverket.

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

Relaterade artiklar