Docker與容器安全
Docker能否大規模用於生產環境,尤其是公有云環境,就在於Docker是否能提供安全的環境。本文將總結《Docker容器與容器雲》一書3.9節『Docker與容器安全』的主要內容,包括Docker現有安全機制、存在的安全問題以及Docker安全增強三個方面。
1. Docker的安全機制
1.1 Docker daemon安全
- Docker向外界服務提供了四種通信方式,默認是以Unix域套接字的方式來與客戶端通信,這種方式較TCP形式更爲安全。
- Docker也提供了TLS傳輸層安全協議,通過--tlsverify(安全傳輸校驗),--tlscacert(信任證書)、--tlskey(服務器或者客戶端祕鑰)、--tlscert(證書位置)來配置。
1.2 鏡像安全
-
Docker registry鏡像庫訪問控制
- Docker daemon第一次啓動時,通過公網(Amazon CDN)載入official.json包,飲食公共image和用戶image的目錄以及數字簽名信息。
- official.json在Docker daemon啓動時加載到MemoryGraph,MemoryGraph用於存儲公鑰以及命名之間的授權映射,默認授權節點對授權空間有讀寫權限。
-
鏡像校驗和
- 鏡像校驗和用來保證鏡像的完整性,以預防可能出現的鏡像破環。
- 目前Docker對於鏡像校驗和和驗證失敗不採取任何措施,僅輸出警告信息
1.3 內核安全
- 內核爲容器提供了兩種技術cgroup和namespace,分別對容器進行資源限制和資源隔離。
- 容器本質是進程,cgroup用來限制容器的資源使用量,避免單個容器耗盡系統資源。
- namespace用來隔離容器與宿主機,以及不同的容器。
- Docker目前僅完整支持uts、ipc、pid、network、mount這5種ns,user ns尚未完全支持。
- 系統資源未進行隔離,如/proc,/sys、SELinux、time、syslog、/dev設備信息等均未進行隔離。
1.4 容器之間的網絡安全
- Docker可通過iptabls設定規則實現禁止或允許容器之間的通信。
1.5 Docker容器Capability限制
- 容器的行爲通過Linux超級用戶分組限制,具體包括了CHOWN、DAC_OVERRIDe、FSETID、FOWNER、MKNOD、NET_RAW、SETGID、SETUID、SETFCAP、SETPCAP、NET_BIND_SERVICE、SYS_CHROOT、KILL和AUDIT_WRITE。
- Docker進程的Capability可通過docker run命令的參數進行配置
2. Docker安全問題
2.1 磁盤資源限制問題
- Docker容器通過鏡像層疊的方式來構建容器內的文件系統,本質上還是在宿主機文件系統的目錄(/var/lib/docker)下存儲文件。
- 極有可能出現一個容器將宿主機上所有的磁盤空間耗盡,導致其它容器無法存儲文件,所以有必要對容器的磁盤使用量進行限制。
2.2 容器逃逸問題
- Docker使用操作系統進行虛擬化,共享內核、內存、CPU以及磁盤,易造成容器逃逸問題。
- Docker1.0之後採用白名單來限制容器的能力,會給出默認的容器Capability清單,禁止容器擁有清單之外的Capability。
2.3 容器DoS攻擊與流量限制問題
- 公有云基於虛擬化技術實現,攻擊數據包可能不需要通過物理網卡就可以攻擊同一個宿主機下的其他容器,傳統Dos預防措施無法適用容器之間的攻擊。
- 默認的Docker容器連接在網橋上,通過veth pari技術創建網卡,其一端在容器內命名爲eth0,另一張網上駐留在宿主機環境之中。
- 同一宿主機下所有容器共用一張物理網卡,如果一個容器搶佔大部分帶寬,會影響其它容器使用。
2.4 超級權限問題
- docker run時加入--privileged參數能使容器獲得所有的超級用戶權限能力,並將所有的宿主機的所有設備掛載到容器內。
3. Docker安全的解決方案
3.1 SELinux
- SELinux三種控制方式
- Type Enforcement: 主要的訪問控制機制。
- Role-Based Access Control(RBAC):基於SELinux用戶的權限控制手段。
- Multi-Level Security(MLS): 多級分類安全,指定level標籤。
- 爲什麼要在Docker中使用SELinux
- SELinux將所有進程和文件打上標籤,而容器以進程方式運行,所以控制進程如何訪問資源,也就是限制容器如何去訪問資源。
- SELinux策略是全局的,它不是針對具體用戶設定,而是強制整個系統遵循。
- 減少提權攻擊風險。
3.2 user namespace
- 容器的超級用戶權限通過ns映射到宿主機是一個普通用戶。
- 容器被惡意程序攻擊,所做的也就是這個普通用戶的權限,而非宿主機的超級權限。
3.3 磁盤限額
- Docker僅對Device Mapper文件系統的限額提供了--storage-opt參數進行限制。
- cgroup沒有對磁盤進行限制,Linux磁盤限額技術主要基於用戶和文件系統。
- 可能的解決方案
- 所有用戶共有宿主機的一塊磁盤,限制用戶在磁盤上的使用量來限定容器的磁盤使用量。
- 選擇支持目錄限額的文件系統,如XFS。
- Docker定期檢查每一個容器磁盤使用量,會對性能造成影響。
- 創建虛擬文件系統,些文件系統僅供某一個容器使用。
3.4 容器流量限制
- Docker沒對容器的網絡帶寬做限制。
- 可以採用Traffic Controller容器對容器網卡流量進行限制,一定程序上減少容器Dos攻擊危害。
3.5 GRSecurity內核安全增強工具
- Docker容器共享宿主機的內存,在內存安全上存在不少問題,需要針對內存破壞做防禦。
- GRSecurity是一個對內核的安全擴展,通過智能訪問控制來阻止內存破壞,預防0day漏洞。
3.6 fork炸彈
- fork炸彈以極快速度創建大量進程,以此消耗系統資源,使系統無法運行新程序,現有進程運行速度放緩。
- 容器本身在內核層面隔離性不足,fork bomb會給容器帶來災難性影響。
- fork bomb受到社區關注(Issue 6479),但目前還沒有完美解決方案。
- Docker無法使用ulimit來限制forkbomb問題,因爲一個宿主機用戶可能同時啓動多個容器,無法對每個容器做進程數的限制。
4. 總結
Docker自身已經提供了不少安全機制,但Docker目前仍然只適於運行可信應用程序(內部使用),如果需要運行任意代碼,安全很難得到保證。在日常應用中,還可以通過SELinux、GRSecurity、seccomp等工具來增強容器安全。