## 1.Docker的核心原理
Docker容器的的本質是宿主機上的進程.通過namespace實現資源隔離,cgroups實現資源的限制,通過寫時復制的機制完成高效的文件操作.docker實現的核心技術-namespace 和 cgroups,其實并不是什么新技術,準確的說namespace 和 cgroups是linux的相關技術.docker對這種技術進行了封裝,提高可操作性。
## 2.容器安全的痛點
容器經常拿來和虛擬機進行對比,容器的好處就不多說了!主要說說:容器的缺點-隔離性低導致的安全性較低. **通常來說,容器相比虛擬機還是不夠安全的.**.
#### 2.1為什么容器不夠安全?
這就要從虛擬機和容器的底層實現機制來對比,
* 虛擬機在hypervisor的基礎上構建虛擬操作系統,有自己的操作系統內核.**容器與宿主機是共用同一個內核的**.
* 虛擬機也不是絕對安全的.找到HyperVisor的弱點,攻克SELinux控制,就可以攻破虛擬機,染指宿主機。但這是非常難的.
* 容器的隔離技術使用的是namespace,但namesapce的資源隔離僅限于以下6個方面
|namespace|隔離內容|內核版本|
|---|---|---|
|UTS|主機名與域名|Linux 2.6.19|
|IPC|信號量,消息隊列和共享內存|Linux 2.6.19|
|PID|進程編號|Linux 2.6.24|
|Network|網絡設備,網絡棧,端口|始于Linux 2.6.24 完成于 Linux 2.6.29|
|Mount|文件掛載|Linux 2.4.19|
|User|用戶用戶組| 始于 Linux 2.6.23 完成于 Linux 3.8|
> 為提升安全性,您的linux內核請升級版本大于3.8
> docker1.10開始支持User namespace,但不是默認開啟的.[《Docker 安全之用戶資源隔離》](http://www.zimug.com/453.html)
這6種資源隔離看上去比較完備,但是仍然有很多的資源沒有隔離,比如:
* SELinux
* Cgroups
* file systems under /sys
* /proc/sys, /proc/sysrq-trigger, /proc/irq, /proc/bus
* /dev/mem
* /dev/sd* file system devices
這將宿主機的資源暴露給了容器的訪問者,會導致安全問題!
**同時筆者認為,docker容器安全的痛點也僅限于互聯網公有云環境下。對于企業內部私有云也算不上痛點,通過對docker進行安全加固可以達到生產環境的安全級別的要求!歡迎批判!**,第4章節,我們將看看如何提升docker容器安全!
## 3.docker容器安全也有自己的優勢
容器的資源隔離程度相對虛擬機較低,與宿主機共享內核.導致容器的安全性低.那么是不是說容器相對于虛擬機,在安全性上完全沒有自己的優勢呢?
筆者認為,還是有的:
1. 可以禁止SSH訪問,防止很多正面攻擊
2. 容器暴露的端口有限,容器的本質是宿主機的進程,他只需要暴露非常有限的端口來提供服務.
3. 可以利用容器云控制容器的生命周期,使其在不影響服務的情況下,盡可能的短命.攻擊短生命周期的容器意義并不大.
3. 容器的文件系統分層,鏡像層是只讀的,只有容器層可寫.容器層文件的生命周期與容器相同(不是數據卷).
## 4.如何提升容器安全性
### 4.1 使用User namespace
**User namespace是從docker1.10開始被支持,并且不是默認開啟的.**
docker 使用namespace進行資源隔離,其中一種是user namespace.user namespace主要隔離了安全相關的標識符和屬性,包括用戶ID,用戶組Id,root目錄,key(密鑰)以及特殊權限.
默認的情況下,docker容器使用的root用戶和宿主機的root用戶是同一個用戶,盡管可以限制容器內root用戶的權限(capability),但本質上仍然和宿主機root用戶是同一個用戶.
有了user namespace之后,我們就可以將宿主機上的普通用戶映射為容器的root用戶,這樣容器中的實際用戶為普通用戶權限,可以將容器的安全程度提高一個等級!
關于具體的實現步驟,請查看我的這篇文章:
[《Docker 安全之用戶資源隔離》](http://www.zimug.com/453.html)
### 4.2 使用OpenSSL保護docker daemon
默認情況下,運行docker命令需要訪問本地的Unix Socket.也可以通過HTTP的方式完成遠程訪問.
如果你需要以安全的方式在網絡中訪問docker,最好使用TLS,指定tlsverify參數,設置tlscacert參數指向一個可信的CA證書.在這種方式下,只有經過CA權限驗證通過的客戶端才能訪問docker deamon.
具體內容請訪問官網:[《Protect the Docker daemon socket》](https://docs.docker.com/engine/security/https/#connecting-to-the-secure-docker-port-using-curl)
### 4.3 安全的組網方式
我們可以將容器的服務端口分為兩種
* 第一種:直接為用戶提供服務的端口,如:web應用常用8080
* 第二種:為其他應用的提供服務的端口.
筆者認為安全的組網方式就是:**盡量**不使用端口映射的方式將容器端口映射到宿主機.端口暴露的越少,安全性就越高.
**什么是盡量?如何盡量?**
我采用overlay的網絡,或者叫應用層網絡,覆蓋網絡,**但這絕不是唯一的方法**.
docker 1.9為我們提供了官方的跨宿主機組網方式overlay(還有其他的網絡工具也是這種方式).容器應用的網絡構建于物理網絡之上,在邏輯上又獨立于物理網絡.
舉個例子:ZF的各個部門是都一個宿主機,容器(職能人員)之間可以跨宿主機溝通.部門級別之間的溝通是物理網絡,各部門的職能人員之間的溝通是應用網絡.
最后形成的溝通結論,對外發布,交給新聞發言人,這個新聞發言人是物理網絡對外服務的接口.
同樣:
對于第一種直接為用戶提供服務的端口,可以采用端口映射的方式映射到宿主機,他就是發言人.
對于第二種端口的消息,應用網絡內部處理,不對外發布。
實現方式可以參考:[《基于consul的Docker-overlay跨多宿主機容器網絡》](http://www.zimug.com/364.html)
### 4.4 限制docker容器的capability
**什么是capability?**
簡單地說,就是執行調用操作的權限.Linux將超級用戶的權限進行分組,每一組代表了所能執行的系統調用操作.
如果是root用戶,剝奪它的某些capability,那么它將無法調用對應的系統操作.如果是普通用戶,對它賦予某些capability,它也可以完成某些超級用戶才能做的系統調用.
capability為系統的權限管理,提供了更加細粒度的權限劃分.
**容器默認擁有的capability(能力)包括:**
* CHOWN: 更改文件UID和GID的能力
* DAC_OVERRIDE:忽略文件的讀,寫,執行訪問權限的檢查的能力
* FOWNER:越過可執行文件的擁有者權限檢查,執行操作的能力
* FSETID:文件修改后保留setuid/setgid標志位
* SETGID:改變進程組id的能力
* SETUID:改變進程用戶ID的能力
* SETFCAP:向security.capability寫入能力屬性的能力
* NET_RAW:創建RAW和PACKET套接字的能力
* MKNOD:使用mknod創建特殊文件的能力
* SYS_REBOOT:允許使用reboot或者kexec_load.kexec_load功能是加載新的內核作為reboot重新啟動所需的內核
* SYS_CHROOT:使用chroot的能力
* KILL:越過權限檢查,發送信號的能力
* NET_BIND_SERVICE:綁定常用端口的能力(端口號小于1024)
* AUDIT_WRITE:允許審計日志寫入的能力
**查看容器的capability(能力)**
通過docker ps 和docker inspect 獲得容器進程的id,查看容器的默認能力
```
$ pscap |grep 165536
1411 19337 165536 top chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap
```
**移除容器的capability(能力)**
使用--cap-drop移除能力,運行容器
```
docker run -it --cap-drop SETGID --cap-drop SETUID ubuntu:14.04 top
```
通過docker ps 和docker inspect 獲得容器進程的id,查看容器的現有能力.setuid和setgid的能力被移除
```
1411 19803 165536 top chown, dac_override, fowner, fsetid, kill, setpcap, net_bind_service, net_raw, sys_chroot, mknod, audit_write, setfcap
```
**為容器新增capability(能力)**
使用--cap-add增加能力,運行容器
```
docker run -it --cap-add SYS_TIME ubuntu:14.04 top
```
通過docker ps 和docker inspect 獲得容器進程的id,查看容器的現有能力.新增了sys_time能力
```
1411 20101 165536 top chown, dac_override, fowner, fsetid, kill, setgid, setuid, setpcap, net_bind_service, net_raw, sys_chroot, sys_time, mknod, audit_write, setfcap
```
**Linux都有哪些capability(能力)?**
[capabilities - overview of Linux capabilities](http://www.man7.org/linux/man-pages/man7/capabilities.7.html)
### 4.5 文件系統只讀保護
Docker 可以設置容器的文件系統為只讀模式.這樣可以禁止,腳本注入方式的攻擊,因為腳本無法保存.
```
$ docker run --rm -ti --read-only ubuntu bash
```
**注意:此方法不能與user namespace 同時使用**
**……未完待續,歡迎持續關注我的博客!**
## 參考
* Docker安全部署的17條建議
http://dockone.io/article/150
* 容器相比虛擬機更為安全的十三個方面
http://dockone.io/article/1427
* Docker背后的內核知識——Namespace資源隔離
http://www.infoq.com/cn/articles/docker-kernel-knowledge-namespace-resource-isolation
* Docker安全
https://segmentfault.com/a/1190000005794220
- 版權
- 博客主題
- 如何不去做運行3.5G-docker鏡像的工程師
- 預備主題
- FastDFS快速入門
- mysql定時創建月表
- SpringMVC-Restful
- Docker生態系統
- The Docker Ecosystem: An Introduction to Common Components
- docker監控指標
- 基于etcd服務發現的overlay跨多宿主機容器網絡
- etcd:從應用場景到實現原理的全方位解讀
- docker存儲驅動詳解
- 使用docker/engine-api操作docker
- 提升Docker安全性
- docker安全之用戶資源隔離
- marathon
- 開始
- 安裝mararhon
- 高可用模式
- 使用marathon
- 應用的部署
- 架構組件
- Dubbo與Zookeeper、SpringMVC整合和使用(負載均衡、容錯)
- Openstack架構解析
- haproxy
- Ubuntu系統安裝截圖
- mesos官方文檔
- 關于譯者
- mesos基礎
- Mesos架構
- 視頻與ppt
- 讓mesos跑起來
- 快速入門
- 配置
- Containerizer
- Docker Containerizer
- 監控
- 博客文章集
- 煮餃子與mesos之間妙不可言的關系
- linux運維
- 基礎篇
- 進階篇
- mysql
- Ubuntu14.04安裝mysql5.6
- MySQL 5.6 replicate原理與實踐
- mysql性能
- redis
- redis安裝及基礎知識
- redis數據結構
- redis命令
- redis數據持久化
- Redis主從復制
- redis集群
- 其他