通信安全—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

三、签署证书

为服务端创建并签署证书:

  1. ~/certs/server/key.pem
  2. ~/certs/server/cert.csr
  3. ~/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

为客户端创建并签署证书:

  1. ~/certs/client/key.pem
  2. ~/certs/client/cert.csr
  3. ~/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

扩展二:原理说明

对称和非对称秘钥双重加密的流程图

大概流程

  1. 先对明文—>对称加密—>形成密文和对称秘钥
  2. 然后将对称秘钥+签名—>非对称加密(私钥加密)—>形成加密的秘钥
  3. 使用hash算法算出hash值
  4. 最后将密文、加密的秘钥、hash值传给对方
  5. 对方收到这三样数据
  6. 对加密的秘钥—>非对称解密(公钥解密)—>解密出对称秘钥和签名(签名用于身份认证)
  7. 使用对称秘钥—>对称解密—>解密出明文
  8. 对明文使用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证书连接的主要内容,如果未能解决你的问题,请参考以下文章

centos8.5 配置vsftpd的SSL/TLS功能

如何忽略服务器上的TLS证书

SSL证书签发

go and https

golang https server分析

配置 vsftpd 使用 SSL 证书加密数据传输