pip check_hostname შეცდომა პროქსის უკან: pip თუ გვირაბი?
ორი სხვადასხვა ჩავარდნა ერთსა და იმავე pip ჰოსტის სახელის შეცდომას ბეჭდავს პროქსის უკან. გამოყავით მოძველებული კლიენტი ხელახლა ხელმომწერი პროქსისგან და შეაკეთეთ სწორი შრე.
ორი სხვადასხვა ჩავარდნა ერთსა და იმავე pip-ის კვალს ბეჭდავს და ერთისთვის შესაფერისი შეკეთება მეორეს აუარესებს. გვირაბით გატარებული ჰოსტის დასახელებისთვის ძალიან ძველ კლიენტს განახლება სჭირდება. ტრაფიკის ხელახლა ხელმომწერ პროქსის სჭირდება სანდო ძირეული სერტიფიკატი და არა ვერსიის დაქვეითება. დაადგინეთ, რომელია ეს ორიდან თქვენთან, სანამ პროქსის ცვლადს შეასწორებთ, რადგან ბილიკები საპირისპირო მიმართულებით მიდის.
წაიკითხეთ ბოლო ჩარჩოები პარამეტრებზე შეხებამდე
სადაც კვალი მთავრდება, გეუბნებათ, რომელმა შრემ დათმო. თუ დახურვის ჩარჩოები pip-თან მოწოდებული urllib3-ის TLS კოდშია და ტექსტი ჰოსტის სახელს უჩივის, კლიენტის ბიბლიოთეკამ ვერ დაასრულა შემოწმების ნაბიჯი და ეს ვერსიის პრობლემაა გაცილებით უფრო ხშირად, ვიდრე სერტიფიკატის პრობლემა. თუ ტექსტი ნაცვლად ამისა იტყობინება უარყოფილ კავშირზე, გადაუწყვეტელ პროქსის სახელზე ან 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 |