הגדרת SELinux: שירותים נופלים לאחר הפעלת ההגבלות
הפעלת בקרת גישה מחייבת (mandatory access control) על צומת שפעל שנים בלעדיה — לעיתים רחוקות עוברת חלק.
שרת האינטרנט מפסיק לקרוא תיקייה עם תוכן סטטי, מסד הנתונים לא עולה לאחר הפעלה מחדש, ומשימות מתוזמנות מסתיימות בשקט — כשל של שירות לאחר ההפעלה נראה כמו אוסף אקראי של תקלות, אף שלכולן סיבה אחת.
המדיניות מתארת לא משתמשים אלא תהליכים: לאיזו שירות מותר לפתוח קובץ, לתפוס פורט, לפנות לסוקט. תוויות על אובייקטים מוצמדות בעת יצירה והעתקה, ולכן תיקייה שאליה מועלה ה-release מקבלת בקלות תווית של תיקייה זמנית — והשירות שעבורו היא ביתית, אינו רשאי עוד לקרוא ממנה.
מכאן מתחיל החלק הערמומי. במצב סלחני ההפרה רק נרשמת, ולכן הגדרת SELinux עוברת "בהצלחה": המהנדס רואה סטטוס ירוק, ולאחר המעבר למצב אכיפה השירות עולה ומחזיר רק חלק מהבקשות.
הסירובים נכנסים לביקורת החסימות ולא ללוג של האפליקציה, ולכן התקלה מתחפשים בכל מקום מלבד הסיבה האמיתית.
המחיר של תמונה כזו — לא השבתה אחת, אלא הידרדרות הדרגתית. מנהלי המערכת או מכבים את בקרת הגישה המחייבת כליל, ומחזירים את רמת הסיכון המקורית, או מוסיפים הרשאות באקראי. כעבור חודש איש כבר לא יסביר לשם מה ניתנה עוד חוקה, ואבחון מדיניות הופך לארכאולוגיה.
סדר העבודות כאן הפוך מהרגיל: תחילה ביקורת החסימות — מה ולאיזה אובייקט לא קיבל גישה, אילו תוויות באמת מונחות על קבצים ופורטים — ורק אחר כך תיקוני המדיניות. מפרקים כיצד זה נסגר.
אפקט מדיד: מה משתנה לאחר הטמעת מדיניות MAC
לאחר הטמעת בקרת גישה מחייבת SELinux או AppArmor משתנה לא רק מודל ההרשאות אלא גם מדדים תפעוליים מדידים. המדיניות מתארת מה מותר לתהליך מסוים, ללא תלות בחשבון משתמש — ולכן האפקט נראה במדדי האירועים, ולא רק בדוח ביקורת.
משטח התקיפה מתכווץ
הפרדת ההרשאות עוברת לרמת הליבה: השירות רואה רק את התיקיות, הפורטים והסוקטים שלו, והשאר אינו קיים עבורו. תהליך עם אפליקציית ווב שנפרצה כבר לא קורא קונפיגורציות של אחרים ולא כותב לתיקיות מערכת. מחלקת התרחישים "נכנסו דרך השירות — התבססו על המארח" מפסיקה לעבוד בשלב הזה.
זמן התגובה לאירוע מתקצר
בעבר הבדיקה החלה בשאלה "מה בכלל קרה": השוו הרשאות, היסטוריית שינויים, פורטים פתוחים. כעת החסימה נרשמת ביומן עם שם התהליך, הנתיב וסוג הפעולה — נקודת הכניסה והאשם נראים מיד. החקירה מסתכמת במעבר אחד על היומן, בלי איסוף מלא של אירועים מכל המארח.
צפיות של שירותים
המדיניות מפרטת את מערך הפעולות התקין, ולכן השירות מתנהג באותו אופן בסביבת בדיקות ובסביבת הייצור: לאחר עדכון הוא לא מקבל הרשאות מורחבות באקראי. סטיות מהמערך המותר נראות בבירור, ולא צפות כעבור שבועות כשגיאות מוזרות.
מחלקת כשלים שנעלמה
הרצה מחשבון משתמש זר, הרשאות שעברו בירושה לאחר תיקון ידני, סקריפט מתיקייה זרה — מצבים אלו נסגרים על ידי המדיניות עוד לפני הופעתם. צ'ק-ליסט הקבלה של ה-release מתקצר: חלק מהערבויות נותנת הליבה, ולא הנהלים.
מצבי הגנה ודרכי הגדרה: השוואת אפשרויות
בחירת המצב קובעת מה יקרה כאשר תהליך סוטה מההתנהגות המותרת: האירוע ייכנס רק ליומן או שהפעולה תיחסם. עבור SELinux ההגדרה מתחילה בהחלטה הזו — ממנה תלויים סדר ההטמעה והיקף ניתוח ההפעלות.
מה לבחור
| אפשרות | מתי מתאימה | מגבלות |
|---|---|---|
| מצב תצפית סלחני | ריצה ראשונה של חוקים על צומת ייצור, מיפוי פניות | אינה חוסמת דבר: הפרות מצטברות ביומן, וההגנה ככזו טרם קיימת |
| מצב אכיפה | שירותים עם מערך פעולות יציב, צמתים ציבוריים | הפעלות שגויות לאחר עדכוני אפליקציות — נדרש ניתוח ותיקון חוקים |
| פרופילים לאפליקציות בודדות | שירות אחד־שניים עם התנהגות ידועה, בידוד תהליך | מכסים רק את התהליך שלהם, השאר חיים מחוץ להגבלות המחייבות |
| ויתור מלא על בקרה מחייבת | משימות צרות שבהן תחזוקת המדיניות יקרה מהסיכון | ההפרדה מצטמצמת להרשאות רגילות של מערכת הקבצים |
הסדר העובד — להתחיל במצב תצפית סלחני, לאסוף יומן עבור מחזור עבודה שלם של השירות יחד עם עדכונים, ואז להעביר את הצומת למצב אכיפה. חריגים משאירים רק במקום שבו התנהגות התהליך נותחה: חוקה בלתי מוסברת מאפסת את משמעות מדיניות הגישה.
מגבלת הגישה היא שמדיניויות גישה דורשות תחזוקה. עדכון השירות משנה את מערך הפניות, ובלי בעלים לחוקים בקרת הגישה המחייבת הופכת למקור של סירובים — פרופילים לאפליקציות בודדות מצמצמים את שטח הסיכון, אך אינם מחליפים בידוד ועדכונים שוטפים.
סדר הטמעת מדיניויות: מביקורת ועד מסירה
הסדר בנוי כך שאף שירות ייצור לא ייעצר בגלל המדיניות: תחילה אוספים עובדות, אחר כך מגבילים. דילוג על כל שלב מחזיר אותנו לניתוח ידני של סירובים ברגע שבו השירות כבר אינו זמין.
- מיפוי וביקורת קונפיגורציה. רושמים רשימות שירותים שמאזינים לפורטים, תיקיות הנתונים שלהם, סוקטים, תיקיות החלפה ונקודות עיגון. בנפרד מסמנים היכן כבר מונחות הקלות מקומיות — אותן יהיה צריך לבנות מחדש.
- מצב תצפית. מעבירים את המערכת למצב מקל, שבו הפרות רק נרשמות ביומן ולא נחסמות, ומחזיקים אותו לא פחות ממחזור שלם: משימות יומיות, רוטציית יומנים, עדכון חבילות, פריקה לילית.
- איסוף וניתוח הפעלות. רשומות הביקורת מקובצות לפי תהליך וסוג גישה, ומפרידים התנהגות תקינה מיציאות אמיתיות מהפרופיל. בשלב זה רואים אילו שירותים יהיה צריך לתאר מדויק יותר, ואילו כותבים למקומות בלתי צפויים.
- ניסוח חוקים. מודול נפרד לכל שירות במקום מודול כללי אחד: בעת עדכון השירות נבנה מחדש רק הפרופיל שלו, ולא כל המערכת. הקלות מתארות באופן ממוקד, עם הצמדה לנתיב ולתווית.
- בדיקה על העתק של המערכת. מרימים שיבוט, מפעילים חסימה ומריצים רגרסיה: הפעלה, מיגרציות, גיבוי, מעבר בעת כשל של צומת.
- העלאה לפעולה. מפעילים לפי קבוצות שירותים, עם חלון תצפית לאחר כל קבוצה וחזרה מוכנה למצב המקל.
- מסירה. המדיניויות והנוהל לעדכונן עוברים למאגר גרסאות: תרשימי תלויות, יומן ההקלות, סדר הפעולות בעת הוספת שירות חדש.
הגדרת SELinux: קונפיגורציות, מדיניויות, תיעוד
התוצאה של ההטמעה — לא רק שרת פעיל, אלא גם ערכה שלפיה הצוות שלכם מתחזק את המדיניות בלעדינו. להלן רשימת מה שנשאר בידיים לאחר המסירה.
- קובצי קונפיגורציה — מצב נלקח משרת הייצור של הקונפיג המרכזי ופרמטרי האתחול, עם הערות אילו ערכים חובה ואילו מותר לשנות.
- מודולי מדיניות — קוד המקור והמודולים הבנויים לכל שירות, עם הסבר על מה אחראי הדומיין ומדוע החוקה מנוסחת דווקא כך.
- תרשים זרימות גישה — מפה: איזה תהליך פועל באיזה דומיין, לאילו סוגי קבצים ופורטים ברשת הוא פונה, והיכן מונחת החסימה.
- נוהל שינויים — הרצף: לאסוף דוח חסימות על סביבת בדיקות, לבנות מודול, לבדוק ורק אז להעלות לייצור.
- הוראות למשמרת תורנית — מה לחפש ביומן הביקורת, כיצד להבחין בין חסימה שגויה לניסיון ניצול, וכיצד להחליש חוקה באופן ממוקד בלי להסיר את ההגנה כולה.
- נוהל נסיגה — צילום מצב של קונפיגורציה ומדיניויות לפני השינויים, וכן סדר החזרה אם עדכון השירות שובר חוקים קיימים.
- מפת כיסוי — רשימת שירותים תחת מדיניות, רשימה בתהליך עבודה, וציון מפורש של מה שהושאר במכוון ללא הגבלות ומדוע.
מקרה בוחן: השירות הפסיק ליפול לאחר הפעלת ההגבלות
הפרויקט החל בניתוח אירועים: שירות על מארח Linux יצא מכלל פעולה כמה פעמים ברבעון, ובכל פעם הסיבה התגלתה כתהליך שקיבל הרשאות מיותרות לאחר התערבות ידנית.
SELinux היה מופעל, אך במצב של רישום הפרות בלי חסימה — הליבה רשמה אותן והעבירה אותן הלאה, ולכן ביומנים הצטברו רשומות, ובעבור האפליקציה לא היה גבול ממשי.
מה הראו המדדים לפני
שיעור ההשבתות עמד על כמה שעות ברבעון: פרק ממוצע — כ־50 דקות, והשחזור ארך מ־40 דקות, משום שהמהנדס השווה ידנית רשומות ליבה מול הקונפיגורציה. חוקים מתירים פתוחים הצטברו ליותר ממאתיים — מחציתם נוספו "ליתר ביטחון" בתקלה הבאה. אירועים חוזרים שבו כל שניים־שלושה שבועות, והתיקונים לא הפחיתו את מספרם.
מה שינו ומה קיבלו
בנינו מחדש את המדיניות מאפס: השארנו רק הרשאות שאושרו על ידי תיעוד (tracing) של תרחישי העבודה, והעברנו דומיינים למצב אכיפה אחד אחד. מספר החוקים הפתוחים הצטמצם לכארבעים, כל אחד מתואר ומוצמד לתהליך או לתיקייה מסוימים. זמן השחזור לאחר תקלה ירד לכמה דקות: פריסת המדיניות נקראת על ידי אדם, ולא רק על ידי הליבה.
במשך שני רבעוני תצפית לא היה אף אירוע חוזר, ושיעור ההשבתות הצטמצם פי כמה. פרופיל AppArmor על המארח השני נבנה לפי אותה סכמה — מתיעוד קריאות אמיתיות, ולא מחסימה גורפת של הכול.
במה נבדל המצב הסלחני ממצב האכיפה
שני המצבים פועלים על אותה מדיניות טעונה — ההבדל ביניהם רק בשאלה אם פסק הדין מבוצע. במצב תצפית סלחני החוקה נבדקת בכל פנייה לקובץ, לסוקט או לתהליך, אך החסימה אינה מופעלת: האפליקציה מקבלת גישה, והמערכת רק רושמת את עובדת ההפרה. מצב אכיפה על אותו פסק דין עוצר את הפעולה — התהליך מקבל סירוב, ולא יוכל לנסות שוב.
מכאן גם הסיכון המרכזי במעבר: מערך ההרשאות שנראה תקין בתצפית מתחיל לקרוע תרחישים רגילים תחת חסימה. אותו עיקרון ב-AppArmor, שם המקבילה לתצפית היא מצב תלונות: הפרופיל פעיל ורושם הפעלות, אך אינו חוסם גישה.
משמעותו של שלב הביניים היא בדיוק זו — לראות את התנהגות המערכת תחת עומס חי לפני שהחסימות מתחילות לפעול.
יומן ההפעלות הוא המקור האמין היחיד למעבר בין המצבים. ממנו שולפים סירובים עם ציון הדומיין, סוג היעד ומחלקת האובייקט: לפיהם רואים איזה תהליך דופק במקום הלא נכון, והיכן המדיניות פשוט צרה מדי.
תחילה מפרידים הפעלות שגויות מחסימות אמיתיות, מסירים הגבלות מיותרות, בודקים את התוצאה על סביבת בדיקות — ורק אחר כך מפעילים אכיפה.
מעבר בטוח נעשה בשלבים: המצב הכללי נשאר במצב תצפית, ואל האכיפה מעבירים דומיין או שירות אחד אחד. אם לאחר ההפעלה השירות אינו עולה, החזרה לתצפית אורכת שניות ואינה דורשת אתחול — הסירוב חל רק על דומיין מסוים, ולא על כל הצומת. מצב אכיפה מוצדק כאשר היומן נקי מהפעלות בלתי צפויות וקיים נוהל נסיגה מתורגל.
ספקות טכניים נפוצים לפני הטמעת מדיניויות
הספקות כאן טבעיים: בקרה מחייבת היא שכבה שעלולה לחסום את עבודת האפליקציה במקום שבו הרשאות גישה רגילות העבירו אותה. לכן את ההטמעה בונים לא כ"להפעיל ולראות", אלא כמעבר מבוקר בין צמתים ושירותים עם נראות בכל שלב.
אפליקציה לא סטנדרטית לא תעבוד תחת enforcing — מה אז?
תחילה הצומת מועבר למצב permissive: המדיניויות מיושמות אך אינן חוסמות, וכל הסירובים נכנסים ליומן עם תוויות של תהליכים וקבצים. המהנדס מנתח אותם ומתאר מודול מקומי או חוקים לנתיבים ולסוגים הנדרשים — תיקונים ממוקדים, ולא "להרשות הכול". ל-enforcing מעבירים שירות נפרד, ולא את המכונה כולה, כדי לא לגרור אחריו את השאר.
מה יקרה בעת עדכון מערכת ואפליקציות?
המדיניות נשענת על נתיבים, תוויות וסוגים, ולא על build מסוים, ולכן עדכון בדרך כלל אינו שובר אותה. הסיכון מתעורר כאשר משתנה מבנה התיקיות או מופיע תהליך עזר חדש — ואז שוב רואים סירובים ביומן. אנו מריצים את העדכון בסביבת בדיקות עם עומס אמיתי ומשווים את היומן לפני ההעברה לצומת הייצור.
האם נדרשת השבתה, וכמה ארוכה?
ברוב השירותים השבתה אינה נדרשת: פריסת המדיניויות ואיסוף הסירובים מתבצעים על מערכת פעילה ב-permissive. עצירה קצרה אפשרית רק במעבר ל-enforcing בשירותים שאי אפשר להפעיל מחדש תוך כדי תנועה — את החלון מתאמים מראש ומחזיקים אותו בגבולות מחזור תחזוקה אחד.
מי מתחזק את המדיניויות לאחר המסירה?
מודולים, קונפיגורציות ורשימת החריגים נמסרים במערכת בקרת גרסאות עם הערות לכל חוקה. לצד זה ניתנת הוראה לתרחישים טיפוסיים: הוספת שירות, החלפת תיקיית נתונים, הופעת סירובים לאחר עדכון. המהנדסים שלכם מבצעים תיקונים כאלה לפי צ'ק-ליסט, ואנחנו מתחברים למקרים לא סטנדרטיים.
אילו סיכונים נותרים וכיצד לבצע נסיגה?
מדיניות צרה מדי שוברת עבודה בתרחיש נדיר, ורחבה מדי אינה נותנת הגנה; את האיזון בודקים על סביבת בדיקות, ולא על הייצור. החזרה ל-permissive היא פקודה אחת, והצומת ממשיך לשרת עומס. בנפרד אנו מתעדים מצבים לפני ההטמעה, כדי שהנסיגה תארך דקות ולא שעות של ניתוח.
נדון במשימה ונחזור עם הערכה ותוכנית עבודה
לצורך דיון ענייני במשימה נדרשים נתוני מקור: בלעדיהם הערכת לוחות הזמנים הופכת לניחושים, ומדיניויות הגבלת הגישה נכתבות "מהזיכרון" ושוברות שירותי ייצור בעדכון הראשון. שלחו את מה שכבר קיים — קונפיגורציות, פריקות, תרשימים, הערות בצורה חופשית.
- הרכב השירותים והצמתים: אילו אפליקציות פועלות, תחת אילו חשבונות משתמש, אילו תיקיות, פורטים וסוקטים באמת נדרשים להן.
- תרשים המערכת: היכן עוברים הגבולות בין ההיקף, האפליקציה והנתונים, אילו צמתים מחליפים ביניהם תעבורה.
- מצב ההגנה הנוכחי: האם מצב הגבלת ההרשאות מופעל או שעדיין רק מצב ביקורת, אילו פרופילים כבר הוחלו, ומה נוסף ביד.
- מגבלות ואיסורים: מה אסור לשנות — סדר העדכון, זמן השבתה מותר, חלונות עבודה, דרישות זמינות.
- מטרות הגישה: מי ולאילו נתונים צריך לפנות, אילו פעולות חייבות להיות מותרות ואילו חסומות ללא תנאי.
- תפקידים ואוטומציה: איזה עובד מתחזק מה, אילו משימות מבוצעות בסקריפטים ובשם מי.
- יומנים והתראות: לאן נאספים האירועים, האם קיימת בקרה על חסימות ונפילות שירותים לאחר החלפת מדיניות.
הצעד הבא — אנחנו מנתחים את הנשלח, מבהירים את החסר, וחוזרים עם תוכנית עבודה: מעבר מדורג של המדיניויות למצב הגבלה, סכמת נסיגות, הערכת לוחות זמנים לכל מערכת. חלק מהנתונים ניתן לאסוף ישירות על השרתים ולשבץ בתוכנית כשלב נפרד.







