חברו את המנהרה, פתחו את אותה סימנייה, והאתר ברשימת ההיתרים עונה בדיוק כפי שענה מהמשרד. זו ההנחה שרוב תוכניות הגישה מרחוק נשענות עליה בשקט, והיא מחזיקה רק כל עוד שלושה דברים נפרדים נשארים נכונים בו-זמנית. אף אחד מהם אינו תכונה של לקוח ה-VPN, ואף רשומת DNS אינה יכולה לספק ולו אחד מהם. כשהסימנייה נכשלת בבית, הדפדפן נותן לכם שגיאה כללית אחת, בין אם הסיבה היא נתיב חסר, כתובת יציאה לא מאושרת או proxy שהחליף את המקור שהוא מדווח עליו. התייחסות לשלושת אלה כאל בעיה אחת היא הדרך שבה תיקון מדיניות קטן הופך לשבוע של הרחבת רשימות היתרים.

התכנון ששורד מפגש עם רשת משרד אמיתית צר יותר מההנחה: טבלת החלטות מפורשת בת שלוש שורות, נקודת אכיפה אחת שאי אפשר לעקוף, ומבחן סירוב שמוכיח משהו. פירוק ההנחה בא קודם, כי כל מה שאחריו תלוי בידיעה איזו שכבה מציגה את המקור שלא כהלכה.

המיתוס: להתחבר זה לא לנתב

מנהרה נוצרת, והלקוח מתקין נתיבים עבור קבוצה כלשהי של קידומות. זה כל מה שהתחברות עושה. אם בקשת HTTPS לא קשורה עוברת דרך המנהרה, ומאיזו כתובת ציבורית היא נראית מגיעה כשהיא מגיעה, אלה החלטות שמקבלים מאוחר יותר רכיבים אחרים: טבלת הניתוב בוחרת את הנתיב, והיציאה בוחרת את המקור.

לכן המשרד ושולחן המטבח נפרדים באותו מחשב נייד, באותו פרופיל דפדפן ובאותה סימנייה. במשרד הבקשה יוצאת דרך כתובת ציבורית מתוחזקת שמפעיל האתר הסכים לה. דרך מנהרה מלאה היא יכולה לצאת דרך יציאת ה-VPN, שהיא כתובת אחרת ועד שמישהו יוסיף אותה, לא מאושרת. דרך מנהרה מפוצלת היא אולי לא תיכנס למנהרה כלל. רק שניים מאותם שלושה נתיבים היו אי פעם חלק מההסכם עם בעל האתר, והשלישי אינו תקלה שצריך לתקן עם שורת allow נוספת.

שלושה מצבי בקשה, שתי יציאות מאושרות

רשמו את המטריצה לפני שנוגעים בחומת אש, כי הטבלה היא התכנון והכלל הוא רק יישום אחד שלה. הכתובות שלהלן הן טווחי תיעוד; החליפו אותן בערכים המתוחזקים שלכם ושמרו אותן במקום שבו בעל האתר יכול לבקר אותן.

Request pathSource the site seesIntended decision
Office, no tunnelOffice public exitAdmit to the application login
Remote, approved full tunnelApproved VPN egressAdmit to the same login
Remote, ordinary connectionNeither approved addressDeny at the network boundary

השורה האמצעית היא המקום שבו רוב התוכניות האלה נשברות. מה שקובע הוא הכתובת שהתקן האכיפה רואה, לא הכתובת הפרטית שהמחשב הנייד מחזיק בתוך המנהרה ולא כתובת ה-LAN שלו. ערך כמו 10.8.0.6 אינו אומר דבר לאתר ציבורי, וגם 192.168.1.44 לא. כתובת מנהרה היא פרט מיעון של המנהרה, לא אישור שהאתר יכול לבדוק.

אם ה-VPN שלכם אינו יכול לספק יציאה יציבה ומתועדת, למטריצה אין שורה אמצעית תקפה ושום כמות של רשימות היתרים לא תמציא אחת. האפשרויות ההוגנות באותו רגע הן אתר פרטי שאליו מגיעים דרך נתיבים פרטיים מפורשים, או שער גישה מודע זהות לפני היישום. לשניהם חוזה שונה מרשימת היתרים ציבורית, ושניהם קלים יותר להסבר למבקר מאשר רשימה שגדלה עד שבמקרה עבדה.

קראו את המקור במקום שבו מתקבלת ההחלטה

שימו את ההגבלה על ההתקן שמסיים את הבקשה, וודאו שאף נתיב מקור חלופי אינו עוקף אותה. מודול הגישה של Nginx מעריך את הוראות allow ו-deny לפי הסדר, ההתאמה הראשונה מנצחת, וכללים שעברו בירושה מבלוק עוטף עדיין חלים בתוך location. allow צר לצד allow רחב באותו מקום בדרך כלל אומר שהרחב הוא שמחליט. קראו את כל התצורה האפקטיבית של אותו location לפני שאתם עורכים בה ולו שורה אחת.

server {
    listen 443 ssl;
    server_name intranet.example.com;

    set_real_ip_from 10.20.0.10;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    location /app/ {
        allow 203.0.113.24;    # office public exit
        allow 198.51.100.77;   # approved VPN egress
        deny  all;
        proxy_pass http://app_backend;
    }
}

מאחורי מאזן עומסים או proxy הפוך, הכלל הזה רואה את ה-proxy אלא אם תגידו לו אחרת. שחזרו את כתובת הקורא רק דרך מנגנון ה-proxy המהימן הנתמך, עם רשימה מפורשת של כתובות proxy. כותרת בקשה שמצהירה על כתובת מאושרת אינה הוכחה שהקורא מחזיק בה, ובמאזין ציבורי כותרת מועברת שאינה מאומתת הופכת את רשימת ההיתרים לקישוט.

אחר כך בדקו את משפחת הכתובות האחרת. מערך כללים שמכסה רק IPv4 הוא החלטה חלקית עבור שם מארח שעונה גם על AAAA, ולקוח עם IPv6 עובד יגיע לאותו יישום בנתיב שמעולם לא סקרתם.

מנהרה מפוצלת: הבקשה שלעולם אינה נכנסת

מנהרה מפוצלת נושאת רק את הקידומות שברשימה שלה. תת-רשתות משרד פנימיות בדרך כלל נכנסות לרשימה הזו; אתר ציבורי לא. הדפדפן מפענח את השם, משווה את הכתובת שנבחרה לטבלת הניתוב, ובכל זאת מוצא את שער ברירת המחדל המקומי לפניו.

כך הבקשה מגיעה מחיבור הבית של המשתמש, נדחית, והדוח אומר שה-VPN שבור בעוד המנהרה עושה בדיוק את מה שהוגדרה לעשות. שני תיקונים לגיטימיים: נתבו את היעד הזה דרך המנהרה ותנו ליציאה המאושרת לשאת אותו, או השלימו עם כך שהאתר נגיש ישירות ותנו למשתמשים מרוחקים נתיב מאושר אחר, כמו שער הגישה. הרחבת רשימת ההיתרים הציבורית של האתר עד שכתובת בית נכללת בה במקרה אינה אף אחד מהשניים, והיא מסירה את הגבול שהתכנון היה אמור לאכוף. שני הראשונים שומרים על המטריצה הוגנת; השלישי מוחק ממנה שורה בשקט.

הוכיחו את הסירוב, ואז את ההתאוששות

בדקו עם בקשה שמפעילה את ההחלטה האמיתית, מלקוח שעומד על כל שורה בטבלה. בדיקת נגישות מול איזה דף לא קשור שמציג כתובת אינה מוכיחה דבר, כי היעד הזה עשוי ללכת בנתיב אחר מהיישום.

curl -sS -o /dev/null -w 'status=%{http_code}
' https://intranet.example.com/app/login
# repeat with the tunnel up, then with it down
tail -f /var/log/nginx/access.log | grep ' /app/'

השוו את רשומת הגישה בגבול למה שהטבלה חזתה. אחר כך הורידו את המנהרה ובצעו בקשה חדשה שאמורה להידחות; דף שכבר נטען או חיבור שכבר פתוח אינו בודק דבר כלל. אם לא מופיע סירוב, נקודת האכיפה אינה במקום שאתם חושבים.

השאירו אימות יישום לאחר הקבלה לרשת, כי יציאת משרד ויציאת VPN כל אחת מייצגת אנשים רבים ואף אחת אינה מזהה אדם. ההוראה למשתמשים נשארת קצרה: העלו את המנהרה המאושרת, ואז נסו שוב. זה מה ששומר על כתובת URL אחת נוחה בזמן שכלל המקור נשאר החלטה ולא ניחוש.

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