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

למה ה-kill switch מוגבל בפועל

אין במערכת ההפעלה דגל kill switch אחד. לקוח שמצהיר על אחד מתקין מערך כללים: להפיל כל מה שלא יוצא דרך המנהרה שלי, ולעיתים קרובות לנהוג ב-fail closed כשהמנהרה נעלמת. בלינוקס זו בדרך כלל שרשרת nftables או iptables, ב-Windows מערך מסננים של Windows Filtering Platform, באנדרואיד וב-iOS הניתוב של שירות המנהרה עצמו בתוספת הגדרת המערכת שחוסמת חיבורים בלי VPN. מדריך ה-VPN של אנדרואיד מתאר את מודל השירות הזה אם אתם רוצים את נקודת המבט של הפלטפורמה.

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

שלושה תנאים שקובעים מי יכוסה

אין צורך למנות כל שילוב. שלוש שאלות מכריעות את זה בכמה דקות.

  1. האם הפלטפורמה בכלל מאפשרת מנהרה שנייה? רוב הטלפונים באנדרואיד וה-iPhone מקבלים שירות VPN פעיל אחד בלבד לכל פרופיל משתמש, כך שהאפליקציה השנייה לעולם לא מחזיקה מנהרה ולעולם לא אוכפת דבר. אתם מקבלים מדיניות אחת, מהאפליקציה שזכתה במקום.
  2. איזה תהליך מחזיק בנתיב ברירת המחדל? Windows, macOS ולינוקס נושאים שני מנהרות בקלות. נתיב ברירת המחדל שייך ללקוח שהגדיר אותו אחרון או עם המדד הטוב יותר, והלקוח השני מחובר אבל לא פעיל. בלינוקס מצב נתיב ברירת המחדל של wg-quick משתמש בניתוב מבוסס מדיניות עם טבלה פרטית וכלל fwmark, ולכן מנהרה שנייה של wg-quick מוסיפה כלל מתחרה במקום להחליף את הראשונה.
  3. האם הלקוח השני מגיע לשרת שלו עצמו? אם ה-kill switch הראשון דוחה כברירת מחדל, נקודת הקצה החיצונית של האפליקציה השנייה היא רק יעד מופל נוסף. הוא מנסה שוב בשקט ולעולם לא מדווח על שגיאה.

הגרסה הקצרה, לשרשורי תמיכה:

SetupWhat you actually get
Second client cannot hold a tunnelOne active policy; the other app only reports that it is waiting
Both tunnels up, second took the default routeThe first kill switch blocks traffic it never meant to touch; the connection dies, or leaks if its rules are broad
First kill switch allows only its own endpoint and interfaceSecond client never connects; first tunnel unaffected
Both up, DNS written by whichever client ran lastName resolution breaks for one side when either tunnel drops

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

מה נכשל ראשון, ואיך זה נראה

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

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

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

אמתו איזו מדיניות באמת בתוקף

עשו זאת עם תעבורה לא מזיקה, לא עם משהו שהייתם מתגעגעים אליו.

בלינוקס שאלו את הקרנל מי מנצח ומה החומת אש קושרת. ip -4 route show default מציין את המנהרה שמחזיקה ביציאה. ip rule show מראה אם ניתוב מבוסס מדיניות בעניין. sudo nft list ruleset | grep -n oifname מראה אם ההפלות קשורות לשם ממשק, לסימן או לשרשרת היציאה כולה.

ב-Windows אותו סיפור חי במדד הנתיב וברשימת המסננים: Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Sort-Object RouteMetric ו-Get-NetFirewallRule -Enabled True | Where-Object DisplayName -match "VPN". ב-macOS, netstat -rn -f inet | head -5 ו-scutil --dns | head -20.

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

מתי שני לקוחות הם העיצוב הלא נכון

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

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

רשימת בדיקה לפני שמשאירים את שניהם

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

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

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

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