প্রক্সির পেছনে 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 |