שני כשלים שונים מדפיסים את אותו עקבות 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 seeFirst commandRepair
hostname message inside vendored TLS framespython3 -m pip --versionupgrade the client
certificate verify failed after the tunnelcurl -x http://proxy.corp.internal:8080 --head https://pypi.org/simple/trust the corporate root
connection refused or HTTP 407env | grep -i -E 'proxy|no_proxy'correct host, port or credentials

מאמרים קשורים