Грешка check_hostname во pip зад прокси: pip или тунелот?
Два различни дефекта ја печатат истата грешка за име на домаќин во pip зад прокси. Разликувајте застарен клиент од прокси што повторно потпишува сообраќај и поправете го вистинскиот слој.
Два различни дефекти ја печатат истата трага од pip, а поправката што одговара на едниот го влошува другиот. Клиент што е премногу стар за да именува тунелиран домаќин бара надградба. Прокси што повторно потпишува сообраќај бара доверен коренски сертификат, а не намалување на верзијата. Утврдете кој од двата го имате пред да уредите променлива за прокси, бидејќи патеките водат во спротивни насоки.
Прочитајте ги последните рамки пред да ги допрете поставките
Местото каде што завршува трагата ви кажува кој слој се откажал. Ако завршните рамки се во TLS кодот на urllib3 вграден во pip и текстот се жали на име на домаќин, клиентската библиотека не можела да заврши чекор за проверка, и тоа е проблем со верзијата многу почесто отколку проблем со сертификат. Ако текстот наместо тоа пријавува одбиена врска, нерешено име на прокси или грешка HTTP 407, виновен е крајот на тунелот и ниедна надградба нема да го промени тоа.
Забележете ја верзијата на pip и променливите за прокси во истата обвивка што не успева. Обвивка отворена пред тунелот да се крене носи различни вредности од онаа отворена потоа, и разликата меѓу нив често е целата дијагноза.
python3 -m pip --version
env | grep -i -E 'proxy|no_proxy'
Кога клиентот е постар од тунелот
Поновите изданија на pip вклучуваа HTTPS стек што го губеше името на целниот домаќин откако сокетот ќе беше обвиткан со тунел. Пораката check_hostname е она што тој стек го испушта кога ќе стигне до проверка без име за споредба. Надградбата го отстранува дефектот бидејќи поновиот клиент го чува името низ ракувањето, и промената е доволно евтина за прво да се проба кога завршните рамки укажуваат на вградениот TLS код.
Ако индексот не може да се достигне од машината што не успева, преземете актуелен wheel на домаќин што може и инсталирајте од датотеката. Користете го името на датотеката што навистина сте ја презеле, а не верзија копирана од блог запис.
python3 -m pip install --upgrade pip
python3 -m pip install ./pip-24.2-py3-none-any.whl
Кога проксито повторно потпишува сообраќај
Прокси што го завршува TLS и повторно издава сертификати под корпоративен корен произведува друга грешка: certificate verify failed, а не жалба за име на домаќин. Таа разлика е трагата, бидејќи клиентот стигнал до сервер и потоа ја одбил идентитетот што му бил покажан. Поправката е експлицитно да се верува на тој корен, или за една команда или преку променливата PIP_CERT, за да може клиентот да изгради синџир до она што го презентира проксито. Додавањето на коренот во системското складиште за доверба исто така работи, но ја менува довербата за секоја програма на машината, и тоа е поголема одлука отколку поправка на една инсталација на пакет.
Држете го --trusted-host како дијагностика, никогаш како постојана состојба. Ја исклучува проверката што сакавте да ја задржите, па навистина погрешен сертификат потоа изгледа здрав. Ако го користевте за да инсталирате еден пакет, отстранете го и поправете го синџирот пред следното издание.
Вашиот сопствен Python код целосно ја игнорира конфигурацијата на pip. Повикот на requests бара проксито и пакетот да се пренесат таму каде што таа сесија ги гледа, затоа блокот подолу ги поставува двете на објектот на сесијата.
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)
Кога крајната точка или портата се погрешни
Клиентот на тунелот често го препишува системското прокси додека се поврзува, што може да го остави pip насочен кон домаќин што никогаш не одговара на таа порта. Тестирајте ја крајната точка со клиент што не е pip пред да смените која било поставка на pip. Ако curl не успее со истиот аргумент за прокси, дефектот е над pip и никаква конфигурација во pip нема да помогне.
Знамето на командата и променливите на околината го кажуваат истото за различни опфати: знамето важи за едно повикување, променливите за секој процес стартуван потоа. Додајте NO_PROXY за внатрешен индекс за приватниот сообраќај на пакети да го прескокне заобиколувањето низ тунелот.
curl -x http://proxy.corp.internal:8080 --head https://pypi.org/simple/
pip install --proxy http://proxy.corp.internal:8080 requests
Зачувајте ја поставката и докажете дека патеката работи
Чувајте го проксито во сопствената конфигурација на pip кога треба да ја надживее тековната обвивка, потоа прочитајте што pip навистина ќе користи. Излезот на debug го именува датотеката и променливата зад секоја вредност, што ги решава споровите за приоритет побрзо од читање на документацијата.
Проверката намерно користи два клиенти. Барањето од стандардната библиотека ја докажува рутата и синџирот на доверба, додека преземањето докажува дека сопствената конфигурација на pip се согласува со нив. Кога првото успева, а второто не, разликата е внатре во pip, а не во мрежата.
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 see | First command | Repair |
|---|---|---|
| hostname message inside vendored TLS frames | python3 -m pip --version | upgrade the client |
| certificate verify failed after the tunnel | curl -x http://proxy.corp.internal:8080 --head https://pypi.org/simple/ | trust the corporate root |
| connection refused or HTTP 407 | env | grep -i -E 'proxy|no_proxy' | correct host, port or credentials |