Linux

如何禁止 Docker 守護程序將主機的根文件系統掛載到容器中

  • November 12, 2019

我有以下容器設置。

在裸機伺服器上安裝並執行了兩個 Docker 守護程序。

  1. Main Docker Daemon執行我的應用程序容器,將 80/443 暴露給外界。
  2. Plugin Docker Daemon執行客戶提供的一些容器,這些容器通過 80/443 與我的應用程序通信。

我想讓客戶訪問Plugin Docker Daemon的 API (2376),以便客戶可以部署/啟動/停止自己的容器。客戶只能訪問 API 而不能訪問主機 (SSH)。

我目前面臨的問題是,如果客戶執行的容器執行不安全的操作,例如docker run -v /:/host/root Ubuntu rm -rf /host/root.

我的問題是如何防止Plugin Docker Daemon在外部掛載根目錄/或任何其他目錄/home/user/

  • 是否可以選擇啟動 Docker 守護程序/home/user/
  • 我可以使用一些 LSM(Linux 安全模組 SELinux/Apparmor)魔法來阻止 docker 守護程序掛載除使用者 home 或 var/docker/libs 之外的部分或所有主機路徑嗎?
  • 可以--userns-remap幫助我實現我的目標嗎?
  • 除了虛擬機,它們還有其他可用的選項嗎?

伺服器完全屬於單個客戶。所以安全或數據洩露不是我最關心的問題。我真正想要防止的是Plugin Daemon中的某個人正在做一些愚蠢的事情,這會影響我在Main Docker Daemon中執行的容器。我想保持精簡併堅持僅使用 docker 的工作流程,並且不會為 VM 創建設置額外的工作流程。

SELinux 將阻止任何未正確標記的內容作為卷安裝在 docker 容器內,作為證明,這裡使用單個文件,相同的策略適用於目錄:

$ sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     allowed
Max kernel policy version:      30

使用範例文件:

$ cat sample_script.sh 
echo 'Hello, world'

它的預設安全上下文是:

$ ls -lrtZ sample_script.sh 
-rw-------. 1 david david unconfined_u:object_r:user_home_t:s0 20 Oct  3 17:18 sample_script.sh

嘗試在容器內使用此文件按預期失敗:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.sh
bash: sample_script.sh: Permission denied

並且將記錄 AVC 拒絕:

$ sudo ausearch -m avc -ts recent
time->Mon Oct  3 17:39:28 2016
type=AVC msg=audit(1475512768.444:784): avc:  denied  { read } for  pid=28720 comm="bash" name="sample_script.sh" dev="dm-13" ino=101062112 scontext=system_u:system_r:svirt_lxc_net_t:s0:c457,c992 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

將安全上下文更改為一個 Docker 後,可以使用:

$ sudo chcon -Rt svirt_sandbox_file_t sample_script.sh
$ ls -lrtZ sample_script.sh 
-rw-------. 1 david david unconfined_u:object_r:svirt_sandbox_file_t:s0 20 Oct  3 17:18 sample_script.sh 

容器現在可以訪問該文件:

$ docker run -v /home/david/sample_script.sh:/sample_script.sh --rm ubuntu bash sample_script.sh
Hello, world

有關 Docker 和 SELinux 的更多資訊,請參閱Red Hat 官方文件和Dan Walsh 的這篇文章

引用自:https://serverfault.com/questions/806811