proxy_redirect לא מחבר את NGINX למארח ה-VPN שלכם
proxy_redirect משכתב כותרות בתגובה שכבר הגיעה; הוא אף פעם לא בוחר את ה-upstream. בדקו את proxy_pass, את המסלול אל הקצה האחורי ואז את הכותרות.
השם מכיל את המילה redirect, ולכן מדביקים אותו בתוך בלוק location כשהקצה האחורי שמאחורי ה-VPN אינו נגיש. שום דבר לא משתנה, והמסקנה המתבקשת היא שההוראה שבורה או שדרושה תחביר אחר. מה שקרה בפועל פשוט יותר ופחות מחמיא: proxy_redirect פועל על תגובה שכבר חזרה, ובפריסה הזאת אף בקשה לא הגיעה עד לשם.
שתי הוראות, שני רגעים בבקשה אחת
בקשת HTTP דרך פרוקסי הפוך עוברת כמה החלטות לפי הסדר, ושתי ההוראות נמצאות בשני הקצוות של הרצף הזה. האחת בוחרת לאן הבקשה הולכת. האחרת עורכת כותרות מסוימות בתגובה שחזרה.
| Directive | When it acts | What it can change |
|---|---|---|
proxy_pass | Before any bytes leave the proxy | Which upstream receives the request |
proxy_redirect | After the upstream responds | Matching Location and Refresh text |
הסדר הזה הוא כל התשובה. אם השורה השנייה לא תתבצע לעולם כי הראשונה נכשלה, ההוראה השנייה אינה מוגדרת שגוי, היא פשוט אינה נגישה. כמה שלא תשכתבו את השורה השנייה, התגובה שהייתה אמורה לערוך לא תיווצר. אבחנו מהשורה הראשונה החוצה, וההתנהגות המבלבלת מתפרקת למסלול חסר או לחיבור שנדחה.
בחירת ה-upstream שייכת ל-proxy_pass
נניח ש-NGINX רץ על מארח כניסה ציבורי ומגיע לאפליקציה בכתובת 10.40.0.20:8080 דרך ה-VPN שלו. הקטע שבוחר את האפליקציה הזאת נראה כך, בתוך בלוק server קיים:
location / {
proxy_pass http://10.40.0.20:8080;
}
השתמשו בסכימה, בכתובת ובפורט האמיתיים, והתייחסו לזה כאל קטע ולא כאל פריסה. מארח הכניסה חייב גם להחזיק את מסלול ה-VPN, נתיב העברה מותר ותעבורה חוזרת תקינה לאותו שירות, כי פרוקסי שמגיע לכתובת על הנייר עדיין זקוק להסכמת הליבה.
תיעוד מודול ה-proxy מפריד את בחירת ה-upstream משכתוב כותרות התגובה, ומציין שערך proxy_pass שמכיל URI משנה את האופן שבו קידומת ה-location המתאימה מוחלפת. הוספה או הסרה של רכיבי נתיב בלי לבדוק את ה-URL שהאפליקציה מצפה לו היא דרך אמינה ליצור 404 שנראה כמו כשל ניתוב.
proxy_redirect מתקן תגובות שמדליפות כתובת פרטית
ברגע שהתעבורה זורמת, קצה אחורי עשוי להשיב בכותררת Location שמציינת את הכתובת הפרטית שלו. דפדפן שעוקב אחרי הכותרת הזאת עוזב את נקודת הכניסה הציבורית ומנסה להגיע למשהו שהוא לא יכול לפתור. שכתוב תגובה שהוגדר בכוונה ממפה את ה-URL הפרטי על הציבורי:
proxy_redirect http://10.40.0.20:8080/ https://app.example.com/;
החליפו את שני הצדדים בערכים אמיתיים. הבינו גם את ההיקף הצר: טקסט הכותרות Location ו-Refresh המתאימות נכתב מחדש, אבל כתובות URL שמוטמעות ב-HTML, ב-JavaScript או בקבצים שהורדו לא.
אם אפליקציה בונה קישורים מוחלטים בכל מקום, הפתרון המתמשך הוא תצורת ה-URL החיצוני שלה עצמה, לא רשימה גדלה של כללי שכתוב בפרוקסי. הוספת כללים עד שהפלט נראה נכון מייצרת תצורה שנכשלת בעמוד הראשון שאיש לא בדק. הגדרה נכונה אחת של האפליקציה מחליפה את כל האוסף.
מה שכתוב כותרת לא יכול לתקן
כמה בעיות סמוכות נראות כמו בעיות הפניה מחדש ואינן כאלה. כותרת ה-Host שנשלחת ל-upstream עשויה להיות חייבת להתאים למארח הווירטואלי של הקצה האחורי. upstream של TLS עשוי לדרוש שם שרת מסוים בתוספת אימות תעודה, ושכתוב כותרת תגובה לא עוזר לאף אחד מהשניים.
היקף הקוקיז ומאפייני הדומיין שייכים לאפליקציה ולתצורה שלה. פרוקסי יכול לזרוק או לשכתב כותרות כל היום ועדיין לייצר הפעלה שנכשלת בבקשה השנייה, כי הקוקי הונפק למארח שהדפדפן מעולם לא ביקר בו. הכשל הזה נראה לסירוגין, ולכן הוא שורד כל כך הרבה זמן בתור קריאות. קריאת הדומיין של הקוקי בדרך כלל מסיימת את החקירה בדקה.
הגבילו גם אימות ובחירת קצה אחורי לאפליקציה המיועדת. פרוקסי הפוך ציבורי אמור לחשוף אפליקציה אחת דרך ה-VPN של השרת במקום להפוך לשער כללי לכל כתובת פרטית שאותו מארח יכול להגיע אליה. location כללי אחד שמעביר כל מה שהקורא מבקש הופך שירות חשוף אחד למפה של הרשת הפרטית שלכם. תנו ל-upstream שם מפורש והשאירו אותו שם.
בדקו לפי הסדר שבו הבקשה נוסעת
אשרו שלושה דברים ברצף: NGINX בחר את ה-location המיועד, השלים בקשה לקצה האחורי, והדפדפן עקב אחרי כל הפניה מאוחרת וטען את תת-המשאבים. לכל שלב יש שורות לוג משלו, וקריאה שלהם לפי הסדר הופכת 502 מעורפל לממצא מדויק.
ההבחנה שדרושה לכם היא בין חיבור upstream שנכשל לבין דפדפן שנשלח לשם פרטי בלתי נגיש. הראשון מופיע בלוג השגיאות של הפרוקסי; השני מופיע כבקשה שלעולם לא מגיעה, כשהדפדפן מתלונן על מארח שהוא לא מצליח לפתור. שתי בעיות שונות, שני קבצים שונים, ורק אחת מהן קשורה ל-proxy_redirect בכלל.