title: docker容器安全
tags: Docker,容器,安全策略
grammar_cjkRuby: true
Docker容器的安全性
1.安全策略-Cgroup
1.限制Cpu
docker run --rm -ti -c 2000 ubuntu bash
2.限制內存
docker run --rm -ti -m 200M ubuntu bash
3.限制快設備io
docker run --rm -ti --name container1 ubuntu bash
dd if=/dev/zero of=testfile0 bs=8k mount=5000 oflag=direct
修改 Cgroup文件
# 查找容器掛載的文件系統“/dev/mapper”的位置
$ mount|grep ContainerID
# 查看容器掛載的文件系統中的文件(Path為上條命令取得的返回結果)
# 返回結果“->”標記后會有一個新的路徑,我們先稱其為DeviceFilePath
$ ls -l Path
# 查詢容器掛載的設備號
$ ls DeviceFilePath -l
# 返回結果中“root disk”后面會有一串用“,”隔開的數字,假設是128和256
# 限制容器的寫速度
$ sudo echo '128:256 10240000' >/sys/fs/cgroup/blkio/system.slice/docker-DockerID.scope/blkio.throttle.write_bps_device
# 10240000是每秒可寫入的最多的字節數。
2.ulimit
在Docker1.6之后,可以設置全局默認的ulimit,如設置CPU時間
sudo docker daemon --default-ulimit cpu=1200
或者在啟動容器時,單獨對其ulimit進行設置
docker run --rm -ti --ulimit cpu=1200 ubuntu bash
進入容器后可以查看
ulimit -t
返回結果:1200
3. 容器組網
在接入容器隔離不足的情況下,將受信任的和不受信任的容器組網在不同的網絡中,可以降低風險。
4. 容器 + 全虛擬化
如果將容器運行在全虛擬化環境中(如在虛擬機中運行容器),這樣就算容器被攻破,虛擬機還具有保護作用。目前一些安全需求很高的應用場景采用的就是這種方式,如公有雲場景。
5. 鏡像簽名
Docker可信鏡像及升級框架(The Update Framework,TUF)是Docker 1.8所提供的一個新功能,可以校驗鏡像的發布者。當發布者將鏡像push到遠程倉庫時,Docker會對鏡像用私鑰進行簽名,之后其他人pull該鏡像的時候,Docker就會用發布者的公鑰來校驗該鏡像是否和發布者所發布的鏡像一致,是否被篡改過,是否是最新版。
6. 日志審核
docker run --rm -ti --log-driver="syslog" ubuntu bash
通過docker inspect ContainerID可以看到容器使用了哪種日志驅動。另外,只有json-file支持docker logs命令,docker logs ContainerID。
7. 監控
容器的資源使用情況主要指容器對內存、網絡I/O、CPU、磁盤I/O的使用情況等,命令:docker stats ContainerID。
查看容器的運行狀態,命令:docker ps -a。
8. 文件系統級防護
可讀寫掛載:
$ docker run --rm -ti ubuntu bash
# echo "hello" >/home/test.txt
# cat /home/test.txt
只讀掛載:
$ docker run --rm -ti --read-only ubuntu bash
# echo "hello" >/home/test.txt
# 返回結果:bash:/home/test.txt:Read-only file system
9. capability
Capabilities 鏈接 https://wiki.archlinux.org/index.php/Capabilities_(簡體中文)
從2.2版開始,Linux有了capability的概念,它打破了Linux操作系統中超級用戶/普通用戶的概念,讓普通用戶也可以做只有超級用戶才能完成的工作。capability可以作用在進程上,也可以作用在程序文件上。它與sudo不同,sudo可以配置某個用戶可以執行某個命令或更改某個文件,而capability則是讓程序擁有某種能力。
每個進程有三個和能力有關的位圖:Inheritable(I)\Permitted(P)\Effective(E),我們可以通過/proc/
命令:cat /proc/$$/status | grep Cap
結果:
# 能夠被當前進程執行的程序繼承的capability。
CapInh: 0000000000000000
# 進程能夠使用的能力,可以包含CapEff中沒有的能力,這些能力是被進程自己臨時放棄的,因此可以把CapEff看作是CapPrm的一個子集。
CapPrm: ffffffffffffffff
# 當一個進程要進行某個特權操作時,操作系統會檢查CapEff的對應位是否有效,而不再是檢查進程的有效UID是否為0。
CapEff: ffffffffffffffff
Docker啟動容器的時候,會通過白名單的方式來設置傳遞給容器的capability,默認情況下,這個白名單只包含CAP_CHOWN等少數的能力。用戶可以通過 -–cap-add 和 -–cap-drop 這兩個參數來修改這個白名單。
$ docker run --rm -ti --cap-drop=chown ubuntu bash
# chown 2.2/etc/hosts
# 返回結果:chown:changing ownership of '/etc/hosts': Operation not permitted
發現禁掉CAP_CHOWN能力后,在容器里就無法改變容器的所有者了。如果不禁掉則正常。如下
$ docker run --rm -ti ubuntu bash
# chown 2.2/etc/hosts
容器應遵循最小權限原則,盡量不要用–privileged參數,不需要的能力全部去掉,甚至禁掉所有的能力。
$ docker run --rm -ti --cap-drop=all ubuntu bash
10. SElinux
SElinux 介紹鏈接 http://www.cnblogs.com/xiaoluo501395377/archive/2013/05/26/3100444.html
SELinux定義了系統中每個用戶、進程、應用和文件訪問及轉變的權限,然后使用一個安全策略來控制這些實體(即用戶、進程、應用和文件)之間的交互,安全策略指定了如何嚴格或寬松的進行檢查。另外,SELinux比較復雜。
11. AppArmor
文檔配置鏈接 http://manpages.ubuntu.com/manpages/xenial/en/man5/apparmor.d.5.html
AppArmor也是一種MAC控制機制,其主要作用是設置摸個可執行程序的訪問控制權限,可以限制程序讀/寫某個目錄/文件,打開/讀/寫網絡端口等。AppArmor是一個高效和易於使用的Linux系統安全特性,它對操作系統和應用程序進行了從內到外的保護,即使是0day漏洞和未知的應用程序漏洞所導致的攻擊也可被識破。AppArmor安全策略可以完全定義個別應用程序所能訪問的系統資源與各自的特權,它包含了大量的默認策略,並將先進的靜態分析和基於學習的工具結合了起來,可以在很短的時間內,為非常復雜的應用制定AppArmor規則。
12. Seccomp
Seccomp(secure computing mode)是一種Linux內核提供的安全特性,它可以實現應用程序的沙盒機制,以白名單或黑名單的方式限制進程進行系統調用。
Seccomp首次於內核2.6.12版合入Linux主線。早期的Seccomp只支持過濾少數幾個系統調用。較新版本的內核支持動態Seccomp策略,也就是seccomp-bpf,因為支持用BPF生成過濾規則,從而使Seccomp可以限制任意的系統調用,並且可以限制系統調用傳入的參數。
Seccomp的使用
生成BPF形式的過濾規則;
調用prctl系統調用將規則傳入內核。
在Docker容器啟動的過程中,會對Seccomp設置一個默認的配置,但目前還不支持命令行參數做配置。
13. grsecurity
grsecurity提供了一個系統的內核patch,使Linux內核的安全性大大增強,並且它提供了一些工具讓用戶配置、使用這些安全特性。grsecurity可以用來控制資源訪問權限。下面是一張關於grsecurity、SELinux和AppArmor的對比圖。
相關安全項目
與Docker安全相關的項目
1. Notary
Docker對安全模塊進行了重構,剝離出了名為Notary的獨立項目。Notary的目標是保證server和client之間的交互使用可信任的連接,用於解決互聯網的內容發布的安全性。該項目並未局限於容器應用,在容器場景下可以對鏡像源認證、鏡像完整性等安全需求提供更好的支持。
2. docker-bench-security
docker-bench-security提供一個腳本,它可以檢測用戶的生產環境是否符合Docker的安全實踐。
Docker安全遺留問題
在Docker的安全問題上Docker社區做了很多的工作,但Docker依然有不少跟安全相關的問題尚未解決。
1. User Namespace
User Namespace可以將host中的一個普通用戶映射成容器里的root用戶,不過雖然允許進程在容器里執行特權操作,但這些特權只局限於該容器內。這對容器的安全是一個非常大的提升,惡意程序通過容器入侵host或者其他容器的風險大大降低,但這並不意味着容器就足夠安全了。另外,由於內核層面隔離性不足,如果用戶在容器的一個特權操作會影響到容器外,那么這個特權操作一般也是不被User Namespace所允許的。
2. 非root運行Docker daemon
目前Docker daemon需要由root用戶啟動,而Docker daemon創建的容器以及容器里運行的應用實際上也是以root用戶運行的。實現由普通用戶啟動Docker daemon和運行容器,有益於Docker的安全。但這個問題很難解決,因為創建容器需要執行很多特權,包括掛載文件系統、配置網絡等。目前社區還沒有一個好的方案。
3. Docker熱升級
Docker管理容器的方式是中心式管理,容器由主機上的Docker daemon進程統一管理。中心式管理方式對於第三方的任務編排工具並不友好,因為什么功能都需要跟Docker關聯起來。更大的問題是,如果Docker daemon掛掉了,重啟daemon后,它無法接管容器,容器也不能運行了。在實際應用中,很多業務都是不能中斷的,而停止容器就往往相當於停止業務,但如果因為安全漏洞的原因需要升級Docker,用於就將處於兩難的境地。點擊了解該問題的進展。
3. 磁盤限額
默認情況下,Docker鏡像、容器rootfs、數據卷都存放在/var/lib/docker目錄里,也就是說跟host是共享同一個文件系統的。如果不對Docker容器做磁盤大小的配額限制,容器就可能用完磁盤的可用空間,導致host和其他容器無法正常工作。
但是目前Docker幾乎沒有提供任何接口用於限制容器的磁盤大小。但graphdriver為devicemapper時,容器會被默認分配一個100GB的空間。這個空間大小可以在啟動Docker daemon時設置為另一個默認值,但無法對每個容器單獨設置一個不同的值。
$ sudo docker daemon --storage-opt dm.basesize=5G
除此之外,用戶只能通過其他手段自行做一些隔離措施,例如為/var/lib/docker單獨分配一個磁盤或分區。
4. 網絡I/O
目前同一台機器上的Docker容器會共享寬帶,但這可能出現某個容器占用大部分帶寬資源,從而影響其他需要網絡資源的容器正常工作的情況。Docker需要一個好的網絡方案,除了要解決容器跨主機通信的問題,還要解決網絡I/O限制的問題。