author: aming
email: jikcheng@163.com
title: Docker安全防护与配置
creation_date: 2023-02-08 12:26
Last modified date: 2023-02-08 14:09
tags: Docker安全防护与配置
File Folder with relative path: reading notes/doc
remark:
other:
本章背景知识
运行在容器内部的进程与运行在本地系统中的进程本质上并无区别,当配置不合适的安全策略可能给本地系统带来安全风险。
本章从虚拟机、容器的隔离和共享机制引导出安全性相关知识。
一、黑客的攻击手段
黑客常用的攻击手段主要有:
1、代码执行;
2、权限提升;
3、信息泄露;
4、权限绕过。
二、 Docker 的层叠安全机制
1、Dokcer 主要采取了层叠式安全机制,即用多层不同安全技术融合在一起的层层防护。
2、如果一个恶意进程突破了某一层防护,紧接着还有下一层基于不同安全机制的防护。
三、Docker 的安全基线标准
本章主要从以下六个方面进行评估安全性。
1、 内核;
2、主机;
3、网络;
4、镜像;
5、容器;
6、其他。
四、Docker Bench
1、Docker Bench 是什么?
该项目按照互联网安全中心(Center for Internet Security,CIS)对于 Docker 1.11+的安全规范进行一系列环境检查,发现当前 Docker 部署在配置、安全等方面的潜在问题。
2、 CIS Docker 规范
CIS Docker 规范在包括
(1)主机配置
(2)Docker 引擎
(3)配置文件权限
(4)镜像管理。
(5)容器运行时环境。
(6)安全项
等六大方面都进行了相关的约束和规定。
01 Docker 容器与虚拟机
一、隔离与共享机制
1、虚拟机隔离机制。
(1)创建虚拟机:
通过添加 Hypervisor 层,创建虚拟网卡、内存、CPU 等虚拟硬件,建立操作系统。
(2)隔离的实现:
每个虚拟机都有自己的系统内核和堆栈空间。
2、容器隔离机制。
(1)创建容器: 通过 LInux 系统自带的隔离的方式,将文件系统、进程、设备、网络等资源进行隔离,对权限、CPU 资源等进行控制,最终实现容器之间互不影响。
(2)容器与宿主机共享内核、文件系统、硬件等资源。
二、性能与损耗
根据隔离和共享机制原理可以得出,与虚拟机相比,容器更加轻量,容器资源损耗更低。
三、安全性
根据隔离和共享机制原理可以得出:
1、虚拟机的安全性要比容器好,要从虚拟机攻破到宿主机或其他虚拟机,需要先攻破 Hypervisor
层,这是极其困难的。
2、由于 Docker 容器与宿主机共享内核、文件系统等资源,将会对其他容器、宿主机产生安全影响。
02 Docker 本身的安全问题
一、Docker CVE 漏洞
1、 Docker Engine 是一种应用程序,本身实现上会有代码缺陷。
2、官方记录 (CVE ) Docker 历史版本共有超过 20 项漏洞。这些漏洞将会成为黑客的攻击手段。
编者注:将 Docker Engine 升级为最新版本,降低黑客攻击的风险。
二、Docker Hub 安全性
Docker Hub
可以让用户上传创建的镜像,以便其他用户下载,快速搭建环境。但同时也带来了一些安全问题。
1、黑客上传恶意镜像。
如果有黑客在制作的镜像中植入木马、后门等恶意软件,那么环境就已经不安全了。
编者注:在生产环境中,尽量下载官方镜像,确保镜像的安全。
2、镜像里软件漏洞。
下载镜像后,需要检查里面软件的版本信息。如果版本不是最新的,攻击者将会使用这些漏洞进行攻击。
编者注:Docker Hub镜像里面,75%的镜像都安装了有漏洞的软件。所以下载镜像后,需要检查里面软件的版本信息,对应的版本是否存在漏洞,并及时更新打上补丁。
3、镜像的恶意篡改。
下载镜像时,通过互联网传输镜像文件,黑客可以将自己的后门软件导入镜像之中。
编者注: Docker 提供了校验机制来预防这个问题,保证镜像的一致性。
03 Docker 架构安全
本节主要介绍Docker 架构与策略设置不合理时导致的安全问题。
一、容器之间的局域网攻击
1、黑客已经控制了宿主机上的一些容器,或者新建一些容器,然后对宿主机或其他容器发起攻击。
2、这些容器之间可以构成局域网,黑客可以采取局域网的 ARP 欺骗、嗅探、广播风暴等攻击方式,进行攻击和破坏。
编者注:建议在一个主机上部署多个容器需要合理的配置网络,设置防火墙规则。
二、DDoS 攻击耗尽资源
当单一的容器分配资源不合理时,黑客攻击可以耗尽宿主机资源,造成堆栈溢出,从而获取 root 权限。
编者注:建议Cgroups (资源限制)安全机制就是要防止此类攻击的。
三、共享 root 用户权限
以 root 用户权限运行容器,容器内的 root 用户也就拥有了宿主机的 root 权限。
编者注:建议使用普通的操作系统用户 docker
运行容器。
04 内核安全
一、Linux 内核版本更新
保持内核为较新的版本,可以防止黑客利用知名的漏洞进行攻击。
1、内核版本号。
Linux 的版本号分为两部分,即内核版本与发行版本。内核版本号由 3 个数字组成:A.B.C。
含义 | 说明 |
---|---|
A | 内核主版本号。这是很少发生变化,只有当发生重大变化的代码和内核发生才会发生。在历史上曾改变两次的内核:1994 年的 1.0 及 1996 年的 2.0。 |
B | 内核次版本号。是指一些重大修改的内核。偶数表示稳定版本;奇数表示开发中版本。 |
C | 内核修订版本号。是指轻微修订的内核。这个数字当有安全补丁, bug 修复,新的功能或驱动程序,内核便会有变化。 |
2、内核版本分类。
分类 | 说明 |
---|---|
mainline | 主线版本 |
stable | 稳定版,由 mainline 在时机成熟时发布,稳定版也会在相应版本号的主线上提供 bug 修复和安全补丁,但内核社区人力有限,因此较老版本会停止维护,而标记为 EOL (End of Life) 的版本表示不再支持的版本。 |
longterm (Long Term Support) | 长期支持版,长期支持版的内核不再支持时会标记 EOL。 |
linux-next,snapshot | 代码提交周期结束之前生成的快照用于给 Linux 代码贡献者们做测试。 |
二、命名空间(User NameSpace)隔离的安全
1、命名空间是什么?
通过命名空间机制,每个容器都有自己独有的网络栈,意味着它们不能访问其他容器的套接字(socket)或接口。
2、命名空间的作用。
(1)启动一个容器时,将在后台为容器创建一个独立的命名空间。
(2)命名空间负责容器之间的隔离,在容器中运行的进程不会被运行在本地主机上的进程和其他容器通过正常渠道发现和影响。
3、命名空间和安全
禁止将容器的命名空间与宿主机进程命名空间共享。
三、控制组资源控制(Cgroups)的安全
1、控制组是什么?
控制组是 Linux 容器机制中的另外一个关键组件,它负责实现资源的审计和限制。
2、资源控制的作用。
(1)Docker 将通过 Linux 相关的调用,在后台为容器创建一个独立的控制组策略集合,该集合将限制容器内应用对资源的消耗。
(2)确保各个容器可以公平地分享主机的内存、CPU、磁盘IO等资源;
3、资源控制和安全。
(1)可以限制容器对资源的占用,确保了当某个容器对资源消耗过大时,不会影响到本地主机系统和其他容器。
(2)可以防止恶意攻击特别是拒绝服务攻击(DDos
)。
四、 控制文件访问权限(SELinux)
1、什么是 SELinux?
安全增强型 Linux(SELinux)是一种采用安全架构的 Linux® 系统,它能够让管理员更好地管控哪些人可以访问系统。它最初是作为 Linux 内核的一系列补丁,由美国国家安全局(NSA)利用 Linux 安全模块(LSM)开发而成。
2、SElinux 的作用。
SELinux 定义了每个人对系统上的应用、进程和文件的访问控制。利用安全策略(一组告知 SELinux 哪些能访问,哪些不能访问的规则)来强制执行策略所允许的访问。
3、SELinux 和安全。
(1)增加更多的编译和运行时的安全检查;并且通过地址随机化机制来避免恶意探测等。
(2)用户可以自定义更加严格的访问控制机制来定制安全策略。
(3)在将文件系统挂载到容器内部时候,可以通过配置只读 (read-only)模式来避免容器内的应用通过文件系统破坏外部环境。
五、内核能力机制(Capability)
1、什么是内核能力机制?
能力机制(Capability)是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制。
2、内核能力机制的作用。
(1)Docker 启动的容器被严格限制只允许使用内核的一部分能力,包括:
chown、dac_override、fowner、kill、setgid、 setuid、setpcap、net_bind_service、net_raw、sys_chroot、mknod、setfcap、audit_write
(2)禁止访问宿主机一些文件系统的操作,比如创建新的设备、修改文件属性等;
(3)禁止直接访问宿主机的套接字;
(4)禁止宿主机模块加载。
3、内核能力机制和安全
恰当分配了内核能力后,就算攻击者在容器中取得了 root 权限,也不能获得本地主机的较高权限,能进行的破坏也有限。
05 Docker API 接口安全
一、Docker API 接口
Docker 提供以下四种 API 接口,分别是:
1、Docker Registry API
Docker Registry API 为了简化镜像和仓库的存储而设计的 REST API。这些 API 并不涉及用户账户和用户认证。
2、Docker Hub API
Docker Hub API 是为 Docker Hub 设计的 REST API。Docker Hub(也就是 Index)是使用校验和公共 namespaces 的方式来存储账户信息、认证账户、进行账户授权。API同时也允许操作相关的用户仓库和 library 仓库。
3、Docker OAuth API。
Docker hub提供V2版本接口后,使用了新的认证授权方式,需要通过OAuth的认证授权方式来调用其API。
4、Docker Remote API
这套 API 用于控制主机 Docker 服务端的 API,等价于 docker 命令行客户端。有了它,你能远程操作 docker 容器,更重要的是你可以通过程序自动化运维 docker 进程。
二、Docker API 接口和安全
1、访问 API支持两种模式:
(1)HTTPS
(2)HTTP
2、API 接口和安全机制:
(1)确保只有可信的网络或 VPN 网络,或证书保护机制下的访问可以进行。
(2)使用 ssl 认证加强保护。
(3)使用 HTTPS 和证书来加强保护。
编者注:对于 Docker API 接口的介绍:请参见:
https://segmentfault.com/a/1190000002711455
docker api是什么-Docker-PHP中文网
06 宿主机安全
1、容器存储目录创建独立操作系统分区。
2、容器内只运行必要的服务。
3、禁止将宿主机上敏感目录映射到容器。
4、对 Docker 守护进程、相关文件和目录进行审计。
5、设置适当的默认文件描述符数。
编者注:
文件描述符:内核(kernel)利用文件描述符(file descriptor)来访问文件。文件描述符是非负整数。
打开现存文件或新建文件时,内核会返回一个文件描述符。读写文件也需要使用文件描述符来指定待读写的文件。
6、用户权限为 root 的 Docker 相关文件的访问权限应该为644
或者更低权限。
7、周期性检查每个主机的容器清单,并清理不必要的容器。
07 网络安全
1、通过 iptables 设定规则实现:禁止或允许容器之间相互连接。
2、禁止将 Docker 绑定到其他 IP/Port
或者 Unix Socket
。
3、禁止在容器上映射特权端口。
4、禁止在容器上使用主机网络模式。
5、只开放容器所需要的端口。
6、若宿主机有多个网卡,将容器进入流量绑定到特定的主机网卡上。
08 镜像安全
1、Docker 镜像进行安全扫描,通过与 CVE 数据库同步扫描镜像,一旦发现漏洞则通知用户处理,或者直接阻止继续构建。
2、如果公司使用的是自己的镜像源,可以跳过检查;
3、如果是第三方镜像源,则至少需要验证 basetime 的 md5 等特征值。
4、不建议使用 --insecure-registry=[]
参数。
LAB01- 使用证书加固 Docker Daemon 安全
Docker Daemon 启动的服务对外提供的是 HTTP 接口,为了增强 HTTP 连接的安全性,我们通过设置 TLS 来认证客户端是可信的,只有通过证书验证的客户端才可以连接 Docker Daemon。
通常情况下服务器和客户端证书都需要通过第三方 CA 签发,在本实验中为了操作方便,我们使用的是自签名的证书。
一、设置环境变量
1、设置一个 RANDFILE
的环境变量:防止报错。
[docker@node1 ~]$ export RANDFILE=.rnd
2、创建存放证书的目录。
[ docker@node1 ~]$ mkdir -p ~/. docker
[ docker@node1 ~]$ cd ~/. docker
二、创建 CA 证书
1、创建 CA 私钥,
创建 CA 私钥,注意需要输入密码,这个密码是不会显示的,请务必记住。
[docker@node1 .docker]$ openssl genrsa -aes256 -out ca-key.pem 4096
回显信息。
Generating RSA private key, 4096 bit long modulus
................................................++
...................................++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem: # 此处输入你想设置的密码(kingbase)
Verifying - Enter pass phrase for ca-key.pem: # 再次输入
2、创建 CA 公钥。
ca-key.pem
创建用来签名的公钥 ca.pem
,输入必要的信息:
[docker@node1 .docker]$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem: # 输入之前设置的密码
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
....
Country Name (2 letter code) [AU]:CN # 输入国家代码
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:kingbase # 输入组织名
Organizational Unit Name (eg, section) []:kingbase
Common Name (e.g. server FQDN or YOUR name) []:192.168.40.111 # 输入服务器域名
Email Address []:kingbase@kingbase.com
输入的信息 | 输入信息 |
---|---|
Country Name (2 letter code) [AU]: | CN |
State or Province Name | Beijing |
Locality Name | Beijing |
Organization Name | kingbase |
Organizational Unit Name | kingbase |
Common Name | 192.168.40.111 |
三、 服务端证书配置
接着创建服务器的 key 和证书 server.csr
,然后使用 CA 证书签发服务器证书:
[docker@node1 .docker]$ openssl genrsa -out server-key.pem 4096
//屏幕输出
Generating RSA private key, 4096 bit long modulus
....................................................................................................................................................++
.................................................................................................................................................................................................................++
e is 65537 (0x10001)
[docker@node1 .docker]$ openssl req -subj "/CN=192.168.40.111" -sha256 -new -key server-key.pem -out server.csr
[docker@node1 .docker] echo subjectAltName = IP:192.168.40.111 >> extfile.cnf
# 设置仅用于服务器身份验证
[docker@node1 ~]$ echo extendedKeyUsage = serverAuth >> extfile.cnf
[docker@node1 .docker] openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=localhost
Getting CA Private Key
Enter pass phrase for ca-key.pem: # 输入密码。
上面的步骤中 extfile.cnf
文件的作用是添加允许连接的 IP 地址,注意服务器证书创建时需要输入服务器的域名,在本实验中我们是用的是 *
。
四、客户端证书配置
客户端的证书用来连接 Docker Daemon 服务,同服务器端证书的操作类似,先创建 key 和 csr 证书,然后使用 CA 签发:
[docker@node1 .docker]$ openssl genrsa -out client-key.pem 4096
[docker@node1 .docker]$ openssl req -subj '/CN=client' -new -key client-key.pem -out client.csr
[docker@node1 .docker] echo extendedKeyUsage = clientAuth > client-extfile.cnf
[docker@node1 .docker]$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile client-extfile.cnf
终端会有如下显示:
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem: # 输入之前设置的密码
现在查看 /home/docker/.docker
目录下所有创建的证书和 key 文件:
已经生成了 cert.pem
和 server-cert.pem
,我们就可以删除两个证书签名请求了:
[docker@node1 .docker]$ rm -v client.csr server.csr
为防止意外损坏密钥,我们删除其写入权限:
[docker@node1 .docker]$ chmod -v 0400 ca-key.pem server-key.pem client-key.pem
[docker@node1 .docker]$ chmod -v 0444 ca.pem server-cert.pem cert.pem
五、配置服务端
1、修改 daemon. json
[root@node1 ~]# vi /etc/docker/daemon.json
------------写入以下内容------------
{
"graph": "/data",
"tls": true,
"tlscacert": "/home/docker/.docker/ca.pem",
"tlscert": "/home/docker/.docker/server-cert.pem",
"tlskey": "/home/docker/.docker/server-key.pem",
"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"],
"tlsverify": true
}
键 | 说明 |
---|---|
“tls”: true | 默认 false, 启动 TLS 认证开关。 |
“tlscacert”: “ca. pem” | 默认 ~/. docker/ca. pem,通过 CA 认证过的 certificate 文件路径 |
“tlscert”: “server-cert. pem” | 默认 ~/. docker/cert. pem ,TLS 的 certificate 文件路径 |
“tlskey”: “server-key. Pem” | 默认 ~/. docker/key. pem,TLS 的 key 文件路径。 |
“tlsverify”: true | 默认 false ,使用 TLS 并做后台进程与客户端通讯的验证。 |
“hosts”: | 设置 Docker API 接口监听地址。 |
2、修改 docker. service 文件
编者注:因为在 systemd
用于启动 Docker 守护程序的系统上 -H
已设置,因此您无法使用该 hosts
键 daemon.json
来添加侦听地址。请参阅:
https://docs.docker.com/engine/admin/systemd/#custom-docker-daemon-options
1、找到 ExecStart 并修改成以下内容
[root@node1 log]# vi /usr/lib/systemd/system/docker.service
----------修改如下---------------------------------
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd. sock
2、生效修改的内容
[root@node1 ~]# systemctl daemon-reload
2、重启 Docker Daemon 进程。
[root@node1 ~]# service docker restart
六、客户端连接 Docker
直接使用不增加证书参数的方式连接并执行 docker image ls
,系统会返回不能连接。而使用客户端连接则可以正确执行。新开一个终端命令窗口执行如下命令:
1、使用 TLS 加密连接方式连接到 Docker 服务。
[docker@node1 ~]$ docker --tlsverify --tlscacert=/home/docker/.docker/ca.pem --tlscert=/home/docker/.docker/cert.pem --tlskey=/home/docker/.docker/client-key.pem -H=192.168.40.111:2376 image ls
//屏幕输出:
docker --tlsverify --tlscacert=/home/docker/.docker/ca.pem --tlscert=/home/docker/.docker/cert.pem --tlskey=/home/docker/.docker/client-key.pem -H=192.168.40.111:2376 image ls
LAB02 -设置特权级运行的容器
有的时候我们需要容器具备更多的权限,比如操作内核模块,控制 swap 交换分区,挂载 USB 磁盘,修改 MAC 地址等。本实验中我们给予容器这些权限,仅仅通过一个简单的 --privileged=true
的参数。
一、关闭超级权限
1、创建 kcp_centos01,一个不具备特权参数的容器
docker run -ti -h node111 --name kcm_centos01 --network host centos:7.2.1511 /bin/bash
2、安装 iproute 软件包。
yum install iproute -y
3、查看容器的 IP 地址和 MAC 地址信息。
ip a
//屏幕输出:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:73:e1:51 brd ff:ff:ff:ff:ff:ff
inet 192.168.40.111/24 brd 192.168.40.255 scope global eno16777736
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe73:e151/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 500
link/ether 52:54:00:62:ff:61 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:96:f5:99:ff brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:96ff:fef5:99ff/64 scope link
valid_lft forever preferred_lft forever
4、修改 mac 地址。
ip link set eno16777736 address 00:01:02:03:04:05
//屏幕输出:
RTNETLINK answers: Operation not permitted
修改失败。
二、开启超级权限
1、创建 kcp_centos01,一个不具备特权参数的容器
docker run -ti --privileged=true -h node112 --name kcm_centos02 --network host centos:7.2.1511 /bin/bash
2、安装 iproute 软件包。
yum install iproute -y
3、查看容器的 IP 地址和 MAC 地址信息。
ip a
4、修改 mac 地址。
ip link set eno16777736 address 00:01:02:03:04:05
5、查看修改后的结果。
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:01:02:03:04:05 brd ff:ff:ff:ff:ff:ff
inet 192.168.40.111/24 brd 192.168.40.255 scope global eno16777736
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe73:e151/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 500
link/ether 52:54:00:62:ff:61 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:96:f5:99:ff brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:96ff:fef5:99ff/64 scope link
valid_lft forever preferred_lft forever
三、查看容器详细信息
docker inspect kcm_centos01 | grep Privileged
docker inspect kcm_centos02 | grep Privileged
LAB03 - Docker Bench Security
增强 Docker 安全性的手段。要逐一去检查会比较繁琐,这里提供 Docker Bench
自动化检查的开源工具。
一、快速安全检查
$ docker run --rm --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker/docker-bench-security
// 屏幕输出:
# ------------------------------------------------------------------------------
# Docker Bench for Security v1.3.4
#
# Docker, Inc. (c) 2015-
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Inspired by the CIS Docker Community Edition Benchmark v1.1.0.
# ------------------------------------------------------------------------------
Initializing Thu Feb 9 05:32:26 UTC 2023
[INFO] 1 - Host Configuration
[WARN] 1.1 - Ensure a separate partition for containers has been created
[NOTE] 1.2 - Ensure the container host has been Hardened
[INFO] 1.3 - Ensure Docker is up to date
[INFO] * Using 20.10.22, verify is it up to date as deemed necessary
[INFO] * Your operating system vendor may provide support and security maintenance for Docker
[INFO] 1.4 - Ensure only trusted users are allowed to control Docker daemon
[INFO] * docker:x:983
[WARN] 1.5 - Ensure auditing is configured for the Docker daemon
[WARN] 1.6 - Ensure auditing is configured for Docker files and directories - /var/lib/docker
[WARN] 1.7 - Ensure auditing is configured for Docker files and directories - /etc/docker
[WARN] 1.8 - Ensure auditing is configured for Docker files and directories - docker.service
[WARN] 1.9 - Ensure auditing is configured for Docker files and directories - docker.socket
[INFO] 1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker
[INFO] * File not found
[WARN] 1.11 - Ensure auditing is configured for Docker files and directories - /etc/docker/daemon.json
[INFO] 1.12 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-containerd
[INFO] * File not found
[INFO] 1.13 - Ensure auditing is configured for Docker files and directories - /usr/bin/docker-runc
[INFO] * File not found
编者注:输出结果中,带有不同的级别,说明问题的严重程度。一般要尽量避免出现 WARN 或以上的问题。
二、输出结果说明
1、信息说明。
标记 | 说明 |
---|---|
PASS | 这些项目都是很稳固的,不需要关注,pass 越多越好。 |
WARN | 需要修复的项目。 |
INFO | 如果这些项目和你的设置和安全需要相关,建议检查和修复这些项目。 |
NOTE | 一些建议。 |
2、信息分类。
分类 | 说明 |
---|---|
[INFO] 1 - Host Configuration | 宿主机配置。 |
[INFO] 2 - Docker daemon configuration | Docker Engine 配置。 |
[INFO] 3 - Docker daemon configuration files | Docker Engine 配置文件。 |
[INFO] 4 - Container Images and Build File | 容器镜像和编译文件。 |
[INFO] 5 - Container Runtime | 容器运行情况。 |
[INFO] 6 - Docker Security Operations | Docker 安全相关类。 |
三、评分查看
对当前 Docker 服务器进行打分为 15 分。
[INFO] Checks: 105
[INFO] Score: 15
LAB04 设置容器权限白名单
--privileged=true
的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供给容器必须的权限。所以 Docker 提供了权限白名单的机制,使用 --cap-add
来添加必要的权限。
为了能够修改 MAC 地址,我们给予新的容器 kcm_centos03 一个 NET_ADMIN
的权限。
一、创建容器
添加 --cap-add=NET_ADMIN
。
docker run -ti -h node113 --cap-add=NET_ADMIN --name kcm_centos03 --network host centos:7.2.1511 /bin/bash
二、修改 MAC 地址
1、安装 iproute 软件包。
yum install iproute -y
2、查看容器的 IP 地址和 MAC 地址信息。
ip a
3、修改 mac 地址。
ip link set eno16777736 address 00:01:02:03:04:05
4、查看修改后的结果。
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:01:02:03:04:05 brd ff:ff:ff:ff:ff:ff
inet 192.168.40.111/24 brd 192.168.40.255 scope global eno16777736
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe73:e151/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN group default qlen 500
link/ether 52:54:00:62:ff:61 brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:96:f5:99:ff brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:96ff:fef5:99ff/64 scope link
valid_lft forever preferred_lft forever
三、查看容器权限的白名单
退出容器后,可以在docker container inspect
命令中查看容器的必要配置:
docker container inspect -f {{.HostConfig.Privileged}} kcm_centos03
//屏幕输出:
false
docker container inspect -f {{.HostConfig.CapAdd}} kcm_centos03
//屏幕输出:
{[NET_ADMIN]}