VPN је активан, интерни панел се отвара у прегледачу, а Python скрипта и даље баца грешку проксија. На тој слици са тунелом ништа није погрешно: интерпретер чита адресу проксија из сопственог окружења и шаље захтев тамо. Овај приручник чита окружење које процес заиста види, примењује најуже искључење и тек онда разматра изричиту политику сесије. Сваки корак завршава се командом чији излаз одлучује да ли настављате.

Прочитајте окружење које процес заиста види

Подешавања проксија на радној површини, export-и у shell-у и линије Environment= systemd јединице су три различита извора, а Requests чита само последњи који наследи. Покрените дијагностику испод у истом shell-у, контејнеру или јединици која покреће скрипту која не успева, а не у вашем интерактивном терминалу. Променљива export-ована у вашем login shell-у није видљива контејнерском процесу, и тај јаз објашњава многа извештаја о проксију који се појављује ниоткуда. Обе команде штампају исте податке на различитим нивоима детаља.

env | grep -i -E 'proxy|requests_ca_bundle|curl_ca_bundle'
python3 -c "import os;[print(k,'=',v) for k,v in sorted(os.environ.items()) if 'proxy' in k.lower()]"

Читају се оба записа сваке променљиве, а дупликати се примењују редоследом којим их је процес примио, па застарели HTTP_PROXY може надјачати вредност коју сте управо export-овали. Променљиве CA пакета су важне и овде, јер мењају у шта се verify разрешава без да се појаве било где у коду. Ако је излаз празан, окружење није ваш проблем и можете престати да читате овај одељак. Ако наводи прокси који не препознајете, пронађите датотеку или јединицу која га поставља пре него што било шта промените.

Питајте Requests шта би урадио са одређеним URL-ом. Овај позив приказује спојене вредности proxy, verify и cert за тај захтев без слања пакета.

python3 -c "import requests;s=requests.Session();print(s.merge_environment_settings('https://api.corp.example/status',{},None,None,None))"

Непразан proxies запис за приватног домаћина је ваш одговор, а одштампана verify вредност говори ком CA пакету би захтев веровао. Ако оба изгледају исправно, дефект је даље у стеку и треба да пређете на одељак о верификацији. Не погађајте из кода: спајање се дешава за сваки захтев, зато се једна сесија може понашати различито за два домаћина.

Искључите приватног домаћина пре него што било шта искључите

Када је прокси заиста потребан за друге одредишне тачке, уско решење је искључење за овог домаћина. Додајте на постојећу листу уместо да је замените, јер брисање NO_PROXY квари сваку другу интерну одредишну тачку која се на њега ослањала. Команде испод додају запис и затим питају Requests да ли заобилажење важи.

export NO_PROXY="${NO_PROXY:+$NO_PROXY,}api.corp.example,.corp.example"
python3 -c "import requests;print(requests.utils.should_bypass_proxies('https://api.corp.example/status',None))"

Подударање је по суфиксу домаћина, па .corp.example покрива цео домен, а api.corp.example једно име. Гола звездица искључује прокси за сваког домаћина и скоро никада није оно што производни посао жели. Да ли ће CIDR запис бити поштован зависи од верзија Requests и urllib3 у слици, зато тестирајте тачан запис уместо да претпостављате да ради. Проверите резултат should_bypass_proxies за прави URL, а не за име домаћина откуцано по сећању.

Држите два слоја одвојено у глави. Заобилажење HTTP проксија не заобилази VPN, јер се одлука о проксију доноси у библиотеци, а одлука о тунелу у табели рутирања језгра.

Искључите trust_env само као намерну политику сесије

Ако цео посао треба да игнорише конфигурацију из окружења, изградите сесију изричито и запишите одлуку у код. То је политика, а не заобилазно решење, и припада diff-у који рецензент може да види. Пример испод задржава таймаут, изричиту CA путању и проверу статуса.

import requests

with requests.Session() as session:
    session.trust_env = False
    response = session.get(
        "https://api.corp.example/status",
        timeout=(5, 20),
        verify="/etc/ssl/certs/corp-ca.pem",
    )
    response.raise_for_status()

Искључивање trust_env мења три понашања одједном, а само једно од њих се односи на прокси. Requests престаје да чита .netrc акредитиве, а променљиве REQUESTS_CA_BUNDLE и CURL_CA_BUNDLE престају да утичу на verify, који се тада враћа на уграђено складиште сертификата. Ако ваша организација завршава TLS сопственим CA, то враћање изазива грешку верификације која изгледа неповезана са променом коју сте управо направили. Изричито прослеђивање verify је оно што држи два ефекта одвојено.

Оно што не треба да радите је да поставите verify=False да утишате насталу грешку. То мења погрешну конфигурацију проксија за непроверену везу и крије проблем са сертификатом који је искључење требало да открије.

Верификујте слој који не успева и задржите могућност враћања

Три квара изгледају исто у дневнику и немају ништа заједничко: прокси који не достиже одредиште баца ProxyError или враћа 502, проблем са поверењем баца SSLError, а одбијање апликације враћа 401 или 403. Репродукујте захтев изван Requests-а да видите који имате. Команде испод уклањају прокси, тестирају ланац сертификата и затим понављају позив кроз библиотеку.

curl -sv --noproxy '*' https://api.corp.example/status -o /dev/null
openssl s_client -connect api.corp.example:443 -servername api.corp.example </dev/null
python3 -c "import requests;r=requests.get('https://api.corp.example/status',timeout=10);print(r.status_code)"

Ако curl позив успе, а Python позив не успе, разлика је и даље окружење. Ако оба не успеју у TLS фази, прокси никада није био проблем и проблем је ланац сертификата. Ако оба враћају 401, захтев је стигао до апликације и преостали посао је аутентификација. Записивање који од три сте приметили штеди следећој особи сат времена.

Враћање је једна линија у оба смера: уклоните искључење или вратите trust_env назад. Сачувајте претходну вредност NO_PROXY пре него што нешто додате, и дајте предност скрипти-омотачу или запису Environment= на нивоу јединице уместо export-а који живи само у историји вашег терминала. Обе промене су видљиве у окружењу процеса, па вас рестартовање обично враћа на старо понашање.

Завршите потврдом четири ствари: спојена подешавања за приватни URL не показују прокси, сертификат се верификује према предвиђеном CA, захтев враћа статус који очекујете, а промена је commit-ована на месту које се може репродуковати. Зелена скрипта са необјашњеним окружењем је поправка која се поново квари на следећој машини. Команде из овог приручника су оне које треба залепити у тикет.

Повезани чланци