כשאנחנו מנסים לפתוח, לערוך, למחוק או להריץ קובץ ומקבלים הודעת `Permission denied`, קל לחשוב שהמחשב פשוט "לא נותן לנו".
בפועל, מאחורי ההודעה עומדת מערכת מסודרת שמנסה לענות על שאלה אחת:
האם לזהות שמבצעת את הפעולה מותר לבצע אותה על המשאב המבוקש?
מערכת ההרשאות היא אחד ממנגנוני ההגנה החשובים ביותר במערכת ההפעלה. היא מפרידה בין משתמשים, מגינה על קובצי מערכת ומגבילה את הנזק שתוכנה תקולה או זדונית יכולה לגרום.
שלושת חלקי בדיקת ההרשאה
בכל ניסיון גישה יש שלושה מרכיבים:
מי? → רוצה לבצע איזו פעולה? → על איזה משאב?לדוגמה:
dina → רוצה לכתוב → /home/evyatar/report.txtמערכת ההפעלה מזהה את המשתמש או התהליך, בודקת את ההרשאות של הקובץ ושל התיקיות בנתיב, ומחליטה אם לאשר או לדחות את הפעולה.
תוכנה אינה פועלת בדרך כלל בכוחות עצמה. היא פועלת תחת זהות המשתמש שהפעיל אותה. אם לעורך טקסט אין אפשרות לשמור קובץ, הסיבה היא בדרך כלל שלמשתמש שמפעיל אותו אין הרשאת כתיבה מתאימה.
קריאה, כתיבה והרצה
במערכות Linux ו-macOS ההרשאות הבסיסיות מסומנות כך:
r = read
w = write
x = executeהרשאת קריאה, `r`, מאפשרת לקרוא את תוכן הקובץ: להציג טקסט, לטעון קובץ הגדרות או לפתוח תמונה.
הרשאת כתיבה, `w`, מאפשרת לשנות את התוכן: לערוך, לקצר או לכתוב מידע חדש.
הרשאת הרצה, `x`, מאפשרת לבקש ממערכת ההפעלה להריץ את הקובץ כתוכנית או כסקריפט. היא אינה הופכת קובץ רגיל לתוכנית תקינה; הפורמט, ה-shebang או קובץ ההרצה עדיין צריכים להיות תקינים, וייתכנו מגבלות נוספות כמו mount עם `noexec`.
בעלים, קבוצה ואחרים
במודל ההרשאות הבסיסי של Unix, כל קובץ מחלק את המשתמשים לשלוש קטגוריות:
user = בעל הקובץ
group = הקבוצה של הקובץ
others = כל שאר המשתמשיםלדוגמה:
-rwxr-x---אחרי הסימן הראשון, ההרשאות מתחלקות לשלוש קבוצות:
rwx לבעלים
r-x לקבוצה
--- לאחריםלכן הבעלים יכול לקרוא, לכתוב ולהריץ; חברי הקבוצה יכולים לקרוא ולהריץ; ואחרים אינם יכולים לגשת.
התו הראשון מציין את סוג האובייקט:
- = קובץ רגיל
d = תיקייה
l = קישור סמלילכן `drwxr-x---` מתאר תיקייה.
איזו קבוצת הרשאות נבדקת?
נניח שקובץ שייך למשתמש `evyatar` ולקבוצה `developers`.
כאשר משתמש מנסה לגשת אליו, המערכת פועלת בדרך כלל כך:
- אם המשתמש הוא הבעלים, נבדקות הרשאות הבעלים.
- אחרת, אם אחת הקבוצות של המשתמש מתאימה לקבוצת הקובץ, נבדקות הרשאות הקבוצה.
- אחרת, נבדקות הרשאות האחרים.
המערכת אינה מחברת את שלוש הקבוצות ואינה בוחרת את ההרשאה הטובה ביותר. אם הבעלים אינו מקבל כתיבה בקטגוריית `user`, הרשאת כתיבה ב-`group` לא משמשת כגיבוי עבורו.
ACL, מנגנוני אבטחה נוספים והרשאות מיוחדות יכולים להוסיף כללים מעבר למודל הבסיסי הזה.
ייצוג מספרי
אפשר לייצג הרשאות גם באמצעות מספרים:
r = 4
w = 2
x = 1מחברים את הערכים:
rwx = 7
rw- = 6
r-x = 5
r-- = 4
--- = 0לכן `rwxr-xr--` מיוצג כ-`754`:
7 = rwx לבעלים
5 = r-x לקבוצה
4 = r-- לאחריםו-`640` מייצג `rw-r-----`: הבעלים יכול לקרוא ולכתוב, הקבוצה יכולה לקרוא, ולאחרים אין גישה.
שינוי הרשאות באמצעות `chmod`
הפקודה `chmod` משנה הרשאות:
chmod 750 deploy.shהפקודה מגדירה `rwxr-x---`.
אפשר גם לבצע שינוי נקודתי:
chmod u+x script.sh
chmod g-w config.txtהפקודה הראשונה מוסיפה לבעלים הרשאת הרצה. השנייה מסירה מהקבוצה הרשאת כתיבה בלי לשנות הרשאות אחרות.
הסימונים הנפוצים הם:
u = בעלים
g = קבוצה
o = אחרים
a = כולםשינוי בעלות באמצעות `chown`
`chmod` משנה הרשאות, אבל אינו משנה למי הקובץ שייך. לשם כך משתמשים ב-`chown`:
chown dina report.txt
chown evyatar:developers app.logהפקודה השנייה מגדירה את `evyatar` כבעלים ואת `developers` כקבוצה. שינוי בעלות דורש בדרך כלל הרשאות מנהל.
הרשאות על תיקיות שונות מהרשאות על קבצים
בתיקייה, המשמעות של אותם סימנים משתנה:
r = לראות את רשימת השמות בתיקייה
w = ליצור, למחוק או לשנות שמות של פריטים
x = לעבור דרך התיקייה ולגשת לפריטים שבתוכהקריאה מאפשרת למנות את השמות שבתיקייה. הרצה, שנקראת לעיתים search או traversal בהקשר הזה, מאפשרת לעבור דרכה ולגשת לפריט מסוים כאשר יודעים את שמו. כתיבה מאפשרת לשנות את רשימת התיקייה.
כדי לפתוח נתיב כמו `/home/evyatar/report.txt`, התהליך צריך בדרך כלל הרשאת `x` על כל תיקייה לאורך הנתיב, וגם את ההרשאה המתאימה על הקובץ עצמו.
למה אפשר לפעמים למחוק קובץ לקריאה בלבד?
נניח שלקובץ יש:
-r--r--r--אף אחד אינו יכול לשנות את תוכנו. אבל אם למשתמש יש הרשאות `w` ו-`x` על תיקיית האב, הוא עשוי להיות מסוגל למחוק את הקובץ.
מחיקה אינה כתיבה לתוכן הקובץ. היא הסרת השם שלו מרשימת התיקייה. לכן ההרשאות המרכזיות למחיקה ולשינוי שם הן בדרך כלל הרשאות תיקיית האב.
יש חריג חשוב: בתיקיות משותפות עם sticky bit, כמו `/tmp`, לא די בהרשאת כתיבה לתיקייה. בדרך כלל רק בעל הקובץ, בעל התיקייה או `root` יכולים למחוק או לשנות את שם הפריט.
תהליך פועל תחת זהות
כאשר תוכנה רצה, מערכת ההפעלה שומרת עבורה זהות והרשאות:
עורך טקסט → פועל כ-evyatar → מנסה לשמור קובץאם ל-`evyatar` יש הרשאת כתיבה, השמירה יכולה להצליח. אם אין לו, היא תיכשל.
לכן הסיכון אינו רק במה שהתוכנה מתוכנתת לעשות, אלא גם באילו הרשאות היא פועלת. שירות שנפרץ יכול בדרך כלל לעשות כל מה שזהות השירות רשאית לעשות.
מה באמת עושה `sudo`?
`sudo` אינו מוחק הרשאות ואינו מבטל את מערכת האבטחה. הוא מבקש להריץ פקודה בזהות אחרת, בדרך כלל `root`, בהתאם למדיניות שהוגדרה.
sudo chown evyatar:developers app.logהפקודה יכולה להצליח משום שהזהות שמבצעת אותה השתנתה. מערכת ההרשאות עדיין פועלת; היא פשוט בודקת כעת זהות חזקה יותר.
זו הסיבה שלא מומלץ להריץ תוכנות שלמות עם `sudo` בלי צורך. אם יש בתוכנה באג או קוד זדוני, גם הוא מקבל הרשאות רחבות. עדיף להעלות הרשאות רק לפעולה המדויקת שדורשת אותן.
עקרון ההרשאה המינימלית
אחד מעקרונות האבטחה המרכזיים הוא Principle of Least Privilege: כל משתמש, תוכנה או שירות צריכים לקבל רק את ההרשאות שהם באמת צריכים.
לדוגמה, שרת אינטרנט שמגיש קבצים מתוך `/var/www/site` צריך אולי לקרוא את קובצי האתר. הוא כנראה אינו צריך לקרוא תיקיות פרטיות, לערוך קובצי מערכת, להתקין תוכנות או לפעול כ-`root`.
אם השרת נפרץ, ההרשאות המוגבלות מצמצמות את הנזק האפשרי.
למה `777` הוא בדרך כלל סימן אזהרה?
777 = rwxrwxrwxכל המשתמשים יכולים לקרוא, לכתוב ולהריץ. לעיתים מפתחים משתמשים ב-`777` כדי להעלים במהירות שגיאת הרשאה. התקלה אולי נעלמת, אבל גם שכבת הגנה משמעותית נעלמת איתה.
במקום זאת צריך לבדוק:
- מי הבעלים?
- מהי הקבוצה?
- איזה process צריך גישה?
- האם דרושה קריאה, כתיבה או הרצה?
- האם ההרשאה צריכה להיות על הקובץ או על התיקייה?
הרשאות ב-Windows ו-ACL
Windows משתמש בדרך כלל ב-ACL, ראשי תיבות של Access Control List. במקום להסתפק רק בבעלים, קבוצה ואחרים, אפשר להגדיר רשימה מפורטת:
Evyatar → קריאה וכתיבה
Dina → קריאה בלבד
Developers → קריאה והרצה
Guests → ללא גישהאפשר להגדיר הרשאות מפורטות כמו קריאה, כתיבה, שינוי, מחיקה, שינוי הרשאות, שינוי בעלות ושליטה מלאה. גם Linux ו-macOS תומכות ב-ACL מעבר למודל הבסיסי של `rwx`.
הרשאות אינן הצפנה
חשוב להבדיל בין שני מנגנונים.
הרשאות גורמות למערכת ההפעלה להחליט אם לאפשר גישה. הצפנה שומרת את התוכן בצורה שאינה קריאה ללא מפתח מתאים.
אם תוקף עוקף את מערכת ההפעלה, מחבר את הכונן למחשב אחר או משיג גישה ישירה לנתונים, הרשאות לבדן לא תמיד יספיקו. במערכות רגישות משתמשים גם בהרשאות וגם בהצפנה.
סיכום
מערכת ההרשאות עונה על השאלה: מי רשאי לעשות מה, על איזה משאב?
- `r`, `w` ו-`x` מייצגות קריאה, כתיבה והרצה או traversal.
- ההרשאות הבסיסיות מחולקות לבעלים, קבוצה ואחרים.
- `chmod` משנה הרשאות ו-`chown` משנה בעלות.
- הרשאות תיקייה שונות במשמעותן מהרשאות קובץ.
- מחיקה ושינוי שם תלויים במידה רבה בהרשאות תיקיית האב.
- תוכנה פועלת תחת זהות והרשאות של process.
- `sudo` משנה את זהות ההרצה; הוא אינו מבטל את ההרשאות.
- `777` הוא בדרך כלל פתרון מסוכן ולא תיקון אמיתי.
- Least Privilege מצמצם את הנזק האפשרי במקרה של תקלה או פריצה.
- הרשאות והצפנה פותרות בעיות שונות ומשלימות זו את זו.
כאשר מבינים את המודל הזה, שגיאות הרשאה מפסיקות להיות הודעות מסתוריות. הן הופכות לבעיה שאפשר לנתח: מי המשתמש, מה הפעולה, על איזה קובץ או תיקייה, ואיזו הרשאה חסרה.