Dvě různé závady vypisují stejný traceback pipu a oprava vhodná pro jednu tu druhou zhorší. Klient příliš starý na to, aby pojmenoval tunelovaného hostitele, potřebuje upgrade. Proxy, která přepodepisuje provoz, potřebuje důvěryhodný kořenový certifikát, ne downgrade. Zjistěte, kterou ze dvou máte, než upravíte proměnnou proxy, protože cesty vedou opačnými směry.

Přečtěte si poslední rámce, než sáhnete na nastavení

Místo, kde traceback končí, vám řekne, která vrstva to vzdala. Pokud závěrečné rámce sedí v TLS kódu urllib3 zabudovaného v pipu a text si stěžuje na název hostitele, klientská knihovna nemohla dokončit krok ověření, a to je problém verze mnohem častěji než problém certifikátu. Pokud text místo toho hlásí odmítnuté připojení, nevyřešený název proxy nebo chybu HTTP 407, je na vině koncový bod tunelu a žádný upgrade to nezmění.

Zachyťte verzi pipu a proměnné proxy ve stejném shellu, který selhává. Shell otevřený před tím, než tunel naběhl, nese jiné hodnoty než ten otevřený potom, a rozdíl mezi nimi je často celá diagnóza.

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

Když je klient starší než tunel

Starší verze pipu přinášely HTTPS stack, který ztratil cílový název hostitele, jakmile socket obalil tunel. Zpráva check_hostname je to, co tento stack vypíše, když dosáhne ověření bez názvu k porovnání. Upgrade závadu odstraní, protože novější klient si název během handshake podrží, a změna je dost levná na to, aby se zkusila první, kdykoli závěrečné rámce ukazují na zabudovaný TLS kód.

Pokud se k indexu nelze ze selhávajícího stroje dostat, stáhněte aktuální wheel na hostiteli, který to umí, a nainstalujte jej ze souboru. Použijte název souboru, který jste skutečně stáhli, ne verzi zkopírovanou z blogového příspěvku.

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

Když proxy přepodepisuje provoz

Proxy, která ukončuje TLS a znovu vydává certifikáty pod firemním kořenem, produkuje jinou chybu: certificate verify failed, nikoli stížnost na název hostitele. Ten rozdíl je stopa, protože klient dosáhl serveru a pak odmítl identitu, která mu byla předložena. Opravou je té kořenové autoritě výslovně důvěřovat, buď pro jeden příkaz, nebo přes proměnnou PIP_CERT, aby si klient mohl postavit řetěz k tomu, co proxy předkládá. Přidání kořene do systémového úložiště důvěry také funguje, ale mění důvěru pro každý program na stroji, což je větší rozhodnutí než oprava jedné instalace balíčku.

--trusted-host mějte jako diagnostiku, nikdy jako trvalý stav. Vypíná kontrolu, kterou jste se snažili zachovat, takže skutečně špatný certifikát pak vypadá zdravě. Pokud jste ho použili k instalaci jednoho balíčku, odstraňte ho a před dalším vydáním řetěz opravte.

Váš vlastní kód v Pythonu konfiguraci pipu úplně ignoruje. Volání requests potřebuje proxy a balíček předané tam, kde je ta relace vidí, a proto blok níže nastavuje obojí na objektu relace.

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)

Když je koncový bod nebo port špatně

Klient tunelu často při připojování přepisuje systémovou proxy, což může nechat pip namířený na hostitele, který na tom portu nikdy neodpoví. Otestujte koncový bod klientem, který není pip, než změníte jakékoli nastavení pipu. Pokud curl selže se stejným argumentem proxy, závada je nad pipem a žádná konfigurace uvnitř pipu nepomůže.

Příznak příkazu a proměnné prostředí říkají totéž pro různé rozsahy: příznak platí pro jedno vyvolání, proměnné pro každý proces spuštěný potom. Přidejte NO_PROXY pro interní index, aby soukromý provoz balíčků vynechal objížďku tunelem.

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

Uložte nastavení a dokažte, že cesta funguje

Uložte proxy do vlastní konfigurace pipu, když má přežít aktuální shell, a pak si přečtěte, co pip skutečně použije. Výstup debug pojmenovává soubor a proměnnou za každou hodnotou, což urovná spory o prioritu rychleji než čtení dokumentace.

Ověření záměrně používá dva klienty. Požadavek ze standardní knihovny dokazuje trasu a řetěz důvěry, zatímco stažení dokazuje, že s nimi vlastní konfigurace pipu souhlasí. Když první uspěje a druhé selže, rozdíl je uvnitř pipu, ne v síti.

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

Související články