这是一个纯docker的问题,但因为牵扯到了jenkins 的docker plugin,所以放在一起记录。
漏洞介绍
该未授权访问漏洞是因为docker remote api可以执行docker命令,从官方文档可以看出,该接口是目的是取代docker 命令界面,通过url操作docker。
众所周知,Docker daemon默认是监听在unix socket上的,如unix:///var/run/docker.sock。 官方还提供一个Restful api接口,允许通过TCP远程访问Docker,例如执行以下启动参数可以让docker监听在本地所有地址的2375端口上:
dockerd -H=0.0.0.0:2375 -H unix:///var/run/docker.sock
之后就可以用docker client或任意http客户端远程访问了。但是开启这种没有任何访问控制的Docker remote Api服务是非常危险的,攻击者发现后可以轻松地拿下整个服务器的权限。
而公司使用的docker版的jenkins master,在和docker版的jenkins slave通讯时,就使用了Docker remote Api服务,所以需要修改此漏洞。
Docker-TLS加密通讯
一, 制作CA证书
1,建立专用目录
略
2,创建ca密钥
openssl genrsa -aes256 -out jenkins-ca-key.pem 4096
这一步,需要设置ca密码。
3,创建CA证书(host-master为docker运行的jenkins-slave主机,这里我感觉CN有商议,但测试成功)
openssl req -new -x509 -days 36500 \
-key jenkins-ca-key.pem \
-sha256 -subj "/CN=host-master" \
-out jenkins-ca.pem
这一步,需要输入ca密码。
二, 创建master证书
1,创建master私钥
openssl genrsa -out jenkins-master-key.pem 4096
2,私钥签名(host-master为docker运行的jenkins-slave主机)
openssl req -subj "/CN=host-master" -sha256 -new \
-key jenkins-master-key.pem \
-out jenkins-master.csr
3,制作证书
openssl x509 -req -days 36500 -sha256 \
-in jenkins-master.csr \
-CA jenkins-ca.pem \
-CAkey jenkins-ca-key.pem \
-CAcreateserial \
-out jenkins-master-cert.pem
这一步,需要输入ca密码。
三, 创建client证书
1,创建client私钥
openssl genrsa -out jenkins-client-key.pem 4096
2,私钥签名(host-client为jenkins master运行的主机)
openssl req -subj "/CN=host-client" -sha256 -new \
-key jenkins-client-key.pem -out jenkins-client.csr
3,创建配置文件,指定密钥扩展用途
echo extendedKeyUsage=clientAuth > extfile.cnf
4,制作证书
openssl x509 -req -days 36500 -sha256 \
-in jenkins-client.csr \
-CA jenkins-ca.pem \
-CAkey jenkins-ca-key.pem \
-CAcreateserial \
-out jenkins-client-cert.pem \
-extfile extfile.cnf
这一步,需要输入ca密码。
四, 删除中间文件及多余文件
仅需要如下6个文件
jenkins-ca.pem
jenkins-ca-key.pem
jenkins-client-cert.pem
jenkins-client-key.pem
jenkins-master-cert.pem
jenkins-master-key.pem
不要被我的命名所迷惑,要注意实际的应用场景。在我们这种情况下,jenkins slave上的docker开放端口,所以要用master的密钥。Master上的docker plugin插件访问这个开放端口,所以要用client的密钥。
五, 配置docker启动参数
将需要的文件cp到开放了docker remote api的主机上,更改docker启动命令参数。其中tlscacert,tlscert,tlskey分别对应第4步骤中的文件。
这个docker启动命令的参数更改有好几种方式,合适的方式是不改docker安装位置的文件,而只更改在/etc/systemd/system/docker.service.d/docker.conf文件里面的启动参数。
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/docker-remote-api/tls/jenkins-ca.pem --tlscert=/docker-remote-api/tls/jenkins-master-cert.pem --tlskey=/docker-remote-api/tls/jenkins-master-key.pem --graph=/xxx/docker --storage-driver=overlay -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
更改docker参数之后,记得reload daemon及重启docker。
六, Jenkins master上配置与远程docker服务连接
1, 新增一个credential(三个框和docker启动参数类似,对应三个文件client-key.pem, client-cert.pem ,ca.pem)的内容。
Client Key: client-key.pem
Client Certificate: client-cert.pem
Server CA Certificate: ca.pem
2, 将此credential应用到docker plugin配置当中。
Docker Host URI,只能用主机名或域名连接,用IP不行。
3,如果Test Connection成功,则所有配置OK。
注意事项
- Docker daemon启动可选客户端不验证参数:tls, tlscert, tlskey。
- Curl访问docker remote api时,可以使用不验证证书模式。
- cannot validate certificate for x.x.x.x because it doesn't contain any IP SANs不使用localhost方法:将以上创建证书中的/CN=*星号修改成自己的域名或主机名即可(例如:/CN=demo.com)。
参考文档
https://docs.docker.com/engine/security/https/
https://developer.aliyun.com/article/64970
http://www.maxwoods.net/archives/1748
https://baijiahao.baidu.com/s?id=1630659036589611210&wfr=spider&for=pc
https://blog.csdn.net/ML908/article/details/105826671/
百度关键字:docker remote api tls, tlscert, tlskey