AppArmor הוא מודול אבטחה של ליבת Linux שאפשר להשתמש בו כדי להגביל את היכולות של תהליכים שפועלים במערכת ההפעלה של המארח. לכל תהליך יכול להיות פרופיל אבטחה משלו. פרופיל האבטחה מאפשר או אוסר יכולות ספציפיות, כמו גישה לרשת או הרשאות קריאה/כתיבה/הפעלה של קבצים.
אפשר להשתמש ב-AppArmor עם קונטיינרים של Docker שפועלים במופעים של מערכת ההפעלה שמותאמת לקונטיינרים. לכל קונטיינר נתון, אפשר להחיל את פרופיל האבטחה של AppArmor שמוגדר כברירת מחדל ומגיע עם Docker, או פרופיל אבטחה מותאם אישית שאתם מספקים.
שימוש בפרופיל האבטחה של Docker AppArmor שמוגדר כברירת מחדל
כשמפעילים קונטיינר במופע של מערכת הפעלה שמותאמת לקונטיינרים, המערכת מחילה באופן אוטומטי את פרופיל האבטחה של docker-default AppArmor. הפקודה הבאה לדוגמה מריצה קונטיינר עם פרופיל האבטחה docker-default:
docker run --rm -it debian:jessie bash -i
כדי לבדוק את פרופיל האבטחה docker-default, אפשר לנסות לקרוא את הקובץ /proc/sysrq-trigger באמצעות הפקודה cat, באופן הבא:
root@88cef496c1a5:/# cat /proc/sysrq-trigger
הפלט צריך לכלול שגיאה מסוג Permission Denied (אין הרשאה), כמו בדוגמה הבאה:
cat: /proc/sysrq-trigger: Permission denied
החלת פרופיל אבטחה בהתאמה אישית
כדי להחיל פרופיל אבטחה אחר, משתמשים באפשרות apparmor=<profile-name>
של שורת הפקודה כשמריצים את הקונטיינר. בדוגמה הבאה, הפקודה מפעילה קונטיינר עם פרופיל אבטחה בשם no-ping:
docker run --rm -i --security-opt apparmor=no-ping debian:jessie bash -i
מידע נוסף על יצירת פרופיל no-ping שמופיע בדוגמה זמין בהמשך הנושא במאמר יצירת פרופיל אבטחה בהתאמה אישית.
אפשר גם לציין את unconfined עם האפשרות apparmor כדי לציין שהקונטיינר יופעל עם פרופיל אבטחה ללא, כמו בדוגמה הבאה:
docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
צפייה בפרופילי האבטחה הפעילים של AppArmor
כדי לראות איזה פרופיל AppArmor חל על התהליכים במופע של מערכת הפעלה שמותאמת לקונטיינרים, אם בכלל, צריך לבדוק את הקובץ /proc/<pid>/attr/current, כאשר <pid> הוא מזהה התהליך.
נניח שהתהליכים הבאים פועלים במופע (כפי שמוצג בפקודה ps -ef | grep '[b]ash -i'):
root 1903 1897 0 21:58 pts/3 00:00:00 docker run --rm -it debian:jessie bash -i
root 1927 1913 0 21:58 pts/4 00:00:00 bash -i
root 1978 1001 0 22:01 pts/0 00:00:00 docker run --rm -it --security-opt apparmor=unconfined debian:jessie bash -i
root 2001 1988 0 22:01 pts/2 00:00:00 bash -i
אם בודקים את /proc/1927/attr/current, אמורה להופיע הפלט הבא שמציין שהתהליך (pid 1927) הופעל עם פרופיל האבטחה של Docker שמוגדר כברירת מחדל:
# cat /proc/1927/attr/current
docker-default (enforce)
אם בודקים את /proc/2001/attr/current, אמורה להתקבל הפלט הבא שמציין שהתהליך (pid 2001) הופעל ללא פרופיל אבטחה (כלומר, עם האפשרות apparmor=unconfined):
# cat /proc/2001/attr/current
unconfined
יצירת פרופיל אבטחה בהתאמה אישית
אם התהליך דורש פרופיל אבטחה שונה מ-docker-default,
אפשר לכתוב פרופיל מותאם אישית משלכם. כדי להשתמש בפרופיל בהתאמה אישית, צריך ליצור את קובץ הפרופיל ואז לטעון את הקובץ הזה ל-AppArmor.
לדוגמה, נניח שאתם רוצים פרופיל אבטחה שלא מאפשר תנועה גולמית ברשת. הסקריפט הבא יוצר קובץ לפרופיל אבטחה בשם no-ping במיקום /etc/apparmor.d/no_raw_net:
cat > /etc/apparmor.d/no_raw_net <<EOF
#include <tunables/global>
profile no-ping flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
network inet icmp,
deny network raw,
deny network packet,
file,
mount,
}
EOF
אחרי שיוצרים את קובץ פרופיל האבטחה, אפשר להשתמש ב-apparmor_parser כדי לטעון את הפרופיל ל-AppArmor:
/sbin/apparmor_parser --replace --write-cache /etc/apparmor.d/no_raw_net
אחרי הטעינה, אפשר לבדוק את פרופיל no-ping באופן הבא:
$ docker run --rm -i --security-opt apparmor=no-ping debian:jessie ping -c3 8.8.8.8
הפקודה יוצרת מאגר עם פרופיל האבטחה no-ping ומנסה להריץ את ping מתוך המאגר. פרופיל האבטחה צריך לחסום את התנועה, וכתוצאה מכך תופיע שגיאה כמו זו:
ping: Lacking privilege for raw socket.
כדי לוודא שפרופיל האבטחה המותאם אישית שלכם קיים כשמופעלת מכונה של מערכת הפעלה שמותאמת לקונטיינרים, ושומר על ההתמדה שלו גם אחרי הפעלה מחדש, אתם יכולים להשתמש ב-cloud-init כדי להתקין את הפרופיל ב-/etc/apparmor.d. כדי לעשות זאת, מוסיפים סקריפט cloud-config למטא-נתונים של המופע כערך של המפתח user-data.
הסקריפט הבא cloud-config מוסיף את פרופיל no-ping אל /etc/apparmor.d:
#cloud-configs
write_files:
- path: /etc/apparmor.d/no_raw_net
permissions: 0644
owner: root
content: |
#include <tunables/global>
profile no-ping flags=(attach_disconnected,mediate_deleted) {
#include <abstractions/base>
network inet tcp,
network inet udp,
network inet icmp,
deny network raw,
deny network packet,
file,
mount,
}
כדי לוודא שקובץ השירות טוען את הפרופיל המותאם אישית ל-AppArmor ומורה ל-Docker להשתמש בו, מריצים את הפקודות הבאות במופע:
ExecStartPre=/sbin/apparmor_parser -r -W /etc/apparmor.d/no_raw_net
ExecStart=/usr/bin/docker run --security-opt apparmor=no-ping ...
אחרי שמריצים את הפקודות, מפעילים מחדש את המופע ואז אפשר להריץ את הקונטיינר שמוגבל על ידי פרופיל AppArmor המותאם אישית.