一.TLS介绍
- TLS(Transport Layer Security Protocol):安全传输层协议
- TLS用于在两个通信应用程序之间提供保密性和数据完整性。TLS协议由TLS记录协议(TLS Record)和TLS握手协议(TLS Handshake)组成。较低的层位TLS记录协议,位于某个可靠传输协议(例如TCP上面)。
- TLS记录协议用于封装各种高层协议,作为这种封装协议之一的握手协议允许服务器与客户端在应用程序协议传输和接收其第一个数据字节之前彼此之间相互认证,协商加密算法和加密密钥。
- TLS握手协议提供的连接安全具有三个属性:
1.可以使用非对称的,或者公共密钥的密码来认证对方的身份,该认证是可选的,但是至少需要一个结点方。
2.共享解密密钥的协商是安全的,对于偷窃者来说协商加密是难以获得的,此外经过认证的连接不能获得加密,即使是进入连接中间的攻击者也不可以。
3.协商是可靠的,没有经过通信方成员的检测,任何攻击者都不可以修改通信协商。
- TLS的最大优势就在于:TLS是独立与应用协议。高层协议可以透明地分布在TLS协议上面。然后,TLS标准并没有规定应用程序如何在TLS上增加安全性;它如何启动TLS握手协议以及如何解释交换地认证证书地决定权留给协议的设计者和实施者来判断
- TLS的主要增加内容,TLS的主要目标是使SSL更安全,并是协议的规范更加精确和完善。TLS在SSL v3.0的基础上,提供了以下增加内容:
1.更加安全的MAC算法
2.更加严密的警报
3.“灰色区域”的规范更加明确
- TLS对于安全性的改进
1.对于消息认证使用密钥散列法:TLS使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络,比如internet上传送时,该代码确保记录不会被变更。SSLv3.0还提供给键控消息认证,但是HMAC比SSLv3.0使用(消息认证代码)MAC功能更加安全。
2.增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。
3.改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。
4.一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。
5.特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。
二.在docker中搭建TLS加密
- 在公司的docker业务中,一般为了防止链路劫持、会话劫持等问题导致docker通信时被中间人攻击,c/s两端应该通过加密方式通讯。
环境分析
角色 | IP地址 | 软件包 |
master(docker服务端) | 192.168.43.101/24 | docker-ce |
client(docker客户端) | 192.168.43.102/24 | docker-ce |
具体操作(master上操作)
- 环境部署
##默认安装好docker-ce,关闭防火墙
[root@192 ~]# hostnamectl set-hostname master
[root@192 ~]# su
[root@master ~]# vi /etc/hosts
[root@master ~]# cat /etc/hosts
127.0.0.1 master
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
[root@master ~]# ping master
PING master (127.0.0.1) 56(84) bytes of data.
64 bytes from master (127.0.0.1): icmp_seq=1 ttl=64 time=0.049 ms
64 bytes from master (127.0.0.1): icmp_seq=2 ttl=64 time=0.154 ms
^C
--- master ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.049/0.101/0.154/0.053 ms
[root@master ~]#
- 创建ca密码
[root@master ~]# mkdir /root/tls
[root@master ~]# cd /root/tls/
[root@master tls]# 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: #输入密码123123
Verifying - Enter pass phrase for ca-key.pem: #输入密码123123
[root@master tls]# ls
ca-key.pem
[root@master tls]#
- 创建ca证书
[root@master tls]# ls
ca-key.pem
[root@master tls]# openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
Enter pass phrase for ca-key.pem:
[root@master tls]# ls
ca-key.pem ca.pem
[root@master tls]#
- 创建服务器私钥
ca-key.pem ca.pem
[root@master tls]# openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
......................++
...........................................................................................................................................++
e is 65537 (0x10001)
[root@master tls]# ls
ca-key.pem ca.pem server-key.pem
[root@master tls]#
- 创建签名私钥
[root@master tls]# ls
ca-key.pem ca.pem server-key.pem
[root@master tls]# openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
[root@master tls]# ls
ca-key.pem ca.pem server.csr server-key.pem
[root@master tls]#
- 使用ca证书和签名私钥,创建server-cert.pem
[root@master tls]# ls
ca-key.pem ca.pem server.csr server-key.pem
[root@master tls]# openssl x509 -req -days 1000 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem
Signature ok
subject=/CN=*
Getting CA Private Key
Enter pass phrase for ca-key.pem:
[root@master tls]# ls
ca-key.pem ca.pem ca.srl server-cert.pem server.csr server-key.pem
[root@master tls]#
- 生成客户端密钥
[root@master tls]# ls
ca-key.pem ca.pem ca.srl server-cert.pem server.csr server-key.pem
[root@master tls]# openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
...........++
............................................++
e is 65537 (0x10001)
[root@master tls]# ls
ca-key.pem ca.pem ca.srl key.pem server-cert.pem server.csr server-key.pem
[root@master tls]#
- 生成客户端签名
[root@master tls]# ls
ca-key.pem ca.pem ca.srl key.pem server-cert.pem server.csr server-key.pem
[root@master tls]# openssl req -subj "/CN=client" -new -key key.pem -out client.csr
[root@master tls]# ls
ca-key.pem ca.pem ca.srl client.csr key.pem server-cert.pem server.csr server-key.pem
[root@master tls]#
- 创建配置文件
[root@master tls]# echo extendedKeyUsage=clientAuth > extfile.cnf
[root@master tls]# ls
ca-key.pem ca.pem ca.srl client.csr extfile.cnf key.pem server-cert.pem server.csr server-key.pem
[root@master tls]#
- 创建签名证书
[root@master tls]# openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
[root@master tls]# ls
ca-key.pem ca.pem ca.srl cert.pem client.csr extfile.cnf key.pem server-cert.pem server.csr server-key.pem
[root@master tls]#
- 修改docker的配置文件,并且重启服务
[root@master tls]# vi /usr/lib/systemd/system/docker.service
[root@master tls]# cat /usr/lib/systemd/system/docker.service | grep 'ExecStart'
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/root/tls/ca.pem --tlscert=/root/tls/server-cert.pem --tlskey=/root/tls/server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
[root@master tls]# systemctl daemon-reload
[root@master tls]# systemctl restart docker
[root@master tls]#
- 将(ca.pem)ca证书,(cert.pem)签名证书,(key.pem)客户端密钥复制到client的/etc/docker目录下
scp ca.pem root@192.168.43.102:/etc/docker/
scp cert.pem root@192.168.43.102:/etc/docker/
scp key.pem root@192.168.43.102:/etc/docker/
- 在client上设置基本环境,且验证TLS
hostnamectl set-hostname client
su
vi /etc/hosts
192.168.43.101 master
[root@client ~]# cd /etc/docker/
[root@client docker]# ls
ca.pem cert.pem daemon.json key.json key.pem
[root@client docker]#
[root@client ~]# cd /etc/docker/ ##需要进入/etc/docker这个目录才可以执行下列命令
[root@client docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://master:2376 version
Client: Docker Engine - Community
Version: 19.03.8
API version: 1.40
Go version: go1.12.17
Git commit: afacb8b
Built: Wed Mar 11 01:27:04 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.8
API version: 1.40 (minimum version 1.12)
Go version: go1.12.17
Git commit: afacb8b
Built: Wed Mar 11 01:25:42 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.13
GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
[root@client docker]#
通过在服务端上创建tls密钥证书,在下发给客户端,客户端通过私钥访问容器,这样就保证的docker通讯的安全性