openconnect שנהרג: המסלולים וה-DNS עדיין מצביעים על המנהרה
תהליך openconnect מת יכול להשאיר מסלולים ורשומות resolver מותקנים. עברו את נתיב הכיבוי, שלחו את האות שהבנייה שלכם מתעדת, ונקו.
המנהרה למטה, אבל המכונה עדיין מתנהגת כאילו היא למעלה: חיפוש תלוי עד לפקיעת הזמן, ומסלול מצביע לממשק שכבר לא קיים. זהו החתימה של תהליך openconnect שמת בלי להריץ את עוזר הניתוק שלו. מצב הרשת שהוא יצר עדיין מותקן, ושום דבר אחר במערכת לא יודע איך להסיר אותו.
עברו על המכונה בסדר שבו נוצר המצב: תהליך, קישור, מסלול, resolver. כל שלב אומר לכם אם הלקוח באמת נעלם או רק התנתק מהמסוף שלכם, וההבחנה הזו מחליטה אם לתקן משהו בכלל.
התחילו בתהליך, לא בקונפיגורציה
פתחו מסוף ושאלו מה עדיין רץ לפני שנוגעים במסלול. pgrep -a openconnect מציג כל מופע עם הארגומנטים שלו, מה שמראה את קובץ ה-pid ואת הסקריפט שניתן לו. תהליך שלא ציפיתם לו מסביר את מנהרת הרפאים מהר יותר מכל יומן.
אם שום דבר לא רץ, הסתכלו בקישור. ip link show tun0 אומר לכם אם הממשק שרד, ו- ip route show dev tun0 מציג מסלולים שעדיין קשורים אליו. אחר כך בדקו את ה-resolver עם resolvectl status. רשמו את כל שלוש הפלטים לפני שמשנים אותם, כי הרשומה הזו היא הדרך להבחין מאוחר יותר בין רשומה מיושנת לחדשה.
ממשק שנעלם בדרך כלל לוקח את המסלולים שלו איתו. מסלולים ששורדים את הקישור בדרך כלל אומרים שהתהליך עוד חי או שלקוח שני מחזיק במכשיר.
סקריפט העזר הוא מה שמבטל את השינויים
openconnect לא מסיר בעצמו את הממשק, המסלולים או רשומות ה-resolver. הוא קורא לעוזר חיצוני, /etc/vpnc/vpnc-script בבנייה upstream ו- /usr/share/vpnc-scripts/vpnc-script בחבילות Debian ו-Ubuntu, שנבחר עם -s. אותו סקריפט שמעלה את המנהרה הוא זה שמפרק אותה.
אם התהליך יוצא בלי לקרוא לעוזר הזה, המצב נשאר. מדריך OpenConnect מציין במפורש שניתוב ושירות שמות לא יעבדו כראוי בלי הסקריפט, והוא מתאר את העוזר כרכיב שמפרק את מצב הממשק ביציאה. זו הסיבה שהנתיב חשוב כשאתם מפעילים את הלקוח עם -s.
איזה אות מגיע לנתיב הזה השתנה בין גרסאות. המדריך של 7.06 מתייחס ל-SIGTERM כיציאה מיידית שמדלגת על הסקריפט. בנייות נוכחיות מתעדות INT ו-TERM כעצירה נקייה, שבה הסשן מנותק והעוזר רץ. קראו את פרק SIGNALS בקובץ הבינארי שבאמת יש לכם במקום להניח אחת משתי ההתנהגויות.
man openconnect | sed -n '/^SIGNALS/,/^LIMITATIONS/p'
שלחו את האות שהבנייה שלכם מתעדת
כשאתם יודעים את האות, עצרו את התהליך לפי pid ולא לפי תבנית.
pgrep -a openconnect
sudo kill -INT "$(cat /var/run/openconnect.pid)"
אחר כך חזרו על שלוש הבדיקות מהפרק הראשון במקום לסמוך על סטטוס היציאה. ip link show tun0 אמור להיכשל, ip route show dev tun0 לא אמור להדפיס דבר, ו- resolvectl status לא אמור יותר להציג את קישור ה-VPN.
SIGHUP אינו כפתור עצירה: הוא מנתק, מריץ את הסקריפט ומשאיר את הסשן ניתן לחידוש עם --cookie. SIGUSR2 כופה התחברות מחדש מיידית. SIGKILL מדלג לגמרי על הניקוי, וזה בדיוק המצב שהמאמר הזה עוסק בו.
תקנו את ה-resolver בלי להחליף את resolv.conf
ברוב מערכות Ubuntu /etc/resolv.conf הוא קישור סמלי אל systemd-resolved, לא קובץ שכדאי לערוך. החלפתו שוברת את פתרון השמות לכל רשת, לא רק ל-VPN. במקום זאת הסירו את הרישום של המנהרה:
resolvectl revert tun0
resolvectl query example.com
אם המערכת משתמשת ב-resolvconf במקום ב-systemd-resolved, הרשומה לכל ממשק נשארת עד שאומרים לה לשחרר את הקישור, ו- resolvconf -d tun0 היא הפעולה המקבילה. בדקו איזה resolver בשימוש לפני בחירת הפקודה.
חיפוש שעדיין מכוון לשרת מאחורי הקישור המת תלוי עד לפקיעת הזמן, והעיכוב הזה נראה כמו שרת DNS שבור ולא כמו מסלול שנשאר.
הפכו את הניתוק הבא למשעמם
השאירו את נתיב קובץ ה-pid זהה באתחול ובכיבוי על ידי העברת --pid-file בכל פעם, או הריצו את openconnect תחת יחידה שה- KillSignal שלה תואם לאות שהגרסה שלכם מתעדת. בדיקה קודם בחזית מראה לכם את הודעות הכיבוי שהעוזר מדפיס.
התחברו, התנתקו והריצו את שלוש הבדיקות פעם אחת. יציאה נקייה לא משאירה קישור VPN, מסלול VPN או רשומת resolver של VPN. אם אחד מהשלושה שורד, עכשיו אתם יודעים איזה רכיב לא ניקה. החקירה הבאה מתחילה אז מהתשובה הזו ולא מחיפוש תלוי.