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

התאימו את הלקוח לשלוש השכבות הניתנות לסקריפט

פרופיל מקורי של מערכת ההפעלה, CLI של ספק, לקוח עם GUI בלבד ולקוח עם SSO בדפדפן דורשים ארבע גישות שונות. השניים הראשונים שורדים אתחולים ללא השגחה, ואתחולים ללא השגחה הם כל העניין. השניים האחרים דורשים החלטת תכנון לפני שהם דורשים סקריפט.

What the client exposesWhat to scriptWhat still bites
OS-native connection entryrasdial, scutil --nc, nmcliTunnel is up before DNS and routes settle
Vendor CLI reading stdinCLI wrapped by the scheduler, secret from the credential storePrompt text changes between releases
GUI onlyPinned version plus a state assertionLocale and DPI break the click targets

מסלול ראשון: מערכת ההפעלה כבר מחזיקה בפרופיל

זה המסלול הזול ביותר וזה שרוב האנשים מחמיצים. ב-Windows ‏rasdial "Office" מתחבר ו-rasdial "Office" /disconnect סוגר אותו; rasphone -d "Office" מפעיל את אותה רשומה דרך ממשק החיוג. macOS מציג את השירותים השמורים עם scutil --nc list ומפעיל אחד עם scutil --nc start. Linux מוסר את העבודה ל-NetworkManager.

rasdial "Office" user *
scutil --nc start "Office"
nmcli connection up id Office
nmcli -t -f GENERAL.STATE connection show Office

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

מסלול שני: הספק מספק שורת פקודה

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

printf '%s\n' "$VPN_PASS" | openconnect --protocol=anyconnect \
  --user "$VPN_USER" --passwd-on-stdin vpn.example.com

ל-FortiClient ולחלק מגרסאות GlobalProtect אין CLI נתמך כלל, ולקוח קהילתי או תחליף ברישיון ספק הוא החלטת רכש, לא עקיפה. ב-CI, תנו לחשבון השירות הרשאות לקובץ הבינארי הזה בדיוק ולא לשלף, כדי שארגומנט מוזרק לא יהפוך לפקודת root.

מסלול שלישי: אוטומציית GUI, ולמה היא אחרונה

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

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

מה נשבר אחרי שהמנהרה עולה

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

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

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

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