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

שני מודלים, בעלים אחד של ההחלפה

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

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

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

החליטו היכן הזהות משתנה

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

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

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

יכולות הן גבולות, לא מענקים

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

מה שבאמת מכניס יכולת לסט הסביבתי של שירות הוא AmbientCapabilities=. מדריך ההרצה של systemd מתעד את שתי ההוראות בנפרד, וההבחנה הזו מסבירה את רוב העצות המבלבלות על יכולות ברשת.

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

מפו סמכות לאורך מחזור החיים

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

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

השתמשו בחשבון ייעודי ולא בחשבון משותף. מפתחי OpenVPN מזהירים מפני ההרגל להשתמש ב-nobody כדוגמה כללית, מפני ששירותים אחרים במארח עשויים כבר לרוץ תחת אותו חשבון והבידוד שאתם חושבים שיש לכם אינו שם.

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

כתבו את התוכנית ושמרו על גישת שחזור

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

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

הצלחה היא מחזור חיים מובן של סמכות מינימלית, לא תהליך שבמקרה רץ תחת שם שאינו root.

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