systemd מפסיק את שירות ה-VPN: התאימו את Type= ללקוח
יחידת VPN בעליית המערכת הופכת ללא פעילה כאשר Type= אינו מתאים לאורך החיים של הלקוח. התאימו את הסוג, תקנו את הבעלות וסדרו את השירות אחרי המנהרה.
יחידות יכולות להיראות תקינות, systemctl start יכול לדווח על הצלחה, ובעוד עשר שניות השירות יושב לא פעיל. או שהוא מופעל מחדש כל חצי דקה עד שמגבלת ההפעלה עוצרת אותו. אף אחת מההתנהגויות אינה תקלת רשת: היחידה מתארת אורך חיים של תהליך שאינו תואם את מה שהלקוח באמת עושה. הלקוח עשוי לבצע fork ולצאת, או להגדיר את הסשן ולצאת מיד.
למה היחידה הופכת ללא פעילה שניות אחרי הפעלה מוצלחת
systemd מסיק את המצב מהתהליך שהוא הפעיל, ולכן Type= הוא טענה על התהליך הזה ולא תיעוד. עם Type=simple היחידה נחשבת פעילה כל עוד הפקודה רצה והופכת ללא פעילה כשהיא חוזרת. לכן לקוח שמעביר את החיבור לעוזר ויוצא נראה כמו קריסה, גם כשהמנהרה פועלת. אז היומן מציג דפוס של הפעלה ועצירה שנקרא כמו קובץ בינארי פגום.
קראו את סוג היחידה לצד התנהגות הלקוח לפני שאתם נוגעים בתצורת הרשת.
בחרו את הסוג שמתאים ללקוח
שני דפוסים מכסים את רוב ממשקי ה-CLI של ספקים: פקודה שמגדירה סשן ויוצאת, ופקודה שמבצעת fork לעוזר לפני שהיא חוזרת. כל אחד מהם דורש צורת יחידה אחרת.
[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/usr/bin/protonvpn-cli connect -f
ExecStop=/usr/bin/protonvpn-cli disconnectoneshot יחד עם RemainAfterExit=true משאיר את היחידה פעילה אחרי שהפקודה חוזרת, מה שמתאים לדפוס הגדר-וצא, ופקודת העצירה נותנת לשירות כיבוי נקי. לקוח שמבצע fork שומר על אותה צורה אך זקוק ל-Type=forking כדי ש-systemd יעקוב אחר הילד. הגדירו Restart=on-failure, RestartSec=30 ו-StartLimitBurst סופי, כדי שהפסקה של הספק לא תהפוך ללולאת הפעלות מחדש שקבורה את השגיאה.
לעולם אל תתנו ללקוח בפיקוח להפוך לדמון
מפקחים מחוץ ל-systemd נתקלים באותה חומה. סקריפט הרצה של runit שמפעיל לקוח שהפך לדמון חוזר מיד למפקח, שקרוא את החזרה כקריסה ומפעיל עותק נוסף. כל מפקח מצפה להחזיק בתהליך החזית, כפי ש-sshd -D נשאר מלפנים. הסירו את דגל הדמון מהפקודות שבפיקוח והשאירו למפקח את עבודת הרקע. סקריפטי עטיפה שחוזרים לפני שהמנהרה קיימת יוצרים את אותה מבוכה.
תהליך שמתנתק מעצמו בלתי נראה לכל מה שהיה אמור להשגיח עליו.
הסשן מסתיים ולוקח איתו את המנהרה
סשן שולחן עבודה מחזיק בלקוח שהוא מפעיל. סיימו את ההתחברות וה-bus של הסשן נעלם, ולוקח איתו את המנהרה, מה שמסביר למה החיבור של לקוח גרפי נופל לעתים קרובות כשהחלון האחרון נסגר. שרתים צריכים להשתמש ביחידת מערכת או בפרופיל NetworkManager שעולה מעצמו. יחידת משתמש הגיונית רק כשהמנהרה אמורה להסתיים עם ההתחברות, לכן קשרו אותה ליעד הסשן הגרפי וציינו זאת בתיאור שלה.
משתמש השירות הוא החצי השני של אותה בעיה. מפתח בבעלות root עם מצב 0600 אינו קריא ליחידה שרצה תחת חשבון אחר, לא משנה מה sudo השיג בקונכייה שלכם.
systemctl cat openvpn-server@work
sudo chown -R openvpn:network /etc/openvpn/server
sudo find /etc/openvpn -type f -perm /077 -lsסדרו את התלויים אחרי שהכתובת קיימת
כשדמון נקשר לכתובת מנהרה שעדיין לא נוצרה, הוא יוצא עם Cannot assign requested address. התיקון הוא סדר מפורש, לא לולאת ניסיונות חוזרים.
[Unit]
After=network.target [email protected]
Requires=sys-devices-virtual-net-wg0.deviceAfter= מסדר את המשימות, בעוד Requires= ביחידת ההתקן קושר את התלוי לקיומו של הממשק, וזה חזק יותר מלהמתין ליעד הרשת בלבד. טענו מחדש את המנהל אחרי העריכה והפעילו מחדש את השירות התלוי, ואז קראו את היומן שלו במקום להניח שהסדר עבד. שלחו את הפלט של הלקוח ליומן עם StandardOutput=journal או אפשרות לוג, כי לקוח בפיקוח שכותב לקובץ שאיש אינו פותח נראה בדיוק כמו כזה שמעולם לא הופעל.
אחר כך הפעילו מחדש פעם אחת ואמתו שהיחידה פעילה אחרי שהתקן המנהרה מופיע. תיקון שאומת רק עם systemctl start לא בדק את סדר האתחול שהוא היה אמור לתקן.