אין מתג „החרגת האפליקציה הזו“: תנו לתהליך מקור משלו
ניתוב משווה כתובות, לא שמות תהליכים. תנו לתוכנית המוחרגת מקור וטבלה משלה, או העבירו את ההחלטה לנתב, שם זה כן ישר.
תוכנית אחת אמורה להשתמש בחיבור הרגיל בזמן שכל השאר נשאר במנהרה, אבל ללקוח אין מתג לכך. גם תפריט נסתר אין למצוא. מסלול נבחר מתוך שדות בתוך החבילה, והחבילה נושאת כתובות ופורטים ולא את זהות התהליך שיצר אותה, ולכן החרגה חייבת להתבטא באחד מאותם שדות. עקבו אחרי חבילה פעם אחת והאפשרויות הזמינות מפסיקות להיות מסתוריות.
למה הלקוח לא יכול להציע זאת
ניתוב לפי יעד משווה את כתובת היעד לקידומות ושומר על ההתאמה הארוכה ביותר. באותו רגע כל חבילה נראית זהה, יהיה אשר יהיה מה שיצר אותה. ניתוב לפי מדיניות מקור מרחיב את ההשוואה לכתובת המקור, וזה הקרס שכל פתרון מעשי משתמש בו: שנו את המקור, וטבלה אחרת הופכת זכאית.
פורטים לא עוזרים. החרגה לפי פורט הייתה צריכה להיבחן לפני חיפוש היעד, ולפורט אין שום חלק בהחלטה הזו. כל דבר שמשווק כהחרגה מבוססת פורט למעשה מחריג לפי שדה אחר ומתאר זאת באופן רופף.
ניתוב אמיתי לפי אפליקציה קיים במקום שבו הפלטפורמה הוסיפה מנגנון לכך, כמו קריאות סינון ב-Windows או קישור שירות ה-VPN ב-Android. עותק שולחני של OpenVPN לא מביא שום דבר מזה, ואף דגל תצורה לא ממציא אותו.
Linux: סמנו את התהליך, ואז נתבו את הסימון
הגישה הנקייה ביותר קושרת את ההחלטה לתהליך שמחזיק בסוקט. התאמת owner עובדת עבור תעבורה שנוצרת מקומית בשרשרת OUTPUT, ולכן סימון שמוחל שם יכול לבחור טבלה נפרדת:
iptables -t mangle -A OUTPUT -m owner --uid-owner 1001 -j MARK --set-mark 0x1
ip rule add fwmark 0x1 table 200
ip route add 192.168.1.0/24 dev eth0 src 192.168.1.0 table 200
ip route add default via 192.168.1.1 dev eth0 table 200
חבילות ממשתמש 1001 פונות אז לטבלה 200 ויוצאות דרך השער הרגיל, בעוד הטבלה הראשית ממשיכה לשלוח את כל השאר למנהרה. התאמת owner חלה רק על חבילות שנוצרות מקומית, וזו בדיוק התעבורה שמעניינת אתכם כאן, והיא אינה יכולה לסווג חבילות שמועברות עבור מארח אחר. אמתו בכלים ולא בכוונה: ss -tnp מציג את הכתובת המקומית ואת התהליך המחזיק בחיבורים קיימים, ו-ip route get 1.1.1.1 mark 0x1 מציג איזו טבלה הסימון בוחר.
מרחב שמות רשת הוא התשובה החזקה יותר לתוכנית עצמאית, מפני שכל סוקט שנוצר בתוכו כבול אליו מכוח המבנה, כך שתהליכי עזר וחיבורים ילדים יורשים את ההתנהגות בלי להיות מסווגים כלל. המחיר הוא אינסטלציה: זוג veth, כתובת בכל קצה, ומסלול ברירת מחדל בתוך מרחב השמות שמצביע חזרה למארח.
ip netns add novpn
ip link add veth-host type veth peer name veth-ns
ip link set veth-ns netns novpn
ip addr add 10.200.0.1/24 dev veth-host
ip netns exec novpn ip addr add 10.200.0.2/24 dev veth-ns
ip netns exec novpn ip route add default via 10.200.0.1
Windows: היעד עדיין מחליט
Windows בוחר את ממשק היציאה לפי היעד, ולכן תוכנית שרוצה נתיב אחר חייבת לשנות משהו שהמחסנית מתייעצת איתו לפני הבחירה הזו. ForceBindIP מכסה את המחצית הראשונה: הוא מפעיל תוכנית כשהסוקטים שלה כבר כבולים לכתובת מקומית שאתם נוקבים בשמה. זה לבדו לא משנה באיזה ממשק החבילה יוצאת, מפני שהיעד עדיין בוחר את המסלול. כבלו מקור במחשב נייד שמסלול ברירת המחדל שלו מצביע למנהרה, והחבילה תיכנס למנהרה בכל זאת.
לתסמין יש צורה קריאה ברגע שמכירים אותו. הוא מתקיים בכתובת LAN שהממשק הנבחר מגיע אליה ישירות, ונכשל בכל דבר באינטרנט שמסלולו מצביע למנהרה. הוא גם נראה כעובד עד שהתוכנית מעבירה עבודה לתהליך עזר, מפני שתהליך עזר שפותח סוקט משלו מעולם לא סופר לו על הכבילה.
העבירו את ההחלטה כשתהליך אחד הוא היחידה הלא נכונה
אם הדרישה האמיתית היא התקן ולא תוכנית, שימו אותו על SSID או VLAN משלו ותנו לנתב להחליט: המקור הזה הולך בנתיב הרגיל בעוד מקורות אחרים משתמשים במנהרה. מכונת שער ייעודית היא העיצוב הישר האחר: היא מחזיקה את ה-VPN ומקבלת רק את היעדים שהנתב שולח אליה. ב-VLAN המדיניות מכסה כל זרימה שההתקן פותח, כולל תהליכי העזר ששברו את גישת Windows. התמורה היא היקף: שתי תוכניות על אותו התקן כבר לא יכולות להיות מטופלות אחרת.
שתיהן מדיניות מקור או יעד עם היקף שאפשר לומר במשפט אחד. אף אחת מהן אינה לפי אפליקציה, ועיצוב שמשווק את עצמו כלפי אפליקציה נכשל בפעם הראשונה שהתוכנית מאצילה את עבודתה לתהליך שני.