Docker最新安全性能調整分析
作者通過對Docker的最新安全更新的深入分析與探索,總結了四條有關Docker安全更新的調整建議,包括調整能力、調整SELinux的標簽、多級安全模式、調整命名空間。
自我發表前兩篇有關Docker安全系列的文章之后,至今已有一段時間。本文更新了自那以后有關Docker的新增內容,并且介紹了全新功能,其中涵蓋了與上游Docker的合并過程。
調整能力
在前面的文章中,我介紹了基于Linux功能的容器分離。借助Linux功能,你可以分離根用戶權限,形成更小的特權群。目前,在默認情況下,Docker容器只擁有以下功能。
CHOWN, DAC_OVERRIDE, FSETID, FOWNER, MKNOD, NET_RAW, SETGID, SETUID, SETFCAP, SETPCAP, NET_BIND_SERVICE, SYS_CHROOT, KILL, AUDIT_WRITE
在某些情況下,你可能要調整此列表,例如,如果你正在構建一個運行ntpd或crony的容器,那么需要能夠修改主機的系統時間。由于需要CAP_SYS_TIME,該容器將無法運行。在Docker的舊版本中,容器必須在--privileged模式下運行,該模式關閉了所有的安全策略。
在Docker1.3版本中添加了--cap-add和--cap-drop。現在為了運行ntpd容器,你可以只需運行:
docker run -d --cap-add SYS_TIME ntpd
其中只將SYS_TIME功能添加到了你的容器中。
另如,如果你的容器沒有更改UID/GID的任何進程,你可以從容器中刪除這些功能,使其更加安全。
docker run --cap-drop SETUID --cap-drop SETGID --cap-drop FOWNER fedora /bin/shpscap | grep 2912
5417 2912 root sh chown, dac_override, fsetid, kill, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap</pre>
或者你可以刪除所有的功能后,再進行一一添加。docker run --cap-drop ALL --cap-add SYS_TIME ntpd /bin/shpscap | grep 2382
5417 2382 root sh sys_time</pre>
調整SELinux的標簽
與調整功能相類似,我們已經新增了調整SELinux標簽的能力。
如果你已經看過SELinux coloring book(譯注:有關強制執行SELinux政策的文章,此文圖文并茂,易于理解),那么你會了解,我們可以通過類型和MCS/MLS級別分離進程。我們使用類型以保護主機免受容器的干擾。但是,我們也可以調節類型以控制允許進入和離開容器的網絡端口。目前,我們都以svirt_net_lxc_t運行所有的容器。這種類型允許監聽并連接所有的網絡端口。我們可以通過調整SELinux的類型標簽,從而設定容器的安全性。
借助常規的SELinux和Apache httpd,在默認情況下,我們只允許Apache進程來監聽Apache的端口(http_port_t)。
# sudo sepolicy network -t http_port_thttp_port_t: tcp: 80,81,443,488,8008,8009,8443,9000</pre>
我們也可以阻斷所有傳出端口的連接。這可以幫助我們鎖定Apache進程,即便像ShellShock一樣的黑客通過安全漏洞破壞了應用程序,我們仍可以 阻止應用程序成為一個垃圾郵件僵尸,或者允許進程攻擊其它系統。正如《加州旅館》歌中唱道,“你可以隨時入住,但你永遠無法離開。”
然而,借助容器的情況下,如果你在一個容器內運行一個Apache服務器應用程序,該應用程序會遭受攻擊,Apache進程能夠通過網絡連接到任何網絡端口、成為垃圾郵件僵尸或者攻擊其他主機/容器。
使用SELinux創建一個新的策略類型供容器運行,這相當容易。首先,你可以創建一個SELinux TE(類型強制執行)文件。# cat > docker_apache.te << _EOFpolicy_module(docker_apache,1.0)
This template interface creates the docker_apache_t type as a
type which can be run as a docker container. The template
gives the domain the least privileges required to run.
virt_sandbox_domain_template(docker_apache)
I know that the apache daemon within the container will require
some capabilities to run. Luckily I already have policy for
Apache and I can query SELinux for the capabilities.
sesearch -AC -s httpd_t -c capability
allow docker_apache_t self: capability { chown dac_override kill setgid setuid net_bind_service sys_chroot sys_nice sys_tty_config } ;
These are the rules required to allow the container to listen
to Apache ports on the network.
allow docker_apache_t self:tcp_socket create_stream_socket_perms; allow docker_apache_t self:udp_socket create_socket_perms; corenet_tcp_bind_all_nodes(docker_apache_t) corenet_tcp_bind_http_port(docker_apache_t) corenet_udp_bind_all_nodes(docker_apache_t) corenet_udp_bind_http_port(docker_apache_t)
Apache needs to resolve names against a DNS server
sysnet_dns_name_resolve(docker_apache_t)
Permissive domains allow processes to not be blocked by SELinux
While developing and testing your policy you probably want to
run the container in permissive mode.
You want to remove this rule, when you are confident in the
policy.
permissive docker_apache_t; _EOF
make -f /usr/share/selinux/devel/Makefile docker_apache.pp
semodule -i docker_apache.pp</pre>
現在使用新類型運行容器:
docker run -d --security-opt type:docker_apache_t httpd
現在,該容器與正常容器相比,有著更為嚴格的SELinux安全性。注意,你可能會需要查看審計日志,以觀察你的應用程序是否需要額外的SELinux準許規則。
你可以通過使用audit2allow命令來添加規則到現有.te文件,重新編譯并安裝如下規則。
grep docker_apache_t /var/log/audit/audit.log | audit2allow >> docker_apache.te make -f /usr/share/selinux/devel/Makefile docker_apache.pp semodule -i docker_apache.pp
多級安全模式
目前,我們使用MCS分離,從而確保容器不被其它容 器干擾或交互,除非它是通過網絡進行的連接。某些政府系統需要不同類型的MLS(多極安全)政策。借助MLS,你可以基于看到的數據級別來標記進程。 MLS說如果你的容器要處理絕密數據,那么它應該在絕密的地方運行。我們已經添加了Docker選項,允許管理員設置容器在特定級別運行,這些應該會滿足 MLS系統的需求。
docker run -d --security-opt label:level:TopSecret --security-opt label:type:docker_apache_t httpd
這個命令將確保開啟Docker容器的兩個交替類型與級別,并且可以阻止容器使用不是相同標簽的數據。不過這方面尚未通過認證,但我們愿意幫助第三方為MLS用戶構建解決方案。
調整命名空間
在其他有關安全的對話中,我已經討論了命名空間如何被看作是一種安全機制,因為其刪除了一個進程查看系統(PID命名空 間)上其他進程的能力。網絡命名空間可以刪除通過你的命名空間看到其他網絡的能力。 IPC(內部進程間通信)命名空間具有阻斷容器使用其它容器的IPC能力。
Docker現在已經放寬這些限制。您可以用容器來共享主機的命名空間:
--pid=主機讓容器共享主機的PID命名空間
--net=主機讓容器共享主機的主機空間
--ipc=主機讓容器共享主機的IPC空間
需要注意的是,既然已與主機共享PID或IPC的命名空間,這就需要我們依序禁用SELinux分離,阻斷其工作。
docker run -ti --pid=host --net=host --ipc=host rhel7 /bin/sh
你可能會在這篇文章中閱讀到相關方面的額外信息Super Privileged Containers。
原文鏈接:Tuning Docker with the newest security enhancements (翻譯:田浩浩 校對:李穎杰)
來自:http://dockerone.com/article/243