在裸机服务器上安装并运行了两个Docker守护程序.
>主Docker守护程序运行我的应用程序容器,将80/443暴露给外界.
>插件Docker守护程序运行客户提供的一些容器,通过80/443与我的应用程序通信.
我想让客户访问Plugin Docker Daemon的API(2376),以便客户可以部署/启动/停止自己的容器.客户只能访问API而不能访问主机(SSH).
我目前面临的问题是,如果客户运行一个像docker这样愚蠢的容器运行-v /:/ host / root ubuntu rm -rf / host / root会怎样.
我的问题是我该如何防止插件Docker守护进程在/ home / user /之外安装root /或任何其他目录,
>是否可以在/ home / user /中启动Docker守护程序?
>我可以使用一些LSM(Linux安全模块SELinux / Apparmor)魔法来阻止docker守护程序挂载除用户home或var / docker / libs之外的部分或全部主机路径吗?
>可以–userns-remap帮我实现目标吗?
>除VM之外,还有其他可用选项吗?
该服务器完全属于单个客户.因此,安全性或数据泄漏不是我主要关注的问题.我真正想要防止的是Plugin Daemon中的某个人正在做一些愚蠢的事情,这会影响我在Main Docker Daemon中运行的容器.我想保持精益,坚持只使用docker工作流程,不要为VM创建额外的工作流程.
解决方法
$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
Dan Walsh在official Red Hat documentation和this article中提供了有关Docker和SELinux的更多信息.