文章目录
- TLS概述
- CA证书的作用
- CA证书的身份验证
- 来吧!展示!!
- 优化机器
- 创建CA证书
- 创建服务器证书
- 使用ca证书与私钥证书签名
- 创建客户端证书
- 将证书复制给客户端
- 客户端验证可以使用服务端的docker
TLS概述
TLS是Https的安全基础,TLS协议可用于保护正常运行于TCP之上的任何应用协议的通信。TLS协议的有点在于它是与应用层协议无关的。高层的应用协议能透明地建立于TLS协议之上。
TLS协议既用到了公钥加密技术又用到了对称加密技术,TLS地握手协议非常有效地让客户和服务端之间完成相互之间地身份认证,其主要过程如下所述:
客户端向服务器传送TLS的协议的版本号、加密算法的种类,产生的随机数、以及其他服务器和客户端之间通信的各种信息。
服务端向客户端传送TLS协议的版本号、加密算法的种类、随机数以及其他相关信息,同时服务器还将客户端传送自己的证书。
客户利用服务器传过来的信息验证服务器的合法性。如果合法性没有通过,通信将断开;弱国合法性验证通过,将继续进行4。
用户随机产生一个用于后面通信的“对称密码”,然后用服务器的公钥对其加密,然后将加密后的“预主密码”传给服务器。
如果服务器要求客户的身份认证,用户可以建立一个随机数然后对其进行数据签名,将这个含有签名的随机数和客户自己的证书以及加密过的“预主密码”一起传给服务器
服务器和客户端用相同的主密码,一个对称密钥用于TLS协议的安全数据通讯的加解密通信。同时在TLS通信过程中还要完成数据通信的完整性,防止数据通信中的各种变化。
CA证书的作用
CA证书顾名思义就是由CA(Certification Authority)机构发布的数字证书。要对CA证书完全理解及其作用,首先要理解SSL。SSL(security sockets layer,安全套接层)是为网络通信提供安全及数据完整性的一种安全协议。SSL3.0版本以后又被称为TLS。
SSL位于TCP与各应用层之间,是操作系统向外提供的API。SSL如何保证网络通信的安全和数据的完整性呢?就是采用了两种手段:身份认证和数据加密。首先身份认证就需要用到CA证书了。先了解CA证书具体包括哪些内容:
- 颁发者
- 使用者
- 版本
- 签名算法
- 签名哈希算法
- 使用者
- 公钥
- 指纹
- 指纹算法
- ……
上述中颁发者、使用者、版本等内容好理解,颁发者就是CA机构,下面会讲到。对于签名算法、签名哈希算法的理解,首先要先理解签名是什么东东?联系到实际情况,当我们向某机构提供报告时,往往在报告最后加上个人的名字,以表示该报告是我本人的。签名在网络通讯中的应用称为数字签名,当服务器向客户端发送信息时,会将报文生成报文摘要,同时对报文摘要进行hash计算,得到hash值,然后对hash值进行加密,然后将加密的hash值放置在报文后面,这个加密后的hash值就称为签名。服务器将报文、签名和数字证书一同发送给客户端。客户端收到这些信息后,会首先验证签名,利用签名算法对签名进行解密,得到报文摘要的hash值,然后将得到的报文生成报文摘要并利用签名hash算法生成新的hash值,通过对比这两个hash值是否一致,就能判断信息是否完整,是否是由真正的服务器发送的。可知签名有两个作用确认消息发送方可靠,确认消息完整准确。
上面提到了hash值的加密,我们还需要理解SSL的加密机制,在使用SSL的网络通讯过程中,消息在请求和响应中都是加密传送的。首先要知道加密算法分为两种:对称加密和非对称加密。对称加密就是发送双发使用相同的密钥对消息进行加解密,常见的对称加密为DES、3DES,AES等。非对称加密是发送双方各自拥有一对公钥私钥,其中公钥是公开的,私钥是保密的。当发送方向接收方发送消息时,发送方利用接收方的公钥对消息进行加密,接收方收到消息后,利用自己的私钥解密就能得到消息的明文。其中非对称加密方法有RSA、Elgamal、ECC等。此处只是简单了说明了这两种加密机制的过程,若要深入理解它们的原理、过程请搜索相应的资料,很容易搜索到。
CA证书的身份验证
好了,了解了签名原理和两种加密机制,我们继续理解网络通讯中是怎么利用CA证书进行身份认证的?客户端与服务端需要经过一个握手的过程才能完成身份认证,建立一个安全的连接。握手的过程如下:
- 客户端访问服务器(比如:https://www.12306.cn),发送ssl版本、客户端支持的加密算法、随机数等消息。
- 服务器向客户端发送ssl版本、随机数、加密算法、证书(证书出现了)等消息。
- 客户端收到消息后,判断证书是否可信(如何判断可信,看下文介绍),若可信,则继续通信,发送消息包括:向服务器发送一个随机数,从证书中获取服务器端的公钥,对随机数加密;编码改变通知,表示随后信息都将使用双方协定的加密方法和密钥发送;客户端握手结束通知。
- 服务器端对数据解密得到随机数,发送消息:编码改变通知,表示随后信息都将使用双方协定的加密方法和密钥发送。
以上就是整个握手的过程,在第三步实际上就完成了身份的认证,第四、五步是进行密钥的商定,因为非对称加密算法对数据加密非常慢,效率低,而对称加密加密效率很高,因此在整个握手过程要生成一个对称加密密钥,然后数据传输中使用对称加密算法对数据加密。可知ssl整个握手过程包括身份认证、密钥商定。
来吧!展示!!
实验环境:
两台 CentOS 7.6 主机,服务器IP:20.0.0.5,客户机IP:20.0.0.6
两台机器均以安装 docker
优化机器
Server设置
[root@5centos ~]# setenforce 0
[root@5centos ~]# iptables -F
[root@5centos ~]# hostnamectl set-hostname server
[root@5centos ~]# su
[root@server ~]# systemctl start docker
[root@server ~]# vim /etc/hosts
20.0.0.5 server
客户端设置
[root@localhost ~]# setenforce 0
[root@localhost ~]# iptables -F
[root@localhost ~]# hostnamectl set-hostname client
[root@localhost ~]# su
[root@client ~]# systemctl start docker
[root@client ~]# vim /etc/hosts
20.0.0.5 server
两机互ping测试
[root@client ~]# ping server
PING server (20.0.0.5) 56(84) bytes of data.
64 bytes from server (20.0.0.5): icmp_seq=1 ttl=64 time=0.710 ms
64 bytes from server (20.0.0.5): icmp_seq=2 ttl=64 time=0.413 ms
64 bytes from server (20.0.0.5): icmp_seq=3 ttl=64 time=0.408 ms
64 bytes from server (20.0.0.5): icmp_seq=4 ttl=64 time=0.381 ms
^C
--- server ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3000ms
rtt min/avg/max/mdev = 0.381/0.478/0.710/0.134 ms
创建CA证书
服务端创建ca密钥,长度为256位;产生一个pem文件,字节大小为4096,密码为123123
[root@server ~]# 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:
[root@server ~]# ls
anaconda-ks.cfg initial-setup-ks.cfg 模板 图片 下载 桌面 ##家目录里就会多一个pem文件
ca-key.pem 公共 视频 文档 音乐
基于ca密钥创建CA证书,遵从x509标准,有限时效为1000天;指定密钥;用哈希256验证;给证书起一个标题名称“/CN=*”
[root@server ~]# openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem
Enter pass phrase for ca-key.pem: ##输入刚才创建的密码 123123
[root@server ~]# ls
anaconda-ks.cfg ca.pem 公共 视频 文档 音乐
ca-key.pem initial-setup-ks.cfg 模板 图片 下载 桌面
创建服务器证书
[root@server ~]# openssl genrsa -out server-key.pem
Generating RSA private key, 2048 bit long modulus
.......................................+++
......+++
e is 65537 (0x10001)
创建私钥签名
[root@server ~]# openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr
[root@server ~]# ls
anaconda-ks.cfg ca.pem server.csr 公共 视频 文档 音乐
ca-key.pem initial-setup-ks.cfg server-key.pem 模板 图片 下载 桌面
使用ca证书与私钥证书签名
遵从x509标准,有限时效为1000天;指定密钥;用哈希256验证;借助CA证书,CA密钥,证书会由CA自动创建并输出
[root@server ~]# 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: ##123123
[root@server ~]# ls
anaconda-ks.cfg ca.srl server.csr 模板 文档 桌面
ca-key.pem initial-setup-ks.cfg server-key.pem 视频 下载
ca.pem server-cert.pem 公共 图片 音乐
创建客户端证书
客户端的密钥也是由服务端帮忙生产的
生产客户端密钥
[root@server ~]# openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
..............++
.............................................................................................................................................................................................................................................................................................................................................................++
e is 65537 (0x10001)
[root@server ~]# ls
anaconda-ks.cfg ca.srl server-cert.pem 公共 图片 音乐
ca-key.pem initial-setup-ks.cfg server.csr 模板 文档 桌面
ca.pem key.pem server-key.pem 视频 下载
客户端密钥签名,需要刚刚创建的密钥签名
[root@server ~]# openssl req -subj "/CN=client" -new -key key.pem -out client.csr
[root@server ~]# ls
anaconda-ks.cfg ca.srl key.pem server-key.pem 视频 下载
ca-key.pem client.csr server-cert.pem 公共 图片 音乐
ca.pem initial-setup-ks.cfg server.csr 模板 文档 桌面
创建配置文件,为了生产客户端证书
[root@server ~]# echo "extendedKeyUsage=clientAuth" > extfile.cnf
为了告诉服务端,服务端即将要开启TLS验证,让服务端开启TLS验证
签名证书,输入密码,(需要签名客户端,CA证书,CA密钥)
[root@server ~]# openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
[root@server ~]# ls
anaconda-ks.cfg cert.pem key.pem 公共 文档
ca-key.pem client.csr server-cert.pem 模板 下载
ca.pem extfile.cnf server.csr 视频 音乐
ca.srl initial-setup-ks.cfg server-key.pem 图片 桌面
删除多余配置文件,并修改配置文件
[root@server ~]# rm -rf ca.srl client.csr extfile.cnf server.csr
[root@server ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=/tls/ca.pem --tlscert=/tls/server-cert.pem --tlskey=/tls/server-key.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
[root@server ~]# mkdir /tls
[root@server ~]# mv *.pem /t
tls/ tmp/
[root@server ~]# mv *.pem /tls/
[root@server ~]# ls /tls
ca-key.pem ca.pem cert.pem key.pem server-cert.pem server-key.pem
[root@server ~]# systemctl daemon-reload
[root@server ~]# systemctl restart docker
[root@server ~]# netstat -ntap | grep 2376
tcp6 0 0 :::2376 :::* LISTEN 22191/dockerd
将证书复制给客户端
[root@server tls]# scp ca.pem root@20.0.0.6:/etc/docker/ ##ca文件
The authenticity of host '20.0.0.6 (20.0.0.6)' can't be established.
ECDSA key fingerprint is SHA256:2A2lZNbKvepBrXabSygRIwVfMeu4F3N6ITcpsFu2yj8.
ECDSA key fingerprint is MD5:9d:30:1f:ba:ce:01:88:88:1c:68:80:c1:c9:3d:79:83.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '20.0.0.6' (ECDSA) to the list of known hosts.
root@20.0.0.6's password:
ca.pem 100% 1765 752.5KB/s 00:00
[root@server tls]# scp cert.pem root@20.0.0.6:/etc/docker/ ##cert 文件
root@20.0.0.6's password:
cert.pem 100% 1655 790.7KB/s 00:00
[root@server tls]# scp key.pem root@20.0.0.6:/etc/docker/
root@20.0.0.6's password:
key.pem 100% 3247 1.6MB/s 00:00
客户端 查看下
[root@client ~]# cd /etc/docker/
[root@client docker]# ls
ca.pem cert.pem key.json key.pem
客户端验证可以使用服务端的docker
服务器先下载个镜像
[root@server tls]# docker pull httpd
[root@server tls]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 417af7dc28bc 11 days ago 138MB
客户机查看
[root@client docker]# docker --tlsverify --tlscacert=ca.pem --tlskey=key.pem --tlscert=cert.pem -H tcp://server:2376 images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 417af7dc28bc 11 days ago 138MB
[root@client docker]# docker --tlsverify --tlscacert ca.pem --tlskey key.pem --tlscert cert.pem -H tcp://server:2376 images ##两种格式都可
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 417af7dc28bc 11 days ago 138MB
[root@client docker]# docker --tlsverify --tlscacert ca.pem --tlskey key.pem --tlscert cert.pem -H tcp://server:2376 run -it httpd bash ##创建一个容器
root@f2cb4ecb16a9:/usr/local/apache2#
root@f2cb4ecb16a9:/usr/local/apache2#
root@f2cb4ecb16a9:/usr/local/apache2# pwd
/usr/local/apache2
服务端查看
[root@server tls]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f2cb4ecb16a9 httpd "bash" 45 seconds ago Up 44 seconds 80/tcp objective_hellman
这样将相对应的证书复制到对方节点上就可以实现客户端和服务端容器的互通,实验结束