במהלך סדרת הפרקים הזו חקרנו בפרט לפחות שני שיטות של בקרת גישה: הרשאות סטנדרטיות ugo/rwx (Manage Users and Groups – Part 3) ורשימות בקרת גישה (Configure ACL’s on File Systems – Part 7).

אף על פי שהן נחוצות כרשאות רמה ראשונה וכמנגנוני בקרת גישה, יש להן מספר מגבלות שמטרתן להתמודד עם Security Enhanced Linux (נקרא גם SELinux בקיצור).
אחת מהמגבלות הזו היא שמשתמש יכול לחשוף קובץ או תיקייה לפריצת אבטחה דרך פקודת chmod שאינה מפורטת היטב ולכן לגרום להתפשטות בלתי צפויה של זכויות גישה. כתוצאה מכך, כל תהליך שנפתח על ידי משתמש זה יכול לעשות מה שהוא רוצה עם הקבצים שבבעלות המשתמש, ולבסוף תוכנה זדונית או מושחתת באופן אחר יכולה להשיג גישה ברמת שורש לכל המערכת.
עם המגבלות האלה בתודעה, United States National Security Agency (נקראת NSA) פיתחה בתחילה את SELinux, שיטת בקרת גישה חובתית וגמישה, כדי להגביל את יכולת התהליכים לגשת או לבצע פעולות אחרות על אובייקטים במערכת (כמו קבצים, תיקיות, יציאות רשת וכו') למודל הרשאה הנמוך ביותר, שניתן לשנות בהמשך ככל הצורך. בכמה מילים, כל אלמנט במערכת מקבל רק את הגישה הנדרשת לתפקוד.
ב-RHEL 7, SELinux משולב בליבת המערכת עצמה ומופעל במצב Enforcing כברירת מחדל. במאמר זה נסביר בקצרה את המושגים הבסיסיים הקשורים ל-SELinux ולפעולתו.
מצבי SELinux
SELinux יכול לפעול בשלושה מצבים שונים:
- Enforcing: SELinux מסרב גישה על פי כללי מדיניות SELinux, שהם סט ההנחיות ששולטות במנוע האבטחה.
- Permissive: SELinux אינו מסרב גישה, אך סט הסריסים מורשים נרשמים עבור פעולות שהיו מורשות אם הייתה פעולה במצב Enforcing.
- Disabled (מוסבר מאליו).
הפקודה getenforce
מציגה את מצב ה-SELinux הנוכחי, והפקודה setenforce
(עקוב אחריה ב-1 או 0) משמשת לשינוי המצב ל-Enforcing או Permissive, בהתאמה, במהלך ההפעלה הנוכחית בלבד.
כדי לשמור על התמיכה במצבים בין התנתקויות ואתחולים מחדש, יהיה עליך לערוך את קובץ /etc/selinux/config
ולהגדיר את המשתנה SELINUX לערך enforcing, permissive, או disabled:
# getenforce # setenforce 0 # getenforce # setenforce 1 # getenforce # cat /etc/selinux/config

רגילות תשתמש ב-setenforce כדי להפעיל או לכבות בין מצבי SELinux (מצב enforcing ל-permissive וחזרה) כמערך פתרון בעיות ראשון. אם SELinux מוגדר כרגע כ-enforcing ובעת חווית בעיה מסוימת, והבעיה נעלמת כאשר מוגדר ל-permissive, תוכל להיות בטוח שמדובר בבעיה של הרשאות SELinux.
ההקשרים של SELinux
A SELinux context consists of an access control environment where decisions are made based on SELinux user, role, and type (and optionally a level):
- A SELinux user complements a regular Linux user account by mapping it to a SELinux user account, which in turn is used in the SELinux context for processes in that session, in order to explicitly define their allowed roles and levels.
- המושג של תפקיד משמש כמתווך בין תחום ומשתמשי SELinux בכך שהוא מגדיר אילו תחומי תהליכים וסוגי קבצים ניתן לגשת אליהם. זה יגנה את המערכת שלך מפני פגיעה בזכויות הגישה ותקיפות נפילת הזכויות.
- A type defines an SELinux file type or an SELinux process domain. Under normal circumstances, processes are prevented from accessing files that other processes use, and and from accessing other processes, thus access is only allowed if a specific SELinux policy rule exists that allows it.
בואו נראה איך כל זה עובד דרך הדוגמאות הבאות.
דוגמא 1: שינוי יציאת ברירת מחדל עבור דמון ה-sshd
ב-מאבטחים את SSH – חלק 8 סברנו כי שינוי היציאה ברירת המחדל שבה sshd מקשיב עליה היא אחת ההתנגדויות הראשוניות לאבטחת השרת שלך מפני התקפות חיצוניות. בואו נערוך עריכה בקובץ /etc/ssh/sshd_config
ונגדיר את הפורט ל־9999:
Port 9999
שמרו את השינויים, והפעילו מחדש את ה־sshd:
# systemctl restart sshd # systemctl status sshd

כפי שאתם רואים, ה־sshd נכשל להתחיל. אבל מה קרה?
A quick inspection of /var/log/audit/audit.log
indicates that sshd has been denied permissions to start on port 9999 (SELinux log messages include the word “AVC” so that they might be easily identified from other messages) because that is a reserved port for the JBoss Management service:
# cat /var/log/audit/audit.log | grep AVC | tail -1

בנקודה זו ניתן להשבית את SELinux (אבל אל תעשו זאת!) כפי שנסבר לעיל ולנסות להפעיל מחדש את sshd, וזה יעבוד. אולם, כלי ה־semanage יכול לומר לנו מה אנחנו צריכים לשנות כדי שנוכל להתחיל את ה־sshd בכל פורט שבחרנו ללא בעיות.
הריצו את הפקודה
# semanage port -l | grep ssh
, כדי לקבל רשימה של הפורטים בהם SELinux מאפשר ל־sshd להאזין.

לכן נשנה את הפורט בקובץ /etc/ssh/sshd_config
לפורט 9998, נוסיף את הפורט ל־ההקשר ssh_port_t, ואז נפעיל מחדש את השירות:
# semanage port -a -t ssh_port_t -p tcp 9998 # systemctl restart sshd # systemctl is-active sshd

כפי שאתה יכול לראות, השירות הופעל בהצלחה הפעם. דוגמה זו ממחישה את העובדה ש־SELinux שולט במספר פורט TCP להגדרות הפנימיות של סוג הפורט שלו.
דוגמה 2: מאפשר ל־httpd לשלוח גישה ל־sendmail
זאת דוגמה של SELinux שמנהלת תהליך שמקבל גישה לתהליך אחר. אם תרצה ליישם mod_security ו־mod_evasive יחד עם Apache בשרת RHEL 7, עליך לאפשר ל־httpd לגשת ל־sendmail כדי לשלוח התראת מייל בעקבות התקפת (D)DoS. בפקודה הבאה, תשלח את הדגל -P אם אינך רוצה שהשינוי יישמר לאורך הפעלות מחדש של המחשב.
# semanage boolean -1 | grep httpd_can_sendmail # setsebool -P httpd_can_sendmail 1 # semanage boolean -1 | grep httpd_can_sendmail

כפי שניתן לראות מהדוגמה לעיל, הגדרות SELinux boolean (או פשוט בוליאנים) הם כללי דרישה שמוטבעים במדיניות SELinux. ניתן לרשום את כל הבוליאנים באמצעות semanage boolean -l
, ובנוסף אפשר לסנן את הפלט בעזרת פקודת ה־grep.
דוגמה 3: מספק אתר סטטי מתיקייה שונה ממה שמוגדר כברירת מחדל
נניח שאתה מספק אתר אינטרנט סטטי באמצעות תיקייה שונה מהתיקייה הברירת-המחדל (/var/www/html
), למשל /websites (זה עשוי להיות המקרה אם אתה שומר את קבצי הרשת שלך בכונן רשת משותף, לדוגמה, וצריך לכלות אותו ב־/websites).
a). Create an index.html file inside /websites with the following contents:
<html> <h2>SELinux test</h2> </html>
אם תעשה זאת,
# ls -lZ /websites/index.html
תראו שהקובץ index.html סומן עם סוג default_t SELinux, אליו אפאצ'י לא יכול לגשת:

b). Change the DocumentRoot directive in /etc/httpd/conf/httpd.conf
to /websites and don’t forget to update the corresponding Directory block. Then, restart Apache.
c). Browse to http://<web server IP address>
, and you should get a 503 Forbidden HTTP response.
d). Next, change the label of /websites, recursively, to the httpd_sys_content_t type in order to grant Apache read-only access to that directory and its contents:
# semanage fcontext -a -t httpd_sys_content_t "/websites(/.*)?"
e). Finally, apply the SELinux policy created in d):
# restorecon -R -v /websites
עכשיו אנא אתחילו את אפאצ'י מחדש ועיינו ב http://<כתובת IP של שרת האינטרנט>
שוב ותראו את הקובץ HTML מוצג כראוי:

סיכום
במאמר זה עברנו על היסודות של SELinux. שימו לב שכתוצאה מהגודל הרחב של הנושא, תיאור מפורט מלא אינו אפשרי במאמר יחיד, אך אנו מאמינים כי העקרונות שמופיעים במדריך זה יעזרו לך להמשיך לנושאים מתקדמים יותר אם תרצו לעשות זאת.
אם אני יכול, אני ממליץ על שני מקורות חיוניים להתחלה: עמוד ה-NSA SELinux ומדריך המשתמש והמנהל של RHEL 7 SELinux.
אל תהססו להודיע לנו אם יש לכם שאלות או הערות.
Source:
https://www.tecmint.com/selinux-essentials-and-control-filesystem-access/