Lỗi check_hostname của pip sau proxy: pip hay đường hầm?
Hai sự cố khác nhau in ra cùng một lỗi tên máy chủ của pip sau proxy. Phân biệt một ứng dụng cũ với proxy ký lại lưu lượng, rồi sửa đúng lớp.
Hai sự cố khác nhau in ra cùng một dấu vết pip, và cách sửa phù hợp với cái này lại làm cái kia tệ hơn. Một ứng dụng quá cũ để gọi tên máy chủ đã được đưa qua đường hầm cần được nâng cấp. Một proxy ký lại lưu lượng cần chứng chỉ gốc đáng tin cậy, không phải hạ cấp. Xác định bạn đang gặp cái nào trước khi sửa biến proxy, vì hai con đường đi ngược chiều nhau.
Đọc các khung cuối trước khi chạm vào cài đặt
Nơi dấu vết kết thúc cho biết lớp nào đã bỏ cuộc. Nếu các khung cuối nằm trong mã TLS của urllib3 đi kèm pip và văn bản phàn nàn về tên máy chủ, thư viện ứng dụng đã không hoàn tất được một bước xác minh, và đó là vấn đề phiên bản thường xuyên hơn nhiều so với vấn đề chứng chỉ. Nếu văn bản thay vào đó báo kết nối bị từ chối, tên proxy chưa phân giải hoặc lỗi HTTP 407, điểm cuối đường hầm là thủ phạm và không bản nâng cấp nào thay đổi được điều đó.
Ghi lại phiên bản pip và các biến proxy trong đúng shell bị lỗi. Một shell mở trước khi đường hầm lên mang giá trị khác với shell mở sau đó, và khác biệt giữa hai cái thường là toàn bộ chẩn đoán.
python3 -m pip --version
env | grep -i -E 'proxy|no_proxy'
Khi ứng dụng cũ hơn đường hầm
Các bản pip cũ đi kèm một ngăn xếp HTTPS mất tên máy chủ đích khi socket bị đường hầm bọc lại. Thông báo check_hostname là thứ ngăn xếp đó phát ra khi đến bước xác minh mà không có tên để so sánh. Bản nâng cấp loại bỏ lỗi vì ứng dụng mới hơn giữ tên qua suốt quá trình bắt tay, và thay đổi này đủ rẻ để thử trước mỗi khi các khung cuối chỉ vào mã TLS đi kèm.
Nếu không thể truy cập chỉ mục từ máy bị lỗi, hãy tải một wheel hiện hành trên máy chủ có thể làm được và cài từ tệp đó. Dùng tên tệp bạn thực sự đã tải, không phải phiên bản sao chép từ một bài blog.
python3 -m pip install --upgrade pip
python3 -m pip install ./pip-24.2-py3-none-any.whl
Khi proxy ký lại lưu lượng
Một proxy kết thúc TLS và phát hành lại chứng chỉ dưới một gốc doanh nghiệp tạo ra lỗi khác: certificate verify failed, không phải phàn nàn về tên máy chủ. Chính khác biệt đó là manh mối, vì ứng dụng đã đến được máy chủ rồi từ chối danh tính được hiển thị. Cách sửa là tin tưởng rõ ràng vào gốc đó, dù cho một lệnh hay qua biến PIP_CERT, để ứng dụng có thể dựng chuỗi đến thứ proxy trình bày. Thêm gốc vào kho tin cậy của hệ thống cũng hiệu quả, nhưng nó thay đổi sự tin cậy cho mọi chương trình trên máy, và đó là quyết định lớn hơn việc sửa một lần cài gói.
Giữ --trusted-host như công cụ chẩn đoán, không bao giờ như trạng thái thường trực. Nó tắt bước kiểm tra mà bạn đang cố giữ, nên một chứng chỉ thực sự sai lại trông khỏe mạnh về sau. Nếu bạn đã dùng nó để cài một gói, hãy bỏ nó đi và sửa chuỗi trước bản phát hành tiếp theo.
Mã Python của chính bạn bỏ qua hoàn toàn cấu hình của pip. Một lời gọi requests cần proxy và gói chứng chỉ được truyền đến nơi phiên đó nhìn thấy chúng, vì thế khối bên dưới đặt cả hai trên đối tượng phiên.
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)
Khi điểm cuối hoặc cổng sai
Ứng dụng đường hầm thường ghi lại proxy hệ thống khi kết nối, điều này có thể để pip trỏ vào một máy chủ không bao giờ trả lời trên cổng đó. Hãy thử điểm cuối bằng một ứng dụng không phải pip trước khi đổi bất kỳ cài đặt pip nào. Nếu curl thất bại với cùng đối số proxy, lỗi nằm trên pip và không cấu hình nào bên trong pip giúp được.
Cờ lệnh và biến môi trường nói cùng một điều cho các phạm vi khác nhau: cờ áp dụng cho một lần gọi, các biến cho mọi tiến trình khởi động sau đó. Thêm NO_PROXY cho một chỉ mục nội bộ để lưu lượng gói riêng tư bỏ qua đường vòng qua đường hầm.
curl -x http://proxy.corp.internal:8080 --head https://pypi.org/simple/
pip install --proxy http://proxy.corp.internal:8080 requests
Duy trì cài đặt và chứng minh đường đi hoạt động
Lưu proxy trong cấu hình riêng của pip khi nó cần sống lâu hơn shell hiện tại, rồi đọc lại xem pip thực sự sẽ dùng gì. Đầu ra debug nêu tên tệp và biến đứng sau mỗi giá trị, điều này giải quyết các tranh cãi về thứ tự ưu tiên nhanh hơn việc đọc tài liệu.
Bước xác minh cố ý dùng hai ứng dụng. Yêu cầu từ thư viện chuẩn chứng minh tuyến đường và chuỗi tin cậy, còn bản tải xuống chứng minh cấu hình riêng của pip đồng ý với chúng. Khi cái đầu thành công và cái sau thất bại, khác biệt nằm bên trong pip chứ không phải trong mạng.
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 |