通信安全—docker建立客户端与服务端TLS证书连接
Posted 透过水花看花儿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通信安全—docker建立客户端与服务端TLS证书连接相关的知识,希望对你有一定的参考价值。
通信安全—docker建立客户端与服务端TLS证书连接
一、TLS证书的作用
在远程上调用Docker时,若没有设置TLS证书,那么docker能被所有人调用,而TLS的作用就是限制指定的主机对Docker进行远程调用,从而保证docker的安全。
二、创建证书
使用openssl来创建CA,并签署秘钥/证书。
1、创建目录
首先创建一个certs目录,并内置三个子目录 ca、client、server,分别用来存放证书,客户端密钥,服务端密钥。
### 在登录用户下递归创建三个目录
mkdir -p ~/certs/ca,client,server
2、创建私钥
运行openssl创建CA秘钥,并将CA证书保存在~/certs/ca 目录下。
###创建密钥ca-key.pem,用于创建对应的证书
openssl genrsa -out ~/certs/ca/ca-key.pem 2048
3、创建证书
通过创建的密钥,创建
###创建证书:ca.pem
openssl req -x509 -new -nodes -key ~/certs/ca/ca-key.pem \\ -days 10000 -out ~/certs/ca/ca.pem -subj '/CN=docker-CA'
4、创建扩展配置文件
创建一个用于client的openssl配置文件~/certs/client/openssl.cnf
###创建文件:openssl.cnf
vim ~/certs/client/openssl.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
创建一个用于server的openssl配置文件~/certs/server/openssl.cnf
alt_names中的ip为Docker Server的ip,即client需要访问的ip,若有多个docker服务,此处填写多个,否则client将无法访问Docker Server
###创建配置文件:openssl.cnf
vim ~/certs/server/openssl.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = docker.local
IP.1 = 192.168.9.1
IP.2 = 192.168.9.2
三、签署证书
为服务端创建并签署证书:
- ~/certs/server/key.pem
- ~/certs/server/cert.csr
- ~/certs/server/cert.pem
###创建服务端
openssl genrsa -out ~/certs/server/key.pem 2048
openssl req -new -key ~/certs/server/key.pem \\
-out ~/certs/server/cert.csr \\
-subj '/CN=docker-server' -config ~/certs/server/openssl.cnf
openssl x509 -req -in ~/certs/server/cert.csr -CA ~/certs/ca/ca.pem \\
-CAkey ~/certs/ca/ca-key.pem -CAcreateserial \\
-out ~/certs/server/cert.pem -days 365 -extensions v3_req \\
-extfile ~/certs/server/openssl.cnf
为客户端创建并签署证书:
- ~/certs/client/key.pem
- ~/certs/client/cert.csr
- ~/certs/client/cert.pem
$ openssl genrsa -out ~/certs/client/key.pem 2048
$ openssl req -new -key ~/certs/client/key.pem -out ~/certs/client/cert.csr \\
-subj '/CN=docker-client' -config ~/certs/client/openssl.cnf
$ openssl x509 -req -in ~/certs/client/cert.csr -CA ~/certs/ca/ca.pem \\
-CAkey ~/certs/ca/ca-key.pem -CAcreateserial \\
-out ~/certs/client/cert.pem -days 365 -extensions v3_req \\
-extfile ~/certs/client/openssl.cnf
创建成功后可见的目录结构:
├── ca
│ ├── ca-key.pem
│ ├── ca.pem
│ └── ca.srl
├── client
│ ├── cert.csr
│ ├── cert.pem
│ ├── key.pem
│ └── openssl.cnf
└── server
├── cert.csr
├── cert.pem
├── key.pem
└── openssl.cnf
四、Docker中配置TLS证书
查看配置文件位置:
systemctl show --property=FragmentPath docker
回显:FragmentPath=/lib/systemd/system/docker.service
配置文件中开启TLS,并配置服务端证书,将上一步生成好的server证书和ca.pem拷贝至/etc/docker/ssl
替换配置文件13行:/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd-current -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock --tlsverify --tlscacert=/etc/docker/ssl/ca.pem --tlscert=/etc/docker/ssl/cert.pem --tlskey=/etc/docker/ssl/key.pem
###这是复杂的修改:此处不解释
ExecStart=/usr/bin/dockerd-current -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock \\
--add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \\
--default-runtime=docker-runc \\
--exec-opt native.cgroupdriver=systemd \\
--userland-proxy-path=/usr/libexec/docker/docker-proxy-current \\
--init-path=/usr/libexec/docker/docker-init-current \\
--seccomp-profile=/etc/docker/seccomp.json \\
--tlsverify \\
--tlscacert=/etc/docker/ssl/ca.pem \\
--tlscert=/etc/docker/ssl/cert.pem \\
--tlskey=/etc/docker/ssl/key.pem \\
$OPTIONS \\
$DOCKER_STORAGE_OPTIONS \\
$DOCKER_NETWORK_OPTIONS \\
$ADD_REGISTRY \\
$BLOCK_REGISTRY \\
$INSECURE_REGISTRY \\
$REGISTRIES
修改之后重新加载systemd和Docker服务
###重载服务配置文件
sudo systemctl daemon-reload
###重启服务
sudo systemctl restart docker
五、测试
客户端:未使用TLS证书,访问远程docker
docker -H tcp://192.168.9.1:2376 version
客户端:使用TLS证书访问远程Docker
docker --tlsverify --tlscacert=./ca.pem --tlscert=./client/cert.pem --tlskey=./client/key.pem -H tcp://192.168.9.1:2376 version
扩展一:命令演示
###查看CRL分发点在证书X509v3详细信息(client-cert.pem)
openssl x509 -in client-cert.pem -noout -text
###撤销客户端证书(client-cert.pem)
openssl ca -config ./openssl.cnf -revoke client-cert.pem
###验证证书是否有效
openssl verify -CAfile ca.pem client-cert.pem
### 立即撤销了客户端的访问权限(有问题,没搞懂)
openssl ca -config intermediate/openssl.cnf -revoke intermediate/certs/bob@example.com.cert.pem
###设置防火墙访问规则:Iptables
##启动防火墙
systemctl start firewalld
## 然后,在宿主机的 firewalld 上做 IP 访问控制即可。(source address 是客户端地址)
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.88.77" port protocol="tcp" port="2375" accept"
firewall-cmd --reload
##客户端操作实现远程调用
docker -H tcp://192.168.88.67 images
扩展二:原理说明
对称和非对称秘钥双重加密的流程图
大概流程
- 先对明文—>对称加密—>形成密文和对称秘钥
- 然后将对称秘钥+签名—>非对称加密(私钥加密)—>形成加密的秘钥
- 使用hash算法算出hash值
- 最后将密文、加密的秘钥、hash值传给对方
- 对方收到这三样数据
- 对加密的秘钥—>非对称解密(公钥解密)—>解密出对称秘钥和签名(签名用于身份认证)
- 使用对称秘钥—>对称解密—>解密出明文
- 对明文使用hash算法,对比传来的hash值
一样说明没有被改动,读取数据;反之被改的,弃掉数据
(1)什么叫做秘钥
对称秘钥(AES、DES、3DES) 相对于家里的锁和对应的钥匙 效率高,但不安全。
非对称秘钥(rsa,公钥-私钥)相当于古代的虎符,不能从私钥推导出公钥。
效率不高(需要加密,转换慢)。
(2)什么叫签名
签名就是身份信息。
比如:使用支付宝转账时,谁转给了商家,转账的谁就是签名。
(3)什么是hash值
Hash算法是一个广义的算法,在这里做数字签名来保障数据传递的安全性,如何确保数据的安全性,通过hash值对比确定数据完整性和安全性。
(4)证书
证书格式:x509(国际标准),需要机构CA颁发。
CA:电子认证服务,证书颁发机构,是受信任的第三方,承担公钥体系中的公钥的合法性建议的责任。
首先CA先颁发ca证书,然后用证书和相关信息找CA颁发server证书、client证书,cilent证书要推送给client。
以上是关于通信安全—docker建立客户端与服务端TLS证书连接的主要内容,如果未能解决你的问题,请参考以下文章