כלא chroot פשוט ליישום בודד

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

בחרו שורש ומצאו את התלויות

נניח שהתוכנית היא /usr/bin/myapp. הכלא הוא סתם תיקייה שתהפוך ל-/ שלה:

sudo mkdir -p /jail/{bin,lib,lib64,etc,dev,usr/bin}

התוכנית לא תרוץ בלי הספריות המשותפות שהיא נקשרת אליהן. שאלו את המקשר הדינמי מה הן:

ldd /usr/bin/myapp

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

sudo cp /usr/bin/myapp /jail/usr/bin/
for lib in $(ldd /usr/bin/myapp | grep -o '/[^ ]*'); do
    sudo cp --parents "$lib" /jail/
done

cp --parents משחזר את מבנה התיקיות תחת /jail, כך שספרייה מ-/lib/x86_64-linux-gnu/ נוחתת במקום התואם בתוך הכלא. זה כל הטריק: התוכנית הכלואה מחפשת את ספריותיה באותם נתיבים, ועכשיו הנתיבים האלה קיימים בתוך הקופסה.

מעטפת להסתכל בה סביב

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

sudo apt-get install sash
sudo cp /bin/sash /jail/bin/

עכשיו אתם יכולים להיכנס לכלא ולבדוק שעולם התוכנית שלם:

sudo chroot /jail /bin/sash

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

צמתי התקנים

תוכניות רבות צריכות לפחות /dev/null, וכמה צריכות /dev/zero ו-/dev/urandom. אלה אינם קבצים רגילים; שחזרו אותם עם mknod:

sudo mknod -m 666 /jail/dev/null c 1 3
sudo mknod -m 666 /jail/dev/zero c 1 5
sudo mknod -m 644 /jail/dev/urandom c 1 9

המספרים הם מספרי המייג'ור והמיינור של התקן התווים, אותם אלה שה-/dev האמיתי משתמש בהם.

הריצו את התוכנית כלואה

sudo chroot /jail /usr/bin/myapp

התהליך רואה עכשיו את /jail כשורש שלו. הוא אינו יכול לפתוח את /etc/passwd על המארח, אינו יכול לקרוא את תיקיית הבית שלכם, אינו יכול לשוטט במערכת הקבצים, מפני שמבפנים אף אחד מאלה אינו קיים.

מה chroot אינו

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

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

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