docker的安全管理与TLS/LLS加密通信
文章目錄
- 一:Docker 容器與虛擬機(jī)的區(qū)別
- 1.1 容器的安全性問題
- 1.2 隔離與共享
- 1.3 性能與損耗
- 二:Docker 存在的安全問題
- 2.1 Docker 自身漏洞
- 2.2 Docker 源碼問題
- 三: Docker 架構(gòu)缺陷與安全機(jī)制
- 3.1 容器之間的局域網(wǎng)攻擊
- 3.2 DDos攻擊耗盡資源
- 3.3 有漏洞的系統(tǒng)調(diào)用
- 3.4 共享root用戶權(quán)限
- 四: Docker 安全基準(zhǔn)線標(biāo)準(zhǔn)
- 4.1 內(nèi)核級(jí)別
- 4.2 主機(jī)級(jí)別
- 4.3網(wǎng)絡(luò)級(jí)別
- 4.4 鏡像級(jí)別
- 4.5 容器級(jí)別
- 4.6 其他設(shè)置
- 五: 容器相關(guān)的常用安全配置
- 5.1 容器最小化
- 5.2 Docker遠(yuǎn)程的API訪問控制
- 在docker 服務(wù)配置文件中指定監(jiān)聽內(nèi)網(wǎng)IP
- 重啟docker
- 在宿主機(jī)的firewalld上做ip訪問控制。source address 指定客戶端地址
- 在客戶端實(shí)現(xiàn)遠(yuǎn)程授權(quán)訪問
- 六: 限制流量流向
- 七 鏡像安全
- 八: DockerClient 端與DockerDaemon 的通信安全
- 8.1 SSL/TLS的通信過程
- 8.2 創(chuàng)建ca證書過程
- 8.3創(chuàng)建目錄,生成ca證書
- 8.3.1 創(chuàng)建目錄,生成私鑰文件
- 8.3.2 創(chuàng)建ca證書
- 8.4 用ca證書簽發(fā)server端證書
- 8.5用ca 證書簽發(fā)client端證書
- 8.6 配置docker服務(wù)配置文件,重啟docker
- 8.7 復(fù)制ca證書和客戶端私鑰,客戶端簽名證書到客戶端主機(jī),并修改服務(wù)端主機(jī)名,做hosts映射
- 8.8客戶端遠(yuǎn)程訪問
- 九:避免Docker 容器中信息泄露
一:Docker 容器與虛擬機(jī)的區(qū)別
1.1 容器的安全性問題
容器的安全性問題的根源在于容器和宿主機(jī)共享內(nèi)核。如果容器里的應(yīng)用導(dǎo)致ELinux內(nèi)核崩潰,那么整個(gè)系統(tǒng)可能都會(huì)崩潰。與虛擬機(jī)是不同的,虛擬機(jī)并沒有與主機(jī)共享內(nèi)核,虛擬機(jī)崩潰一般不會(huì)導(dǎo)致宿主機(jī)崩潰。
1.2 隔離與共享
虛擬機(jī)通過添加Hypervisor層(虛擬化中間層),虛擬出網(wǎng)卡、內(nèi)存、cpu等虛擬硬件,再在其上建立虛擬機(jī),每個(gè)虛擬機(jī)都有自己的系統(tǒng)內(nèi)核。虛擬機(jī)通過Hypervisor進(jìn)行隔離
而Docker容器則是通過隔離的方式,將文件系統(tǒng)、進(jìn)程、設(shè)備、網(wǎng)絡(luò)等資源進(jìn)行隔離,再對(duì)權(quán)限、cpu資源等進(jìn)行控制,最終讓容器之間互不影響,容器無法影響宿主機(jī)。Docker 通過Namespace進(jìn)行隔離
容器與宿主機(jī)共享內(nèi)核、文件系統(tǒng)、硬件等資源。
1.3 性能與損耗
與虛擬機(jī)相比,容器資源損耗要少。同樣的宿主機(jī)下,能夠建立容器的數(shù)量要比虛擬機(jī)多。
但是,虛擬機(jī)的安全性要比容器稍好,要從虛擬機(jī)攻破到宿主機(jī)或其他虛擬機(jī),需要先攻破Hypervisor層,這是極其困難的。
而docker 容器與宿主機(jī)共享內(nèi)核、文件系統(tǒng)等資源,更有可能對(duì)其他容器、宿主機(jī)產(chǎn)生影響。
| 啟動(dòng)速度 | 快,幾秒鐘 | 慢,幾分鐘 |
| 運(yùn)行性能 | 接近原生(直接在內(nèi)核中運(yùn)行) | 運(yùn)行與Hypervisor上,50%左右損失 |
| 磁盤占用 | 小,甚至幾十kb(根據(jù)鏡像層的情況) | 非常大,上GB |
| 并發(fā)性 | 一臺(tái)宿主機(jī)可以啟動(dòng)成百上千個(gè)容器 | 最多幾十個(gè)虛擬機(jī) |
| 隔離性 | 進(jìn)程級(jí)別 | 系統(tǒng)級(jí)別(更徹底) |
| 操作系統(tǒng)很 | 主要支持Linux | 幾乎所有 |
| 封裝程度 | 只打包項(xiàng)目代碼和依賴關(guān)系,共享宿主機(jī)內(nèi)核 | 完整的操作系統(tǒng),與宿主機(jī)隔離 |
二:Docker 存在的安全問題
2.1 Docker 自身漏洞
Docker自身漏洞作為一款應(yīng)用Docker本身實(shí)現(xiàn)上會(huì)有代碼缺陷。CVE官方記錄Docker歷史版本共有超過20項(xiàng)漏洞,可參見Docker官方網(wǎng)站。黑客常用的攻擊手段主要有代碼執(zhí)行、權(quán)限提升、信息泄露、權(quán)限繞過等。目前Docker版本更迭非常快, Docker用戶可將Docker升級(jí)為最新版本。
2.2 Docker 源碼問題
Docker提供了Docker hub,可以讓用戶上傳創(chuàng)建的鏡像,以便其他用戶下載,快速搭建環(huán)境。但同時(shí)也帶來了一些安全問題。例如下面三種方式:
- 如果有黑客在制作的鏡像中植入木馬、后門等惡意軟件,那么環(huán)境從一開始就已經(jīng)不安全了,后續(xù)更沒有什么安全可言。
- DockerHub上能下載的鏡像里面, 758的鏡像都安裝了有漏洞的軟件。所以下載鏡像后,需要檢查里面軟件的版本信息,對(duì)應(yīng)的版本是否存在漏洞,并及時(shí)更新打上補(bǔ)丁。
- 鏡像在傳輸過程中可能被篡改, 目前新版本的Docker已經(jīng)提供了相應(yīng)的校驗(yàn)機(jī)制來預(yù)防這個(gè)問題。
三: Docker 架構(gòu)缺陷與安全機(jī)制
Docker本身的架構(gòu)與機(jī)制就可能產(chǎn)生問題,例如這樣一種攻擊場(chǎng)景,黑客已經(jīng)控制了宿主機(jī)上的一些容器,或者獲得了通過在公有云上建立容器的方式,然后對(duì)宿主機(jī)或其他容器發(fā)起攻擊。
3.1 容器之間的局域網(wǎng)攻擊
主機(jī)上的容器之間可以構(gòu)成局域網(wǎng),因此針對(duì)局域網(wǎng)的ARP欺騙、端口掃描、廣播風(fēng)暴等攻擊方式便可以用上。
所以,在一個(gè)主機(jī)上部署多個(gè)容器需要合理的配置網(wǎng)絡(luò)安全,比如設(shè)置iptables規(guī)則。
3.2 DDos攻擊耗盡資源
cgroups安全機(jī)制就是要防止此類攻擊的,不要為單一的容器分配過多的資源即可避免此類問題。
3.3 有漏洞的系統(tǒng)調(diào)用
Docker與虛擬機(jī)的一個(gè)重要的區(qū)別就是Docker與宿主機(jī)共用一個(gè)操作系統(tǒng)內(nèi)核。
一旦宿主內(nèi)核存在可以越權(quán)或者提權(quán)漏洞,盡管Docker使用普通用戶執(zhí)行,在容器被入侵時(shí),攻擊者還可以利用內(nèi)核漏洞跳到宿主機(jī)做更多的事情。
3.4 共享root用戶權(quán)限
如果以root用戶權(quán)限運(yùn)行容器(docker run --privileged) ,容器內(nèi)的root用戶也就擁有了宿主機(jī)的root權(quán)限
四: Docker 安全基準(zhǔn)線標(biāo)準(zhǔn)
下面從內(nèi)核、主機(jī)、網(wǎng)絡(luò)、鏡像、容器以及其它等6個(gè)方面總結(jié)Docker安全基線標(biāo)準(zhǔn)。
4.1 內(nèi)核級(jí)別
4.2 主機(jī)級(jí)別
4.3網(wǎng)絡(luò)級(jí)別
4.4 鏡像級(jí)別
4.5 容器級(jí)別
4.6 其他設(shè)置
由于安全屬于非常具體的技術(shù),這里不再贅述,可直接參閱Docker官方文檔, https://docs.docker.com/engine/security
五: 容器相關(guān)的常用安全配置
5.1 容器最小化
如果僅在容器中運(yùn)行必要的服務(wù),像SSH等服務(wù)是不能輕易開啟去連接容器的。通常使用一下方式進(jìn)入容器
docker exec -it 容器ID bash
5.2 Docker遠(yuǎn)程的API訪問控制
Docker 的遠(yuǎn)程調(diào)用API 接口存在未授權(quán)訪問漏洞,至少應(yīng)該限制外網(wǎng)訪問。建議使用Socket 方式訪問。
在docker 服務(wù)配置文件中指定監(jiān)聽內(nèi)網(wǎng)IP
[root@host103 ~]#vim /usr/lib/systemd/system/docker.service 13行修改 13:// ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://192.168.23.103:2375重啟docker
[root@host103 ~]# systemctl daemon-reload [root@host103 ~]# systemctl restart docke[root@host103 ~]# netstat -natp | grep 2375 tcp 0 0 192.168.23.103:2375 0.0.0.0:* LISTEN 77808/dockerd在宿主機(jī)的firewalld上做ip訪問控制。source address 指定客戶端地址
[root@host103 ~]# firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.23.104" port protocol="tcp" port="2375" accept" success[root@host103 ~]# firewall-cmd --reload success在客戶端實(shí)現(xiàn)遠(yuǎn)程授權(quán)訪問
#在host103主機(jī)docker 客戶端啟動(dòng)容器 [root@host103 ~]# docker run -itd --name test1 centos:7 bas [root@host103 ~]# docker run -itd --name test2 centos:7 ba [root@host103 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS e816df360df1 centos:7 "bash" 4 seconds ago Up 3 secon acfda848249f centos:7 "bash" 8 seconds ago Up 8 sec#可以使用 -H選項(xiàng)指定ip和端口,能夠使用遠(yuǎn)程的docker [root@host104 ~]# docker -H tcp://192.168.23.103:2375 ps CONTAINER ID IMAGE COMMAND CREATED STAT e816df360df1 centos:7 "bash" 13 seconds ago Up 1 acfda848249f centos:7 "bash" 17 seconds ago Up六: 限制流量流向
使用防火墻過濾器限制Docker容器的源IP 地址范圍與外界通信
[root@host103 ~]# firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.100.0/24" reject" success生產(chǎn)環(huán)境中的大量問題是因?yàn)镈ocker容器端口外放引起的漏洞,除了操作系統(tǒng)賬戶權(quán)限控制上的問題,更在于對(duì)Docker Daemon的進(jìn)程管理上存在隱患。
目前常用的Docker版本都支持Docker Daemon管理宿主機(jī)iptables的,而且一旦啟動(dòng)進(jìn)程加上-p host port:guest port
的端口映射, Docker Daemon會(huì)直接增加對(duì)應(yīng)的FORWARD Chain并且-j ACCEPT,而默認(rèn)的DROP規(guī)則是在INPUT鏈做的,對(duì)docker沒法限制,這就留下了很嚴(yán)重的安全隱患。因此建議:
(1)不在有外網(wǎng)ip的機(jī)器上使用Docker服務(wù)。
(2)使用k8s等docker編排系統(tǒng)管理Docker容器。
(3)宿主機(jī)上Docker daemon啟動(dòng)命令加一個(gè)–iptables=false,然后把常用iptables規(guī)則寫進(jìn)文件里,再用iptables-restore重定向輸入去刷新規(guī)則。
七 鏡像安全
一般情況下,要確保只從受信任的庫中獲取鏡像,推薦使用harbor私有倉庫。
如果公司使用的不是自己的鏡像源,需要使用Docker鏡像安全掃描工具Clair,對(duì)下載的鏡像進(jìn)行檢查。通過與CVE數(shù)據(jù)庫同步掃描鏡像,驗(yàn)證鏡像的md5等特征值,確認(rèn)一致后再基于鏡像進(jìn)一步構(gòu)建。一旦發(fā)現(xiàn)漏洞則通知用戶處理,或者直接阻止鏡像繼續(xù)構(gòu)建。
也可以使用linux自帶的md5sum工具
八: DockerClient 端與DockerDaemon 的通信安全
8.1 SSL/TLS的通信過程
為了防止鏈路劫持、會(huì)話劫持等問題導(dǎo)致Docker通信時(shí)被中間人攻, c/s兩端應(yīng)該通過TLs加密方式通訊。
通過在服務(wù)端上創(chuàng)建t1s密鑰證書,再下發(fā)給客戶端,客戶端通過私鑰訪問容器,這樣就保證的docker通訊的安全性。
使用證書訪問的工作流程:
8.2 創(chuàng)建ca證書過程
首先創(chuàng)建ca證書, ca證書只是一個(gè)官方認(rèn)證的證書,接下來要?jiǎng)?chuàng)建server, client節(jié)點(diǎn)的證書。此時(shí)創(chuàng)建證書有三步:
(1)設(shè)置私鑰,確保安全加密
(2)使用私鑰簽名,確保身份真實(shí)不可抵賴
(3)使用ca證書制作證書
注意,docker 的go 版本要再1.15版本以下
8.3創(chuàng)建目錄,生成ca證書
8.3.1 創(chuàng)建目錄,生成私鑰文件
#卸載原docker-ce docker-ce-cli,安裝20.10.5-3的版本 [root@host103 ~]#yum remove -y docker-ce-cli docker-ce [root@host103 ~]#yum install -y docker-ce-cli-20.10.5-3.el7.x86_64 docker-ce #docker version查看到的docker 信息中,go版本不可以高于1.15 [root@host103 ~]#docker version#創(chuàng)建目錄 [root@host103 ~]# mkdir /tls [root@host103 ~]# cd /tls/#使用openssl 生成私鑰 [root@host103 tls]# openssl genrsa -aes256 -out ca-key.pem 4096 Generating RSA private key, 4096 bit long modulus ..............................................................................++ .......................................................................++ e is 65537 (0x10001) #驗(yàn)證密碼輸入123123 Enter pass phrase for ca-key.pem:123123 Verifying - Enter pass phrase for ca-key.pem:123123genrsa:使用RSA算法產(chǎn)生私鑰
-aes256:使用256位密鑰的AEs算法對(duì)私鑰進(jìn)行加密,這樣每次使用私鑰文件都將輸入密碼,可省略
-out:輸出文件的路徑,若未指定輸出文件,則為標(biāo)準(zhǔn)輸出
4096:指定私鑰長(zhǎng)度,默認(rèn)為1024。該項(xiàng)必須為命令行的最后一項(xiàng)參數(shù)
8.3.2 創(chuàng)建ca證書
#創(chuàng)建ca證書 [root@host103 tls]# openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem #驗(yàn)證密碼,是之前的123123 Enter pass phrase for ca-key.pem: 123123[root@host103 tls]# ls ca-key.pem ca.pemreq:執(zhí)行證書簽發(fā)命令-new:新證書簽發(fā)請(qǐng)求
-x509:生成x509格式證書,專用于創(chuàng)建私有cA時(shí)使用
-days:證書的有效時(shí)長(zhǎng),單位是天
-key:指定私鑰路徑
-sha256:證書摘要采用sha256算法
-subj: 證書相關(guān)的用戶信息 (subject的縮寫)
-out:輸出文件的路徑
8.4 用ca證書簽發(fā)server端證書
#創(chuàng)建服務(wù)器私鑰 [root@host103 tls]# openssl genrsa -out server-key.pem 4096 Generating RSA private key, 4096 bit long modulus ...................................................++ ..............++ e is 65537 (0x10001)#生成證書簽名請(qǐng)求文件(csr文件) [root@host103 tls]# openssl req -new -key server-key.pem -sha256 -subj "/CN=*" -out server.csr [root@host103 tls]# ls ca-key.pem ca.pem server.csr server-key.pem#使用ca證書與私鑰證書簽發(fā)服務(wù)端簽名證書(密碼123123) [root@host103 tls]# openssl x509 -req -days 1000 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem Signature ok subject=/CN=* Getting CA Private Key Enter pass phrase for ca-key.pem:123123[root@host103 tls]# ls ca-key.pem ca.pem ca.srl server-cert.pem server.csr server-key.pemx509:生成x509格式證書
-req:輸入csr文件
-in:要輸入的csr文件
-CA:指定ca證書的路徑
-CAkey:指定ca證書的私鑰路徑
-CAcreateserial:表示創(chuàng)建證書序列號(hào)文件,創(chuàng)建的序列號(hào)文件默認(rèn)名稱為ca.srl
8.5用ca 證書簽發(fā)client端證書
#生成客戶端私鑰 [root@host103 tls]# openssl genrsa -out client-key.pem 4096 Generating RSA private key, 4096 bit long modulus ......++ ............++ e is 65537 (0x10001) #生成了客戶端私鑰client-key.pem [root@host103 tls]# ls ca-key.pem ca.pem ca.srl client-key.pem server-cert.pem server.csr server-key.pem#生成證書簽名請(qǐng)求文件client-csr [root@host103 tls]# openssl req -new -key client-key.pem -subj "/CN=client" -out client.csr [root@host103 tls]# ls ca-key.pem ca.pem ca.srl client.csr client-key.pem server-cert.pem server.csr server-key.pem#創(chuàng)建擴(kuò)展配置文件extfile.cnf,使得密鑰適合客戶端身份驗(yàn)證 [root@host103 tls]# echo extendedKeyUsage=clientAuth > extfile.cnf#使用ca證書簽發(fā)客戶端簽名證書。密碼123123 [root@host103 tls]# openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem -extfile extfile.cnf Signature ok subject=/CN=client Getting CA Private Key Enter pass phrase for ca-key.pem:[root@host103 tls]# ls ca-key.pem ca.pem ca.srl client-cert.pem client.csr client-key.pem extfile.cnf server-cert.pem server.csr server-key.pem#刪除兩個(gè)證書簽名請(qǐng)求文件和擴(kuò)展配置文件 [root@host103 tls]# rm -rf ca.srl client.csr extfile.cnf server.csr [root@host103 tls]# ls ca-key.pem ca.pem client-cert.pem client-key.pem server-cert.pem server-key.pem8.6 配置docker服務(wù)配置文件,重啟docker
[root@host103 tls]# vim /lib/systemd/system/docker.service #修改13行 ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/tls/ca.pem --tlscert=/tls/server-cert.pem --tlskey=/tls/server-key.pem -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2376#重啟docker配置 [root@host103 tls]# systemctl daemon-reload [root@host103 tls]# systemctl restart docker [root@host103 tls]# netstat -natp | grep 2376 tcp6 0 0 :::2376 :::* LISTEN 81977/dockerd [root@host103 tls]# setenforce 08.7 復(fù)制ca證書和客戶端私鑰,客戶端簽名證書到客戶端主機(jī),并修改服務(wù)端主機(jī)名,做hosts映射
# 復(fù)制ca證書和客戶端私鑰,客戶端簽名證書到客戶端主機(jī) [root@host103 tls]# scp ca.pem 192.168.23.104:/etc/docker/ [root@host103 tls]# scp client-cert.pem 192.168.23.104:/etc/docker/ [root@host103 tls]# scp client-key.pem 192.168.23.104:/etc/docker/#配置服務(wù)端主機(jī)名和ip映射 [root@host103 tls]# echo '127.0.0.1 host103' >> /etc/hosts#本地連接 [root@host103 tls]# docker --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H tcp://host103:2376 images REPOSITORY TAG IMAGE ID CREATED SIZE#本地連接 [root@host103 tls]# docker --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem -H tcp://host103:2376 pull nginx[root@host103 tls]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 87a94228f133 8 days ago 133MB8.8客戶端遠(yuǎn)程訪問
[root@client ~]#yum remove -y docker-ce-cli docker-ce [root@client ~]#yum install -y docker-ce-cli-20.10.5-3.el7.x86_64 docker-ce[root@client ~]# echo '192.168.23.103 host103' > /etc/hosts[root@client ~]# cd /etc/docker/ [root@client docker]# ls ca.pem client-cert.pem client-key.pem daemon.json key.json[root@client docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem -H tcp://host103:2376 images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 87a94228f133 8 days ago 133MB如果訪問報(bào)錯(cuò)如下:
rpc error: code = Unavailable desc = connection error: desc = "transport: authentication handshake failed: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0"則是因?yàn)閐ocker版本過高,其go版本高于1.15,因?yàn)闉?go 1.15 版本開始廢棄 CommonName
九:避免Docker 容器中信息泄露
近幾年 Github 上大量泄露個(gè)人或企業(yè)各種賬號(hào)密碼,出現(xiàn)這種問題一般都使用 dockerfile 或者 docker-compose 文件創(chuàng)建容器。 如果這些文件中存在賬號(hào)密碼等認(rèn)證信息,一旦 Docker 容器對(duì)外開放,則這些宿主機(jī)上的敏感信息也會(huì)隨之泄露。
因此可以通過以下方式檢查容器創(chuàng)建模板的內(nèi)容。
總結(jié)
以上是生活随笔為你收集整理的docker的安全管理与TLS/LLS加密通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: consul 自动发现与自动注册
- 下一篇: 在做TLS/SSL时报错