כתיבת סקריפט ללקוח VPN: בחרו את השכבה לפני הסיסמה
ה-CLI של הספק, rasdial, כוונת אפליקציה או אוטומציית ממשק נכשלים כל אחד אחרת. בחרו את השכבה, החזיקו את הסוד מחוץ ל-argv והמתינו למצב, לא לקודי יציאה.
סקריפטים מפעילים לקוחות VPN בשכבה שהמחבר בחר, ושכבה זו היא לעתים רחוקות זו שהמשימה הייתה צריכה. שורת הפקודה של הספק, החייגן של מערכת ההפעלה וכוונת אפליקציה ניידת חוזרים כולם בנקודות שונות בחיי החיבור. הם גם מטפלים בסוד אחרת, וההבדל הזה קובע אם הסיסמה גלויה לכל משתמש במכונה. בחרו את השכבה לפני שתכתבו את השורה הראשונה של הסקריפט.
שכבה 1: שורת הפקודה של הספק
רוב לקוחות שולחן העבודה מספקים שורת פקודה שמקבלת שם פרופיל ולעתים קרובות מדי סיסמה. הלקוח הוותיק של Cisco קיבל פועל connect עם ארגומנטים של משתמש וסיסמה; macOS חושף את השירות המובנה דרך networksetup; NetworkManager עונה ל-nmcli. הקריאות האלה חוזרות כשהפקודה מסתיימת, וזה לא אותו רגע שבו המנהרה נעשית שמישה. קראו את התיעוד של הספק עבור הגרסה שאתם פורסים, כי הממשקים האלה משתנים וחלקם מוסרים לגמרי.
nmcli connection up "Work VPN"
networksetup -connectpppoeservice "Work VPN"
היתרון הוא שהספק מכיר את מאגר הפרופילים של עצמו, ולכן הקריאה משתמשת באותה תצורה שה-GUI היה משתמש בה. החסרון הוא שכל ספק ממציא פעלים משלו, וסקריפט שנכתב ללקוח אחד לא עובר לאחר. התייחסו לשכבה הזו כאל הדרך הקצרה ביותר כשהלקוח קבוע והגרסה מוצמדת.
שכבה 2: השירות של מערכת ההפעלה עצמה
ב-Windows החייגן הוא חלק ממערכת ההפעלה, והוא פועל מול רשומה בספר הטלפונים ולא מול מאגר הפרופילים של הספק. זה הופך אותו לנייד יותר בין לקוחות ולקל יותר לסקריפט מחשבון שירות. זה גם אומר שהחיבור יכול להתקיים במקום אחד ולא באחר, מה שמבלבל אנשים שמסתכלים ברשימה הלא נכונה.
rasdial "Work VPN" user pass
Get-VpnConnection -Name "Work VPN" | Select-Object ConnectionStatus
השתמשו במשטח PowerShell כשאתם צריכים ליצור או להסיר את הרשומה במקום לחייג אליה. שכבות WMI ו-cmdlet חושפות את אותם אובייקטים בשמות שונים, וההסרה היא פעולה נפרדת מהניתוק. סקריפט שרק מחייג ישאיר רשומות מיושנות אחרי העברה. בדקו לאיזה מאגר האוטומציה שלכם כותבת לפני שאתם מבטיחים שהניקוי יקרה.
Remove-VpnConnection -Name "Old VPN" -Force
Get-VpnConnection
ב-macOS המקבילה היא רשימת שירותי הרשת, שבה שירות קיים מתחבר לפי שם במקום להיווצר תוך כדי.
פרטי הגישה דולפים בכל שכבה, אז בחרו את הערוץ
כל מה שאתם מעבירים בשורת הפקודה מופיע בטבלת התהליכים לכל משתמש מקומי, ובדרך כלל שורד גם בהיסטוריית ה-shell. החלופה הנתמכת של OpenVPN היא לקרוא את הסוד מקובץ עם --askpass, והקובץ עצמו צריך הרשאות שמתאימות לאמון שאתם נותנים בו. צינור בעל שם מונע כתיבת הסוד לדיסק אבל מאפשר לכל תהליך שיכול לפתוח אותו לכתוב שם. ב-Windows שמרו את הסוד במנהל פרטי הגישה, או בקובץ שרק חשבון השירות יכול לקרוא, ולעולם לא כליטרלי בקובץ batch.
openvpn --config /etc/openvpn/work.conf --askpass /etc/openvpn/work.secret --auth-nocache --daemon
ls -l /etc/openvpn/work.secret
אותו כלל חל על אסימונים וקודים חד-פעמיים: אם האוטומציה צריכה אותם, האוטומציה צריכה ערוץ שאינו ארגומנט של שורת פקודה. סובבו את הסוד כשאתם משנים את המנגנון, כי הערך הישן שכב איפשהו ביומן. סקריפט שעובד ודולף אינו סקריפט עובד.
המתינו למצב, ואז פקחו על בעלים אחד
כל אחת מהקריאות האלה חוזרת לפני שהמנהרה מוכנה, אז סקרו את המצב שהלקוח חושף או בדקו יעד בתוכו עם מגבלת זמן. העתקת קבצים או פתיחת חיבור למסד נתונים מיד אחרי קריאת החיבור היא מירוץ, והיא נכשלת לסירוגין באופן שנראה כמו תקלת רשת.
ip link show tun0
nmcli -t -f GENERAL.STATE connection show "Work VPN"
curl -sS --max-time 5 https://app.internal.example/health -o /dev/null
לניתוק אותה בעיה בכיוון ההפוך: התהליך יכול לצאת לפני שהמסלולים נעלמו. השתמשו בקרסי הלקוח היכן שהם קיימים, כמו סקריפטי up ו-down של OpenVPN או ExecStartPost של יחידת systemd, כי הם רצים בנקודה שבאמת מעניינת אתכם. קרסים רצים עם ההרשאות של מה שהפעיל אותם, ולכן קרס שמפעיל מחדש את הרשת צריך כלל מפורש ולא הנחה. שמרו בדיוק על בעלים אחד לאורך חיי החיבור.
כששני מפקחים מפעילים ועוצרים את אותו פרופיל, התוצאה היא לולאת התחברות מחדש שנקראת כמו תקלה של ספק. ה-runbook מסתיים כשהשכבה מתועדת, לסוד יש ערוץ שאינו argv, תנאי ההמתנה הוא בדיקת מצב עם מגבלת זמן, ותהליך אחד מחזיק במחזור החיים.