ה-DNS של OpenVPN נשאר אחרי SIGKILL: בדקו קודם את הבעלים
SIGKILL לא יכול להריץ את ה-hook down של OpenVPN, אבל systemd-resolved עשוי להפיל DNS לכל קישור בכל זאת. החליטו מה יצא, מי הבעלים של הפותר, ומה נשאר.
ה-DNS מפסיק לפתור אחרי שקליינט OpenVPN נהרג, והאינסטינקט הראשון הוא לשכתב את /etc/resolv.conf. השינוי הזה יכול לשבור פותר שעובד בזמן שהמצב המיושן האמיתי נמצא במקום אחר. השאלה שצריך ליישב קודם היא מי הבעלים של הגדרות ה-DNS שהמנהרה התקינה, והאם ליציאה שדילגה על הניקוי הייתה משמעות אמיתית.
שלושה תנאים מכריעים את התיקון: האות שסיים את התהליך, רכיב הפותר שקיבל את ההגדרות, והאם קישור המנהרה עדיין קיים. ענו עליהם בסדר הזה והתיקון בדרך כלל מגיע בלי לגעת בקובץ גלובלי.
החליטו איזה סוג יציאה התרחש
במהדורת Community של OpenVPN, גם SIGINT וגם SIGTERM הם בקשות ליציאה מסודרת. אי אפשר לתפוס את SIGKILL: לא ניתן לחסום או לטפל בו, ולכן שום שגרת כיבוי לא מקבלת הזדמנות לרוץ. Ctrl+C רגיל במסוף בחזית מייצר SIGINT, בעוד שמפקח שמפסיק להמתין בדרך כלל מסלים ל-SIGKILL. ההבדל חשוב כי רק המקרה השני מבטיח שה-hooks דולגו.
הרצה בתוך screen או tmux לא משנה איזה אות Ctrl+C שולח. בדקו מה התהליך קיבל בפועל ולא מה המסוף עושה בדרך כלל.
כששירות או מנהל חיבורים מריץ את המנהרה, עצרו את החיבור האחד הזה דרך הבעלים שלו במקום להרוג את ה-pid. מנהל עשוי להעלות את התהליך מחדש, ולהשאיר לכם מנהרה חדשה ומצב פותר מבלבל. תהליך עצמאי צריך רק בקשת סיום רגילה כדי שהניקוי ירוץ.
החליטו מי הבעלים של הפותר
systemd-resolved, סקריפט בסגנון resolvconf ושכתוב קובץ פשוט הם שלושה בעלים שונים. הראשון מחזיק הגדרות לכל קישור בזיכרון ומפיל אותן כשהממשק נעלם. השני מחזיק רשומות שנשארות עד שמשהו מסיר אותן. השלישי כותב קובץ ומשאיר את השחזור למי שכתב אותו.
זהו את הבעלים לפני בחירת פקודת תיקון. לאותו סימפטום יש שלוש תשובות נכונות שונות בהתאם למי שנמצא בשימוש.
VPN שמנוהל ב-NetworkManager עשוי כבר להחזיק בשינויי הפותר. הוספת עוזר שני מעליו יוצרת שני בעלים שמתחרים על אותו קישור, ומצבו של המפסיד חוזר להופיע בחיבור מחדש הבא. אם מנהל אחראי, תקנו את ההגדרה במנהל ולא בסקריפט.
מה ה-hook down יכול לעשות ומה לא
הסקריפט down רץ פעם אחת אחרי שהתקן TUN/TAP נסגר. הוספת down-pre הופכת את הסדר הזה ומריצה את הסקריפט כשהתקן עדיין קיים, מה שדורשים עוזרים שזקוקים לקישור החי.
אף אחת מההנחיות לא גורמת ל-hook לרוץ אחרי SIGKILL. גם ההרשאות לא משוחזרות על ידי down-pre: אם הדמון יורד אל user או group או נכנס אל chroot, ה-hook רץ עם מה שההרשאה הזו משאירה לו. Hook שנקרא עדיין עלול להיכשל בעדכון הפותר. המדריך של OpenVPN מכסה את האותות ואת מחזור החיים של הקריאה החוזרת.
בדקו את השגיאה של ה-hook עצמו לצד סטטוס היציאה של התהליך. ניקוי חסר וניקוי כושל נראים אותו דבר בפותר ושונים ביומנים.
בדקו את המצב שבאמת נשאר
במערכת שמשתמשת ב-systemd-resolved, resolvectl status מראה איזה קישור עדיין נושא את שרתי ה-DNS של ה-VPN או תחומי הניתוב. הקישור הזה עשוי להיות של חיבור שכבר איננו, או של מנהרה אחרת שעדיין פעילה.
ממשק שנעלם לוקח איתו את התצורה שלו לכל קישור, ולכן hook שדולג יכול להתקיים לצד DNS נקי. אם הקישור עדיין רשום והוא בבעלות בלעדית של החיבור שנעצר, המנהל שבבעלותו צריך להסיר אותו. אם סקריפט ישן יותר שכתב מחדש קובץ פותר גלובלי, חפשו במקום זאת את שלב השחזור המתועד של אותו סקריפט.
שחזרו בלי לגנוב קישור אחר
כשההגדרות לכל קישור באחריותכם, resolvectl revert לוקח את שם הקישור ומנקה את תצורת ה-DNS בזמן ריצה עבור הממשק הזה. זו פעולה בזמן ריצה ולא עריכת פרופיל, ולכן תצורת החיבור המתמשכת נשארת ללא שינוי. אם תנקבו בקישור הלא נכון תנקו את ה-DNS של מנהרה שעובדת, ולכן השם מגיע מפלט הסטטוס.
ודאו ש-/etc/resolv.conf הוא קישור סמלי מנוהל לפני עריכתו, ואז עצרו את הקליינט כרגיל פעם נוספת והביטו שוב ב-DNS. אם העצירה השנייה מנקה, הבעיה הקודמת הייתה היציאה הכפויה ולא התצורה.