כדאי לעיין בדף הזה כדי להכיר את המושגים של 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.
רמות האכיפה
אפשר להטמיע את SELinux במצבים שונים:
- Permissive (מתירנית) – מדיניות האבטחה של SELinux לא נאכפת, רק נרשמת ביומן.
- אכיפה – מדיניות האבטחה נאכפת ונרשמת ביומן. כשלים מופיעים כשגיאות EPERM.
הבחירה הזו היא בינארית וקובעת אם המדיניות תפעל או רק תאפשר לכם לאסוף נתונים על כשלים פוטנציאליים. האפשרות 'מתירנית' שימושית במיוחד במהלך ההטמעה.
סוגים, מאפיינים וכללים
מערכת Android מסתמכת על רכיב Type Enforcement (TE) של SELinux לצורך המדיניות שלה. המשמעות היא שלכל האובייקטים (כמו קובץ, תהליך או שקע) משויך סוג. לדוגמה, כברירת מחדל, סוג האפליקציה הוא untrusted_app. הסוג של תהליך נקרא גם הדומיין שלו. אפשר להוסיף הערה לסוג עם מאפיין אחד או יותר. המאפיינים שימושיים כשרוצים להתייחס לכמה סוגים בו-זמנית.
אובייקטים ממופים למחלקות (לדוגמה, קובץ, ספרייה, קישור סמלי, שקע), וסוגי הגישה השונים לכל מחלקה מיוצגים על ידי הרשאות.
לדוגמה, ההרשאה open קיימת למחלקה file. סוגים ומאפיינים מתעדכנים באופן קבוע כחלק ממדיניות SELinux של Android, אבל הרשאות וסיווגים מוגדרים באופן סטטי ומתעדכנים לעיתים רחוקות כחלק מגרסה חדשה של Linux.
כלל במדיניות מופיע בפורמט הבא:
allow source target:class permissions;
כאשר:
- מקור – הסוג (או המאפיין) של נושא הכלל. מי מבקש גישה?
- Target (יעד) – הסוג (או המאפיין) של האובייקט. למה נדרשת גישה?
- 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 הם חלק מהתמיכה ב-Multi-Level Security (MLS) ב-SELinux. ב-Android מגרסה 12 ואילך, הקטגוריות משמשות ל:
- בידוד נתוני האפליקציה כך שאפליקציה אחרת לא תוכל לגשת אליהם,
- בידוד נתוני האפליקציה ממשתמש פיזי אחד למשתמש פיזי אחר.
ספציפיות
מערכת Android לא משתמשת בכל התכונות ש-SELinux מספקת. כשקוראים מסמכים חיצוניים, חשוב לזכור את הנקודות הבאות:
- רוב המדיניות ב-AOSP מוגדרת באמצעות שפת המדיניות של ליבת המערכת. יש כמה מקרים חריגים שבהם אפשר להשתמש בשפת ביניים נפוצה (CIL).
- לא נעשה שימוש במשתמשים ב-SELinux. המשתמש היחיד שמוגדר הוא
u. כשצריך, משתמשים פיזיים מיוצגים באמצעות השדה categories של הקשר אבטחה. - לא נעשה שימוש בתפקידים ב-SELinux ובבקרת גישה מבוססת-תפקידים (RBAC). מוגדרים שני תפקידי ברירת מחדל שמשמשים:
rלנושאים ו-object_rלאובייקטים. - לא נעשה שימוש ברגישויות של SELinux. הרגישות שמוגדרת כברירת מחדל
s0תמיד מוגדרת. - לא נעשה שימוש בערכים בוליאניים של SELinux. כשמגדירים מדיניות למכשיר, היא לא תלויה במצב של המכשיר. כך קל יותר לבצע ביקורת על כללי המדיניות ולנפות באגים.