Грешка 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 |