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

שתי משימות עם שם אחד

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

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

Android: שער הסכמה, ואין API לפרופילים

VpnService קיימת מאז Android 4.0 ומאפשרת לאפליקציה ליצור ממשק tun ואז לקרוא ולכתוב חבילות. יש להצהיר על השירות עם BIND_VPN_SERVICE, ו-VpnService.prepare() מפיקה את דיאלוג המערכת שמבקש מהמשתמש לאשר אותו. הדוגמה של הפלטפורמה, ToyVpn, היא ההצהרה הברורה ביותר של הצורה המיועדת: הקוד שלכם מחזיק בממשק ובכל מה שזורם דרכו.

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

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

iOS: ההרשאה היא הגבול

iOS מחלקת את אותה עבודה אחרת. לקוח VPN מיישם ספק מנהרת חבילות או פרוקסי אפליקציה במסגרת Network Extension, וההרשאה המתאימה חייבת להינתן לחשבון המפתח. תצורת VPN אישית דרך NEVPNManager קיימת למקרה הפשוט יותר, והיא עדיין פועלת באותו מודל הרשאות. Apple מתעדת את כל המשטח במדריך Network Extension, שכדאי לקרוא לפני שמגדירים את היקף העבודה.

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

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

שולחן העבודה מגיע רחוק יותר, אבל הבעלות לא משתנה

Windows הוא המקרה המתירן. Add-VpnConnection יוצר רשומת ספר טלפונים מהפעלת PowerShell מוגברת, ו-rasdial מתחבר או מנתק אותה מסקריפט. אפליקציה יכולה גם להפעיל לקוח ספק דרך שורת הפקודה המתועדת שלו. יצירת הפרופיל היא עדיין פעולה ניהולית, כי הרשומה חיה במאגר ברמת המחשב כולו.

macOS מתנהגת אותו דבר עם כלים אחרים. scutil --nc start ו-stop פועלים על שירותים קיימים, בעוד יצירת שירות היא משימת ניהול מערכת. החזקה בתהליך במחשב נייד אינה הופכת אתכם לבעלים של התצורה.

מה לבנות במקום

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

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

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