Коли ви запускаєте контейнер з привілеями, ви вимикаєте такі захисти:
Монтування /dev
У контейнері з привілеями всі пристрої можуть бути доступні в /dev/. Тому ви можете втекти, монтувавши диск хоста.
# docker run --rm -it alpine shls/devconsolefdmqueueptmxrandomstderrstdouturandomcorefullnullptsshmstdinttyzero
# docker run --rm --privileged -it alpine shls/devcachefilesmapperportshmtty24tty44tty7consolemempsauxstderrtty25tty45tty8coremqueueptmxstdintty26tty46tty9cpunbd0ptsstdouttty27tty47ttyS0[...]
Файлові системи ядра тільки для читання
Файлові системи ядра забезпечують механізм для процесу, щоб змінити поведінку ядра. Однак, коли мова йде про процеси контейнера, ми хочемо запобігти їх змінам у ядрі. Тому ми монтуємо файлові системи ядра як тільки для читання всередині контейнера, що забезпечує неможливість модифікації ядра процесами контейнера.
# docker run --rm --privileged -it alpine shmount|grep'(ro'
Маскування над файловими системами ядра
Файлова система /proc вибірково записувана, але для безпеки певні частини захищені від запису та читання, накладаючи на них tmpfs, що забезпечує недоступність чутливих областей для процесів контейнера.
tmpfs — це файлова система, яка зберігає всі файли у віртуальній пам'яті. tmpfs не створює жодних файлів на вашому жорсткому диску. Тому, якщо ви демонтуєте файлову систему tmpfs, всі файли, що в ній знаходяться, втрачаються назавжди.
# docker run --rm -it alpine shmount|grep/proc.*tmpfstmpfson/proc/acpitypetmpfs (ro,relatime)tmpfson/proc/kcoretypetmpfs (rw,nosuid,size=65536k,mode=755)tmpfson/proc/keystypetmpfs (rw,nosuid,size=65536k,mode=755)
# docker run --rm --privileged -it alpine shmount|grep/proc.*tmpfs
Linux можливості
Контейнерні движки запускають контейнери з обмеженою кількістю можливостей, щоб контролювати, що відбувається всередині контейнера за замовчуванням. Привілейовані контейнери мають всіможливості доступні. Щоб дізнатися про можливості, прочитайте:
# docker run --rm -it alpine shapkadd-Ulibcap; capsh--print[...]Current:cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=eipBoundingset=cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap[...]
# docker run --rm --privileged -it alpine shapkadd-Ulibcap; capsh--print[...]Current:=eipcap_perfmon,cap_bpf,cap_checkpoint_restore-eipBounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
[...]
Ви можете маніпулювати можливостями, доступними контейнеру, не запускаючи в режимі --privileged, використовуючи прапори --cap-add та --cap-drop.
Seccomp
Seccomp корисний для обмеженняsyscalls, які контейнер може викликати. За замовчуванням профіль seccomp увімкнено при запуску контейнерів docker, але в режимі привілейованого доступу він вимкнений. Дізнайтеся більше про Seccomp тут:
# docker run --rm -it alpine shgrepSeccomp/proc/1/statusSeccomp:2Seccomp_filters:1
# docker run --rm --privileged -it alpine shgrepSeccomp/proc/1/statusSeccomp:0Seccomp_filters:0
# You can manually disable seccomp in docker with--security-optseccomp=unconfined
Також зверніть увагу, що коли Docker (або інші CRI) використовуються в кластері Kubernetes, seccomp фільтр за замовчуванням вимкнений.
AppArmor
AppArmor - це покращення ядра для обмеження контейнерів до обмеженого набору ресурсів з профілями для кожної програми. Коли ви запускаєте з прапором --privileged, ця захист вимкнена.
# You can manually disable seccomp in docker with--security-optapparmor=unconfined
SELinux
Запуск контейнера з прапором --privileged вимикає мітки SELinux, що призводить до успадкування мітки від контейнерного движка, зазвичай unconfined, що надає повний доступ, подібний до контейнерного движка. У безкореневому режимі використовується container_runtime_t, тоді як у кореневому режимі застосовується spc_t.
# You can manually disable selinux in docker with--security-optlabel:disable
Що не впливає
Простори імен
Простори імен НЕ підлягають впливу прапора --privileged. Навіть якщо у них не ввімкнені обмеження безпеки, вони не бачать усіх процесів на системі або хост-мережі, наприклад. Користувачі можуть вимкнути окремі простори імен, використовуючи прапори контейнерних движків --pid=host, --net=host, --ipc=host, --uts=host.
# docker run --rm --privileged -it alpine shps-efPIDUSERTIMECOMMAND1root0:00sh18root0:00ps-ef
За замовчуванням, контейнерні движки не використовують простори користувачів, за винятком контейнерів без кореня, які потребують їх для монтування файлової системи та використання кількох UID. Простори користувачів, які є невід'ємною частиною контейнерів без кореня, не можуть бути вимкнені і значно підвищують безпеку, обмежуючи привілеї.