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

שני מתקינים, שני תיעודים שונים

חבילות Debian מחזיקות רשימת קבצים, ו-purge מוחק בדיוק את מה שהרשימה מציינת בתוספת תצורת החבילה. מתקין shell או חבילת .run אינו מחזיק רשימה כזו; הוא כותב לאן שהוא רוצה, בדרך כלל אל /opt, /usr/local ו-/etc/systemd/system. אף אחד מהנתיבים האלה אינו מופיע ברשימת הקבצים של שום חבילה, ולכן dpkg לא יודע עליהם ולא מדווח עליהם. בסוף יש שני בעלי התקנה על מערכת קבצים אחת, ורק אחד מהם מנהל ספרים.

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

dpkg -S /etc/systemd/system/acmevpn.service
systemctl list-unit-files | grep -i acmevpn

unit וקישור ה-wants שלו הם קבצים נפרדים

הפעלה היא פעולה נפרדת מהתקנה. ה-unit מצהיר על יחסי יעד בקטע [Install], ו-systemctl enable הופך את ההצהרות לקישורים סמליים בתוך תיקיית .wants/ של כל יעד. כעת קיימים שני נתיבים: קובץ ה-unit, והקישור שמושך אותו ליעד אתחול. מחקו רק את הקובץ והקישור מצביע לשום מקום, מה שיוצר תלונה באתחול; מחקו רק את הקישור וה-unit נשאר ניתן להפעלה לפי שם. שניהם חייבים ללכת.

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

systemctl disable --now acmevpn.service
systemctl show -p FragmentPath -p ExecStart acmevpn.service
sudo rm /etc/systemd/system/acmevpn.service
sudo rm /etc/systemd/system/multi-user.target.wants/acmevpn.service
systemctl daemon-reload

קראו את FragmentPath במקום להניח את המיקום, כי הספק אולי כתב אל /usr/lib/systemd/system או /lib/systemd/system ולא אל /etc. מחיקת העותק שציפיתם לו משאירה את העותק האפקטיבי פועל, והתיקון נראה מוצלח עד הטעינה מחדש הבאה. פרטו שוב את קובצי ה-unit לאחר סיום הטעינה, וודאו שהשם אינו מופיע עוד.

מצאו את הקובץ הבינארי שמחזיק את הסידור בחיים

unit מופעל ממשיך להפעיל את הדמון יהיה אשר יהיה מה שבסיס נתוני החבילות חושב. תהליך זה יכול להחזיר את המנהרה, להוסיף מסלולים מחדש או לשחזר כלל kill-switch, וההתנהגות נראית על-טבעית עד שתבדקו את הסידור. עקבו אחר נתיב ExecStart ובדקו אם הקובץ הבינארי עדיין שם, כי קובץ הרצה שהושאר תחת /opt הוא כל מה שהסידור צריך. מחיקת ה-unit עוצרת את ההפעלה המתוזמנת; היא אינה מוחקת את התוכנית.

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

sudo ls -l /opt/acmevpn /usr/local/bin/acmevpn
sudo find /var/lib -maxdepth 2 -iname "*acme*"
systemctl is-enabled acmevpn.service

בחרו בעלים אחד לאתחול ובדקו אותו

שלושה מועמדים יכולים לתבוע את האתחול, והתקנת שלושתם יוצרת מרוץ ולא ביטחון כפול. קובץ הפעלה אוטומטית של שולחן עבודה פועל רק לאחר שמישהו נכנס, unit של systemd פועל קודם אך דורש לקוח שעובד בלי מסך, ורשומת cron @reboot נורית לפי לוח זמנים שעלול להיות שגוי ללקוח רשת. ה-CLI של הספק עשוי גם לדרוש ארגומנט שרת, כי באתחול אין הפעלה קודמת להמשיך אותה. בחרו את המועמד שמתאים לאופן שבו הלקוח מאמת, והשליכו את האחרים.

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

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

רשמו מה ה-purge הבא צריך לצפות

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

שמרו אותה לצד תצורת השירות ולא בתיקייה אישית, ותארכו אותה, כי עדכון של הספק יכול לשחזר unit שמחקתם. השוואה של systemctl list-unit-files להערה הזו כל כמה חודשים תופסת את השחזור בזמן שהתיקון עוד זול.

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