כדאי לעיין בדף הזה כדי להכיר את המושגים של SELinux.
בקרת גישה חובה
Security Enhanced Linux (SELinux) היא מערכת של בקרת גישה חובה (MAC) למערכת ההפעלה Linux. כמערכת MAC, היא שונה ממערכת בקרת הגישה הדיסקרטיטיבית (DAC) המוכרת של Linux. במערכת DAC יש מושג של בעלות, שבמסגרתו הבעלים של משאב מסוים שולט בהרשאות הגישה שמשויכות אליו. בדרך כלל, הרשאות הגישה הן ברמת גסה ועלולות לגרום להסלמת הרשאות לא מכוונת. עם זאת, מערכת MAC מתייעצת עם רשות מרכזית כדי לקבל החלטה לגבי כל ניסיונות הגישה.
SELinux יושם כחלק מהמסגרת של מודול האבטחה של Linux (LSM), שמזהה אובייקטים שונים בליבה ופעולות רגישות שמבוצעות בהם. בנקודה שבה כל אחת מהפעולות האלה מתבצעת, מתבצעת קריאה לפונקציית ה-hook של LSM כדי לקבוע אם צריך לאפשר את הפעולה על סמך המידע שלה שנשמר באובייקט אבטחה אטום. SELinux מספק הטמעה של ה-hooks האלה וניהול של אובייקטי האבטחה האלה, שמשתלבים עם המדיניות שלו כדי לקבוע את החלטות הגישה.
יחד עם אמצעי אבטחה אחרים של Android, מדיניות בקרת הגישה של Android מגבילה מאוד את הנזק הפוטנציאלי של מכונות וחשבונות שנפרצו. שימוש בכלים כמו אמצעי הבקרה על הגישה השרירותית והחובה של Android מאפשר לכם ליצור מבנה שיבטיח שהתוכנה תפעל רק ברמת ההרשאה המינימלית. כך אפשר לצמצם את ההשפעות של התקפות ולהפחית את הסבירות לכך שתהליכים שגויים ימחקו או אפילו ישדרו נתונים.
ב-Android מגרסה 4.3 ואילך, SELinux מספק אמצעי בקרת גישה חובה (MAC) על סביבות מסורתיות של בקרת גישה שרירותית (DAC). לדוגמה, בדרך כלל תוכנה צריכה לפעול כחשבון המשתמש root כדי לכתוב למכשירי בלוק גולמיים. בסביבת Linux מסורתית שמבוססת על DAC, אם משתמש root נפרץ, הוא יכול לכתוב בכל מכשיר בלוק גולמי. עם זאת, אפשר להשתמש ב-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 – סוג האובייקט (לדוגמה, קובץ, שקע) שאליו מתבצעת הגישה.
- הרשאות – הפעולה (או קבוצת הפעולות) (למשל, קריאה, כתיבה) שמתבצעת.
דוגמה לכלל:
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 Notebook.
הקשר וקטגוריות של אבטחה
כשמנפים באגים בכללי מדיניות של 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 מוגדרים באמצעות Kernel Policy Language. יש כמה יוצאים מן הכלל לשימוש ב-Common Intermediate Language (CIL).
- לא נעשה שימוש במשתמשים של SELinux. המשתמש היחיד שהוגדר הוא
u
. במקרים הנדרשים, משתמשים פיזיים מיוצגים באמצעות השדה categories של הקשר אבטחה. - לא נעשה שימוש בתפקידים של SELinux ובבקרת גישה מבוססת-תפקידים (RBAC). מוגדרים שני תפקידים שמוגדרים כברירת מחדל, ומשתמשים בהם:
r
לנושאים ו-object_r
לאובייקטים. - לא נעשה שימוש ברגישויות של SELinux. רגישות ברירת המחדל של
s0
תמיד מוגדרת. - לא נעשה שימוש בערכים הבוליאניים של SELinux. כשמגדירים מדיניות למכשיר, היא לא תלויה במצב של המכשיר. כך קל יותר לבצע ביקורת ולפתור באגים במדיניות.