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

הכלל שאתם חושבים שכתבתם

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

ברגע שהתנאי הוא מצב חיבור ולא כתובת מקור, קבוצת השולחים המותרים אינה עוד קבוצת עמיתי ה-VPN. כל מי שמגיע לכתובת הציבורית יכול לשלוח בקשת echo כל עוד השער פתוח. המנהרה לא הפכה לנתיב; המנהרה הפכה למתג.

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

מה השער באמת שולט בו

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

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

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

בנו את האובייקט פעם אחת ואז החליפו אותו

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

New-NetFirewallRule -Name "VpnGateEchoV4" -DisplayName "Public echo gated on VPN state" -Direction Inbound -Action Allow -Protocol ICMPv4 -IcmpType 8 -LocalAddress 203.0.113.10 -RemoteAddress Any -Enabled False
Set-NetFirewallRule -Name "VpnGateEchoV4" -Enabled True

השם הוא המזהה הקבוע; שם התצוגה הוא תיעוד שאדם רשאי לערוך. תאמו לפי -Name והסקריפט יפסיק לייצר כפילויות. אותה צורת פקודה מכסה את מקרה IPv6 עם -Protocol ICMPv6 -IcmpType 128, אבל זה כלל נפרד כי מספרי סוג ה-echo שונים בין שתי המשפחות.

שמרו על משפחת הכתובות וסוג ה-ICMP מפורשים מסיבה שנייה: -Protocol ICMPv4 בלי סוג מתיר כל הודעת ICMPv4 שהפרופיל מתיר, כולל אלו שמעולם לא התכוונתם לקבל. נקיבת סוג 8 מצמצמת את הכלל לבקשת echo, וזה הדבר היחיד שבדיקת נגישות שולחת.

איפה האוטומציה סותרת את הכוונה

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

יש מלכודת היקף בבדיקת המצב עצמה. Get-VpnConnection מדווח על פרופילי לקוח שהוגדרו במכונה, כברירת מחדל למשתמש הנוכחי ולכל המשתמשים עם -AllUserConnection. הוא אינו מדווח על המשתמשים המרוחקים שמחוברים כעת לשרת RRAS; זו תצפית אחרת עם פקודה אחרת. שער שנבנה על הלא נכון אינו מחובר לשום דבר.

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

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

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