מושגים של SELinux

כדאי לעיין בדף הזה כדי להכיר את המושגים של SELinux.

בקרת גישה חובה

‫Security Enhanced Linux (SELinux) היא מערכת חובה לבקרת גישה (MAC) למערכת ההפעלה Linux. מערכת MAC שונה ממערכת בקרת הגישה (DAC) המוכרת של לינוקס. במערכת DAC, קיים מושג של בעלות, שבו הבעלים של משאב מסוים שולט בהרשאות הגישה שמשויכות אליו. בדרך כלל מדובר בהרשאות גסות שעלולות להוביל להעלאת הרשאות לא מכוונת. לעומת זאת, מערכת MAC מתייעצת עם רשות מרכזית כדי לקבל החלטה לגבי כל ניסיון גישה.

‫SELinux הוטמעה כחלק ממסגרת Linux Security Module‏ (LSM), שמזהה אובייקטים שונים של ליבה ופעולות רגישות שמתבצעות בהם. בנקודה שבה כל אחת מהפעולות האלה אמורה להתבצע, נקראת פונקציית LSM hook כדי לקבוע אם הפעולה צריכה להיות מותרת על סמך המידע שמאוחסן לגביה באובייקט אבטחה אטום. ‫SELinux מספק הטמעה של ה-hooks האלה וניהול של אובייקטי האבטחה האלה, שמשולבים עם המדיניות שלו כדי לקבוע את החלטות הגישה.

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

ב-Android מגרסה 4.3 ואילך, ‏SELinux מספקת בקרת גישה מחייבת (MAC) מעל סביבות מסורתיות של בקרת גישה לפי שיקול דעת (DAC). לדוגמה, כדי לכתוב למכשירים של בלוקים גולמיים, התוכנה צריכה בדרך כלל לפעול כחשבון משתמש מסוג root. בסביבת Linux מסורתית שמבוססת על DAC, אם חשבון משתמש הבסיס נפרץ, המשתמש יכול לכתוב לכל מכשיר בלוק גולמי. עם זאת, אפשר להשתמש ב-SELinux כדי לתייג את המכשירים האלה, כך שהתהליך שהוקצו לו הרשאות root יוכל לכתוב רק לאלה שצוינו במדיניות המשויכת. כך התהליך לא יכול לדרוס נתונים והגדרות מערכת מחוץ למכשיר הבלוק הגולמי הספציפי.

תרחישים לדוגמה

רמות האכיפה

אפשר להטמיע את SELinux במצבים שונים:

  • Permissive (מתירנית) – מדיניות האבטחה של SELinux לא נאכפת, רק נרשמת ביומן.
  • אכיפה – מדיניות האבטחה נאכפת ונרשמת ביומן. כשלים מופיעים כשגיאות EPERM.

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

סוגים, מאפיינים וכללים

מערכת Android מסתמכת על רכיב Type Enforcement ‏ (TE) של SELinux לצורך המדיניות שלה. כלומר, לכל האובייקטים (כמו קובץ, תהליך או שקע) משויך סוג. לדוגמה, כברירת מחדל, סוג האפליקציה הוא untrusted_app. הסוג של תהליך נקרא גם הדומיין שלו. אפשר להוסיף הערה לסוג עם מאפיין אחד או יותר. המאפיינים שימושיים כשרוצים להתייחס לכמה סוגים בו-זמנית.

אובייקטים ממופים למחלקות (לדוגמה, קובץ, ספרייה, קישור סמלי, שקע), והסוגים השונים של גישה לכל מחלקה מיוצגים על ידי הרשאות. לדוגמה, ההרשאה open קיימת למחלקה file. סוגים ומאפיינים מתעדכנים באופן קבוע כחלק ממדיניות SELinux של Android, אבל הרשאות וסיווגים מוגדרים באופן סטטי ומתעדכנים לעיתים רחוקות כחלק מגרסה חדשה של Linux.

כלל במדיניות מופיע בפורמט הבא: allow source target:class permissions; כאשר:

  • מקור – הסוג (או המאפיין) של נושא הכלל. מי מבקש גישה?
  • יעד – הסוג (או המאפיין) של האובייקט. למה נדרשת גישה?
  • Class – סוג האובייקט (לדוגמה, קובץ, socket) שאליו מתבצעת גישה.
  • הרשאות – הפעולה (או קבוצת הפעולות) (לדוגמה, קריאה, כתיבה) שמבוצעת.

דוגמה לכלל:

allow untrusted_app app_data_file:file { read write };

ההגדרה הזו מציינת שלאפליקציות יש הרשאה לקרוא ולכתוב קבצים עם התווית app_data_file. יש סוגים אחרים של אפליקציות. לדוגמה, isolated_app משמש לשירותי אפליקציות עם isolatedProcess=true במניפסט שלהם. במקום לחזור על הכלל עבור שני הסוגים, מערכת Android משתמשת במאפיין בשם appdomain לכל הסוגים שכוללים אפליקציות:

# Associate the attribute appdomain with the type untrusted_app.
typeattribute untrusted_app appdomain;

# Associate the attribute appdomain with the type isolated_app.
typeattribute isolated_app appdomain;

allow appdomain app_data_file:file { read write };

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

  • domain – מאפיין שמשויך לכל סוגי התהליכים,
  • file_type – מאפיין שמשויך לכל סוגי הקבצים.

פקודות מאקרו

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

allow appdomain app_data_file:file rw_file_perms;

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

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

הקשר וקטגוריות האבטחה

כשמבצעים ניפוי באגים במדיניות SELinux או כשמתייגים קבצים (באמצעות file_contexts או כשמבצעים ls -Z), יכול להיות שתיתקלו בהקשר אבטחה (שנקרא גם תווית). לדוגמה: u:r:untrusted_app:s0:c15,c256,c513,c768. הפורמט של הקשר אבטחה הוא: user:role:type:sensitivity[:categories]. בדרך כלל אפשר להתעלם מהשדות user, role ו-sensitivity של הקשר (ראו ספציפיות). הסבר על השדה type מופיע בקטע הקודם. categories הם חלק מהתמיכה באבטחה רב-שכבתית (MLS) ב-SELinux. ב-Android מגרסה 12 ואילך, הקטגוריות משמשות ל:

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

ספציפיות

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

  • רוב כללי המדיניות ב-AOSP מוגדרים באמצעות שפת המדיניות של ליבת המערכת. יש כמה חריגים לשימוש בשפת ביניים נפוצה (CIL).
  • לא נעשה שימוש במשתמשים ב-SELinux. המשתמש היחיד שמוגדר הוא u. כשצריך, משתמשים פיזיים מיוצגים באמצעות השדה categories של הקשר האבטחה.
  • לא נעשה שימוש בתפקידים ב-SELinux ובבקרת גישה מבוססת-תפקידים (RBAC). מוגדרים שני תפקידי ברירת מחדל שמשמשים את המערכת: r לנושאים ו-object_r לאובייקטים.
  • לא נעשה שימוש ברגישויות של SELinux. רגישות ברירת המחדל s0 תמיד מוגדרת.
  • לא נעשה שימוש בבוליאנים של SELinux. כשמגדירים מדיניות למכשיר, היא לא תלויה במצב המכשיר. כך קל יותר לבצע ביקורת על כללי המדיניות ולנפות באגים.