Docker 安全与监控
TLS 加密配置
Docker Daemon 监听 Socket 有三种方式,分别是 unix、tcp 和 fd。其中,监听 fd 文件是使用 system 的系统专用。
在默认配置中,Docker Remote API 通过 Socket 监听来自本地的连接,监听地址位于 unix:///var/run/docker.sock
。可以通过 curl
发送一个简单的请求来测试:
[root@server4 .docker]$ curl --unix-socket /var/run/docker.sock http://localhost/info | python -mjson.tool
{
"Architecture": "x86_64",
"BridgeNfIp6tables": false,
"BridgeNfIptables": false,
"CPUSet": true,
"CPUShares": true,
"CgroupDriver": "cgroupfs",
可以通过 -H
选项来修改监听方式:
[root@server1 ~]$ dockerd -H 192.168.2.234:5999 -H unix:///var/run/docker.sock &
客户端可以通过 docker -H
指定服务端地址来操作服务端。也可以设置 Docker_HOST 变量固定服务器地址:
[root@server4 ~]$ docker -H tcp://192.168.2.234:5999 pull ubuntu
在 Docker 中规定 2375 作为非加密端口,2376 作为加密端口。如果没有启用 TLS,则服务端与客户端的通信没有认证和加密,任何客户端口可以向服务端发送命令。
使用 TLS 通信需要在服务端和客户端中加入 TLS 相关的配置。首先创建 RSA 私钥 ca.key
:
[root@server1 ~]$ openssl genrsa -aes256 -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
..................................................................++
..................++
e is 65537 (0x10001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:
使用 RSA 私钥创建 CA 证书 ca.pem
。参数 -x509
是生成自签名 CA 证书,参数 -days 365
设置证书有效期:
[root@server1 ~]$ openssl req -new -x509 -days 365 -key ca.key -sha256 -out ca.pem
Enter pass phrase for ca.key:
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) [XX]:CN
State or Province Name (full name) []:BeiJing
Locality Name (eg, city) [Default City]:BeiJing
Organization Name (eg, company) [Default Company Ltd]:server1
Organizational Unit Name (eg, section) []:Dev
Common Name (eg, your name or your server's hostname) []:server1
Email Address []:root@server1.com
[root@server1 ~]$ scp ca.* root@192.168.2.241:/root
root@192.168.2.241's password:
ca.key 100% 3326 2.7MB/s 00:00
ca.pem 100% 2094 2.4MB/s 00:00
ca.srl 100% 17 24.3KB/s 00:00
创建服务器私钥和 CSR。其中 server.key
是服务器私钥的文件名,server.csr
是服务器 CSR 文件名:
[root@server1 ~]$ openssl genrsa -out server.key 4096
Generating RSA private key, 4096 bit long modulus
................++
............................................................................................................................................................................................................................................++
e is 65537 (0x10001)
[root@server1 ~]$ openssl req -subj "/CN=server1" -sha256 -new -key server.key -out server.csr
使用 CA 证书创建服务器证书文件,可以限制连接客户端 IP:
[root@server1 ~]$ echo subjectAltName = IP:192.168.2.234,IP:192.168.2.241,IP:127.0.0.1 > allowip.cnf
[root@server1 ~]$ openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out server.pem -extfile allowip.cnf
Signature ok
subject=/CN=server1
Getting CA Private Key
Enter pass phrase for ca.key:
创建客户端私钥和 CSR:
[root@server4 ~]$ openssl genrsa -out client.key 4096
Generating RSA private key, 4096 bit long modulus
................................................................................................................................................................................................................................................++
...............................................................................................................++
e is 65537 (0x10001)
[root@server4 ~]$ openssl req -subj '/CN=server4' -new -key client.key -out client.csr
使用 CA 证书创建客户端证书文件,需要加入 extendedKeyUsage
选项:
[root@server4 ~]$ echo extendedKeyUsage = clientAuth > client.cnf
[root@server4 ~]$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out client.pem -extfile client.cnf
Signature ok
subject=/CN=server4
Getting CA Private Key
Enter pass phrase for ca.key:
创建 PEM 文件之后可以删除 CSR 文件。修改证书权限并移动到 ~/.docker/
目录下:
[root@server4 ~]$ rm -f client.cnf client.csr
[root@server4 ~]$ chmod -v 0400 *.key
mode of ‘ca.key’ changed from 0644 (rw-r--r--) to 0244 (r--r--r--)
mode of ‘client.key’ changed from 0644 (rw-r--r--) to 0244 (r--r--r--)
[root@server4 ~]$ chmod -v 0444 *.pem
mode of ‘ca.pem’ changed from 0644 (rw-r--r--) to 0444 (r--r--r--)
mode of ‘client.pem’ changed from 0644 (rw-r--r--) to 0444 (r--r--r--)
[root@server4 ~]$ mkdir .docker
[root@server4 ~]$ cp ca.pem client.* .docker/
[root@server1 ~]$ rm -f server.csr allowip.cnf
[root@server1 ~]$ chmod -v 0400 *.key
mode of ‘ca.key’ changed from 0644 (rw-r--r--) to 0244 (r--r--r--)
mode of ‘server.key’ changed from 0644 (rw-r--r--) to 0244 (r--r--r--)
[root@server1 ~]$ chmod -v 0444 *.pem
mode of ‘ca.pem’ changed from 0644 (rw-r--r--) to 0444 (r--r--r--)
mode of ‘server.pem’ changed from 0644 (rw-r--r--) to 0444 (r--r--r--)
[root@server1 ~]$ mkdir .docker
[root@server1 ~]$ cp ca.pem server.* .docker/
修改服务端配置文件并重启:
[root@server1 ~]$ vi /etc/docker/daemon.json
{
"tlsverify": true,
"tlscacert": "/root/.docker/ca.pem",
"tlscert": "/root/.docker/server.pem",
"tlskey": "/root/.docker/server.key"
}
[root@server1 ~]$ systemctl restart docker
修改客户端配置文件并重启:
[root@server4 ~]$ vi /etc/docker/daemon.json
{
"tlsverify": true,
"tlscacert": "/root/.docker/ca.pem",
"tlscert": "/root/.docker/client.pem",
"tlskey": "/root/.docker/client.key"
}
[root@server4 ~]$ systemctl restart docker
客户端测试连接:
[root@server4 ~]$ cd /root/.docker/
[root@server4 ~]$ docker --tlsverify --tlscacert=ca.pem --tlscert=client.pem --tlskey=client.key -H tcp://192.168.2.234:5999 ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7198e1cdf396 pytest/volume "/bin/sleep 60" 5 hours ago Exited (0) 5 hours ago clever_aryabhata
Docker Bench
Docker Bench 是一个开源项目,该项目按照互联网安全中心(CIS,Center for Internet Security)对于 Docker 的安全规范进行一系列环境检查。
可以利用 Docker 镜像快速进行检查:
[root@server4 ~]$ docker run -it --net host --pid host --userns host --cap-add audit_control -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST -v /var/lib:/bar/lib -v /var/run/docker.sock:/var/run/docker.sock -v /usr/lib/systemd:/usr/lib/systemd -v /etc:/etc --label docker_bench_security docker/docker-bench-security
Sysdig
Sysdig 是一个轻量级的系统监控工具,原生支持容器。可以使用容器来运行:
[root@server4 ~]$ docker run -it --rm --name=sysdig --privileged --volume=/var/run/docker.sock:/host/var/run/docker.sock --volume=/dev/:/host/dev/ --volume=/proc/:/host/proc/:ro --volume=/boot/:/host/boot/:ro --volume=/lib/modules/:/host/lib/modules/:ro --volume=/usr/:/host/usr/:ro sysdig/sysdig
启动后进入容器执行 csysdig
命令:
root@213496097e95:/# csysdig
PID PPID CPU USER TH VIRT RES FILE NET Command
1250 1 0.50 root 16 1G 40M 0 0.00 /usr/bin/contain
5459 5298 0.50 root 2 362M 15M 0 0.00 csysdig
1500 1 0.00 root 1 88M 2M 0 0.00 /usr/libexec/pos
1506 1500 0.00 1 88M 4M 0 0.00 pickup -l -t uni
4624 4511 0.00 www-data 1 222M 9M 0 0.00 apache2 -DFOREGR
954 1 0.00 2 65M 3M 0 0.00 /usr/bin/dbus-da
4475 1477 0.00 root 7 806M 10M 0 0.00 /usr/bin/docker-
947 1 0.00 root 3 267M 5M 0 0.00 /usr/bin/vmtools
5254 5233 0.00 root 11 1G 39M 4K 0.00 docker run -it -
4291 4272 0.00 8 1G 74M 0 0.00 mysqld
1036 1 0.00 root 1 108M 860K 0 0.00 /sbin/agetty --n
1507 1500 0.00 1 88M 4M 0 0.00 qmgr -l -t unix
948 1 0.00 7 598M 14M 0 0.00 /usr/lib/polkit-
F1Help F2Views F4FilterF5Echo F6Dig F7LegendF8ActionsF9Sort F12Spe 8/43(18.6%)
Weave Scope
Weave Scope 可以将 Docker 容器分布生成一张地图,看起来很直观:
[root@server4 ~]$ sudo curl -L https://github.com/weaveworks/scope/releases/download/latest_release/scope -o /usr/local/bin/scope
[root@server4 ~]$ chmod a+x /usr/local/bin/scope
[root@server4 ~]$ scope launch
Scope probe started
Weave Scope is listening at the following URL(s):
* http://192.168.2.204:4040/
* http://172.18.0.1:4040/
使用 scope launch
将以容器方式启动 Weave Scope,之后通过 http://192.168.2.204:4040/
在浏览器访问。
如果需要监控多台主机,在 scope launch
后面加上对应主机的 IP 地址,并在每台主机上运行:
[root@server4 ~]$ scope launch 192.168.2.204 192.168.2.205 192.168.2.206
加入基本账号验证:
[root@server4 ~]$ scope launch -app.basicAuth -app.basicAuth.password 123456 -app.basicAuth.username user -probe.basicAuth -probe.basicAuth.password 123456 -probe.basicAuth.username user
ELK
ELK 套件是三个软件的合称:Elasticsearch(搜索引擎)、Logstash(日志分析)和 Kibana(可视化)。
下面采用最小部署。其中,5601 是 Kibana web 接口,9200 是 Elasticsearch JSON 接口,5044 是 Logstash 日志接口:
[root@server4 ~]$ docker run -d -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk
如果启动报错 “vm.max_map_count [65530] is too low”,需要修改 /etc/sysctl.conf
文件:
[root@server4 ~]$ vi /etc/sysctl.conf
vm.max_map_count=262144
[root@server4 ~]$ sysctl -p
net.ipv4.ip_forward = 1
vm.max_map_count = 262144
启动之后通过 http://192.168.2.204:5601/ 来访问。由于目前没有任何日志,所以还需要使用 Filebeat 来配合,它能将指定路径下的日志文件转发给 ELK:
[root@server4 ~]$ curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.3.0-x86_64.rpm
[root@server4 ~]$ rpm -vi filebeat-7.3.0-x86_64.rpm
之后修改 Filebeat 配置文件:
[root@server4 ~]$ vi /etc/filebeat/filebeat.yml
#=========================== Filebeat inputs =============================
- type: log
enabled: true
paths:
- /var/lib/docker/containers/*/*.log
- /var/log/*.log
#-------------------------- Elasticsearch output ------------------------------
output.elasticsearch:
# Array of hosts to connect to.
hosts: ["localhost:9200"]
[root@server4 ~]$ filebeat setup -e
启动 Filebeat 后,监控的日志会发送给 Elasticsearch:
[root@server4 ~]$ systemctl start filebeat.service
访问 http://192.168.2.204:5601,进入 Kibana 的 Discover 页面,即可查看日志。