MENU

使用强加密/TLS交换部署远程Docker

December 14, 2019 • 小技巧,Network

无奈垃圾学校领导不给服务器,只好用LSHIY的服务器部署Docker环境.

首先在Ubuntu上安装Docker,这个步骤就不再详细叙述.

我是Ubuntu16.04,所以我使用以下步骤,来自Docker官网
移除旧依赖

sudo apt-get remove docker docker-engine docker.io containerd runc

添加基本依赖并导入依赖源:

sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88

添加Docker源

    sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

安装Docker

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Linux服务器上建一个目录,进入此目录,我使用的是/root/ssl
创建根证书RSA私钥:

openssl genrsa -aes256 -out ca-key.pem 4096

页面提示Enter pass phrase for ca-key.pem,
此时输入秘钥的密码,回车后会要求再输入一次,两次密码一致就会在当前目录生成CA秘钥文件ca-key.pem;
以此秘钥创建CA证书,自己给自己签发证书,自己就是CA机构,也可以交给第三方机构去签发

openssl req -new -x509 -days 1000 -key ca-key.pem -sha256 -subj "/CN=*" -out ca.pem

此时生成的ca.pem文件就是CA证书;

创建服务端私钥

openssl genrsa -out server-key.pem 4096

此时生成的server-key.pem文件就是服务端私钥;

生成服务端证书签名请求(csr即certificate signing request,里面包含公钥与服务端信息)

openssl req -subj "/CN=*" -sha256 -new -key server-key.pem -out server.csr

此时生成的server.csr文件就是服务端证书;

生成签名过的服务端证书(期间会要求输入密码)

openssl x509 -req -days 1000 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

此时生成的server-cert.pem文件就是已盖章生效的服务端证书;

生成客户私钥:

openssl genrsa -out key.pem 4096

此时生成的key.pem文件就是客户私钥;

生成客户端证书签名请求:

openssl req -subj "/CN=client" -new -key key.pem -out client.csr

此时生成的client.csr文件就是客户端证书签名请求;

生成名为extfile.cnf的配置文件

echo extendedKeyUsage=clientAuth > extfile.cnf

生成签名过的客户端证书(期间会要求输入密码)

openssl x509 -req -days 1000 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf

将多余的文件删除:

rm -rf ca.srl client.csr extfile.cnf server.csr

此时还剩以下文件:

文件名作用
ca.pemCA机构证书
ca-key.pem根证书RSA私钥
cert.pem客户端证书
key.pem客户私钥
server-cert.pem服务端证书
server-key.pem服务端私钥

至此,所有证书文件制作完成,接下来对Docker做TLS安全配置;


Docker Server TLS的配置

打开文件/lib/systemd/system/docker.service,找到下图的内容

更改如下配置

ExecStart=/usr/bin/dockerd --tlsverify --tlscacert=/root/ssl/ca.pem --tlscert=/root/ssl/server-cert.pem --tlskey=/root/ssl/server-key.pem -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:23751

加载上述配置,再重启docker服务

systemctl daemon-reload && systemctl restart docker

配置完成,接下来进行客户端Client的配置

导出密钥

scp /root/work/ca.pem root@192.168.121.132:/root/work \
&& scp /root/work/cert.pem root@192.168.121.132:/root/work \
&& scp /root/work/key.pem root@192.168.121.132:/root/work

在制作证书时没有允许通过IP访问服务端,所以客户端在连接主机的Docker时不能直接用主机的IP,所以要用host来访问主机,给客户端电脑增加一个host配置

主机IP docker-daemon

使用Docker验证

docker --tlsverify --tlscacert=/Users/evsio0n/ssl/ca.pem --tlscert=/Users/evsio0n/ssl/cert.pem --tlskey=/Users/evsio0n/ssl/key.pem -H tcp://docker-deamon:23751 version

Terminal显示以下信息:

Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea
 Built:             Wed Nov 13 07:22:34 2019
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea838
  Built:            Wed Nov 13 07:48:43 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

连接成功,收工!

一个错误需要注意

error during connect: Get https://docker.local:23751/v1.40/version: x509: certificate is valid for *, not docker.local

这个是因为ssl仅支持单名称加密,(*)的这种格式.把hosts改成单名称即可.