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

הוספה ויצירה הן בדיקות שונות

פתיחת קובץ קיים להוספה דורשת הרשאת כתיבה על הקובץ הזה ועוד הרשאת חיפוש בכל תיקייה בנתיב שלו. יצירת קובץ דורשת כתיבה וחיפוש בתיקייה המכילה, משום שהפעולה מוסיפה לה שם. החלפת קובץ באמצעות שינוי שם נוגעת בשתי התיקיות ובכללי ה-sticky bit שלהן גם כן.

OperationWhat must permit itTypical failure message
Append to an existing logFile write access, path traversalPermission denied on the file
Create a missing logDirectory write and search accessPermission denied on the path
Rename a replacement into placeBoth directories, plus sticky restrictionsPermission denied or operation not permitted

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

ACL של ברירת מחדל תורשות, הן אינן מעניקות

רשומה שמתחילה בקידומת ברירת המחדל מתארת מה אובייקטים חדשים תורשים מהתיקייה. היא אינה מעניקה דבר לתיקייה עצמה, והיא אינה מתקנת את ה-ACL של קובץ שכבר קיים.

namei -l /var/log/openvpn/server.log
getfacl -p /var/log/openvpn
getfacl -p /var/log/openvpn/server.log

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

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

זהה מי כותב באותו רגע

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

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

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

סובב בלי להחזיר את התקלה

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

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

כשקיצור נכשל בכל זאת, הפסק להוסיף הרשאות

כשל בקיצור קובץ שאתה יכול לכתוב בו אינו מוסבר בהרשאות תיקייה, והוספת עוד מהן לא תעזר. הבט בתכונות ובהגבלה במקום: תכונת append-only מתירה כתיבה רק במצב הוספה, ועיגון לקריאה בלבד או sandbox של שירות יכולים לחסום פעולה שה-ACL מתיר.

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

מאמרים קשורים