The basic concept of TLS
TLS (Transport Layer Security), TLS is a protocol built on the TCP protocol of the transmission layer, serving the application Layer. Its predecessor is SSL (Secure Socket Layer), which realizes the function of encrypting the message of the application layer and then delivering it to TCP for transmission.
TLS protocol has three characteristics: confidentiality (data is encrypted transmission, preventing third-party sniffing), data integrity (based on MAC verification mechanism), two-way authentication support (to avoid identity being impersonated)
In Docker, TLS encryption is established to prevent link hijacking, session hijacking and other problems from causing Docker communication to be conducted by an intermediary. Both ends of c/s should communicate through encryption.
Diagram TLS establishment process
Process diagram of TLS C/S connection establishment (complete i.e. bidirectional verification process)
In general, it is sending hello packets, client sending authentication and request authentication, corresponding response authentication, then corresponding negotiation verification, generating information, and finally both sides start to prepare encrypted communication. Both sides use client key to encrypt the communication content through symmetric encryption algorithm, and then conduct two-way communication. With the end of communication, either side can disconnect the ssl connection information.
Deployment configuration process
Basic environment required
Two servers, one server and one client, are deployed and installed with docker CE
Configuration process
1. Preparation: on the server node
#Create working directory folder [root@localhost ~]# mkdir /tls [root@localhost ~]# cd /tls/ #Set host name [root@localhost tls]# hostnamectl set-hostname server [root@localhost tls]# su [root@server tls]# vim /etc/hosts 127.0.0.1 server ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 #Conduct the test [root@server tls]# ping server PING server (127.0.0.1) 56(84) bytes of data. 64 bytes from server (127.0.0.1): icmp_seq=1 ttl=64 time=0.033 ms 64 bytes from server (127.0.0.1): icmp_seq=2 ttl=64 time=0.029 ms 64 bytes from server (127.0.0.1): icmp_seq=3 ttl=64 time=0.031 ms 64 bytes from server (127.0.0.1): icmp_seq=4 ttl=64 time=0.084 ms ^C --- server ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3012ms rtt min/avg/max/mdev = 0.029/0.044/0.084/0.023 ms
2. Create ca key certificate and ca certificate
#Create ca key certificate [root@server tls]# openssl genrsa -aes256 -out ca-key.pem 4096 Generating RSA private key, 4096 bit long modulus ...........................................................................++ .................................++ e is 65537 (0x10001) #You need to set your own password Enter pass phrase for ca-key.pem: Verifying - Enter pass phrase for ca-key.pem: #Create ca certificate [root@server tls]# openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem #Now you need to enter the password you just set interactively Enter pass phrase for ca-key.pem:
3. Server private key certificate and generate signing private key
#Create server private key certificate [root@server tls]# openssl genrsa -out server-key.pem 4096 Generating RSA private key, 4096 bit long modulus ...........................................++ ...........................................................................................++ e is 65537 (0x10001) #Using the ca certificate created above and the server private key to generate the signature private key [root@server tls]# openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr#Sign with the ca certificate and private key created above #View the corresponding certificate [root@server tls]# ls ca-key.pem ca.pem server.csr server-key.pem #Sign [root@server 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 #Input password Enter pass phrase for ca-key.pem: [root@server tls]# ls ca-key.pem ca.pem ca.srl server-cert.pem server.csr server-key.pem
4. Generate client key and sign client
#Generate client key [root@server tls]# openssl genrsa -out key.pem 4096 Generating RSA private key, 4096 bit long modulus .........................................................................................................++ ...............................................++ e is 65537 (0x10001) #Sign client [root@server tls]# openssl req -subj "/CN=client" -new -key key.pem -out client.csr
5. Create a profile to enhance the key
#Enhanced key file creation [root@server tls]# echo extendedKeyUsage=clientAuth > extfile.cnf #Signing certificate [root@server 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:
6. Remove redundant files and set up the docker service
[root@server tls]# rm -rf ca.srl client.csr extfile.cnf server.csr [root@server tls]# vim /lib/systemd/system/docker.service //Save and exit after modifying the lower 14 lines (quasi start mode setting) 14 ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/tls/ca.pem --tlscert=/tls/server-cert.pem --tlskey=/tls/server-ke y.pem -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
7. Reload service and restart docker
[root@server tls]# systemctl daemon-reload [root@server tls]# systemctl restart docker.service
8. Copy / TLS / ca.pem/tls/cert.pem/tls/key.pem to the client host
[root@server tls]# ls ca-key.pem ca.pem cert.pem key.pem server-cert.pem server-key.pem [root@server tls]# scp ca.pem cert.pem key.pem root@192.168.0.136:/etc/docker root@192.168.0.136's password: ca.pem 100% 1765 894.4KB/s 00:00 cert.pem 100% 1696 1.7MB/s 00:00 key.pem 100% 3243 2.6MB/s 00:00
client settings
1. Check whether the three files copied remotely exist
[root@localhost ~]# ls /etc/docker/ ca.pem cert.pem daemon.json key.json key.pem
2. Environment installation and setup host name and hosts file
[root@localhost ~]# systemctl status docker.service ● docker.service - Docker Application Container Engine Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled) Active: active (running) since IV. 2020-04-30 09:31:18 CST; 3min 20s ago Docs: https://docs.docker.com [root@localhost ~]# hostnamectl set-hostname client [root@localhost ~]# su [root@client ~]# vim /etc/hosts [root@client ~]# cat /etc/hosts 192.168.0.135 server [root@client ~]# ping server PING server (192.168.0.135) 56(84) bytes of data. 64 bytes from server (192.168.0.135): icmp_seq=1 ttl=64 time=0.444 ms 64 bytes from server (192.168.0.135): icmp_seq=2 ttl=64 time=0.345 ms 64 bytes from server (192.168.0.135): icmp_seq=3 ttl=64 time=1.09 ms ^C --- server ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2002ms rtt min/avg/max/mdev = 0.345/0.628/1.096/0.333 ms
3. Enter the / etc/docker directory to view the docker version on the server side for verification
[root@client docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://server: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 #Above is the client, below is the server 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
After TLS encryption communication and configuration of the above docker container is completed, a simple test is carried out below
Final test
Pull an image on the server side and view it on the client side
#Pull a nginx image [root@server tls]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx 54fec2fa59d0: Pull complete 4ede6f09aefe: Pull complete f9dc69acb465: Pull complete Digest: sha256:86ae264c3f4acb99b2dee4d0098c40cb8c46dcf9e1148f05d3a51c4df6758c12 Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest [root@server tls]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 602e111c06b6 Less than a second ago 127MB #View image on client [root@client docker]# docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem -H tcp://server:2376 images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 602e111c06b6 6 days ago 127MB
The test is correct (just look at the image ID), thank you for reading!