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

אותה עבודה בשני מנגנונים

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

PropertyTeardown scriptFirewall unit
Runs when the client is killedNoYes
Needs privilege at teardown timeUsually yesConfigured once, at boot
Acts on the whole machineOften, including recovery pathsOnly on the flows it matches

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

מה וו הפירוק יכול ומה הוא לא יכול

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

#!/bin/sh
for dev in /sys/class/net/*; do
  name=$(basename "$dev")
  [ "$name" = lo ] || ip link set dev "$name" down
done

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

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

מה כלל חומת האש עושה אחרת

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

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

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

persist-tun קובע אם קיים פער

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

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

השאירו את נתיב ההתחברות מחדש חי, ואז בדקו ארבעה מצבים

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

ip route add 198.51.100.20/32 via 192.168.0.1 dev wlan0

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

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