【Docker】对Docker Remote Api 进行认证
将虚拟机配置docker
docker的安装,我在我的博客里有写,这里就不写了。
第一步
1 2 3
| cd /etc/docker echo 01 | sudo tee ca.srl sudo openssl genrsa -des3 -out ca-key.pem
|
第二步
创建私钥的过程中,我们需要为CA密钥设置一个密码,我们需要牢记这个密码,并确保它的安全性。在新CA中,我们需要用这个密码来创建并对证书签名。
1
| sudo openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem
|
第三步
注意这里Common Name (e.g. server FQDN or YOUR name) []:docker.example.com,这里填写你的服务器的域名或者IP地址。(其他的跳过就好了)
1
| sudo openssl genrsa -des3 -out server-key.pem
|
这将为我们的服务器创建一个密钥server-key.pem。像前面一样,我们要确保此密钥的安全性,这是保证我们的Docker服务器安全的基础。
第四步
1
| sudo openssl req -new -key server-key.pem -out server.csr
|
第五步
这将创建一个名为server.csr的文件。这也是一个请求,这个请求将为创建我们的服务器证书进行签名。在这些选项中最重要的是Common Name或CN。该项的值要么为Docker服务器(即从DNS中解析后得到的结果,比如docker.example.com)的FQDN(fully qualified domain name,完全限定的域名)形式,要么为*,这将允许在任何服务器上使用该服务器证书。
我直接输入了虚拟机的ip 192.168.73.123
1 2
| sudo openssl x509 -req -days 365 -in server.csr -CA ca.pem \ -CAkey ca-key.pem -out server-cert.pem
|
第六步
需要输入CA密钥文件的密码,该命令会生成一个名为server-cert.pem的文件,这个文件就是我们的服务器证书
1
| sudo openssl rsa -in server-key.pem -out server-key.pem
|
第七步
1 2
| sudo chmod 0600 /etc/docker/server-key.pem /etc/docker/server-cert.pem \ /etc/docker/ca-key.pem /etc/docker/ca.pem
|
第八步
需要编辑/usr/lib/systemd/system/docker.service
1
| vim /usr/lib/systemd/system/docker.service
|
1 2 3
| ExecStart=/usr/bin/docker -d -H tcp://0.0.0.0:2376 --tlsverify --tlscacert=/etc/docker/ca.pem --tlscert=/etc/docker/server-cert.pem --tlskey=/etc/docker/server-key.pem
|
第九步
1
| sudo systemctl --system daemon-reload
|
第十步
1
| sudo openssl genrsa -des3 -out client-key.pem
|
第十一步
创建一个名为client-key.pem的密钥文件。我们同样需要在创建阶段设置一个临时性的密码。
1
| sudo openssl req -new -key client-key.pem -out client.csr
|
第十二步
1
| echo extendedKeyUsage = clientAuth > extfile.cnf
|
第十三步
1 2
| sudo openssl x509 -req -days 365 -in client.csr -CA ca.pem \ -CAkey ca-key.pem -out client-cert.pem -extfile extfile.cnf
|
第十四步
1
| sudo openssl rsa -in client-key.pem -out client-key.pem
|
第十五步
1 2 3 4 5
| mkdir -p ~/.docker/ cp ca.pem ~/.docker/ca.pem cp client-key.pem ~/.docker/key.pem cp client-cert.pem ~/.docker/cert.pem chmod 0600 ~/.docker/key.pem ~/.docker/cert.pem
|
第十六步
1
| sudo docker -H=192.168.73.123:2376 --tlsverify info
|
Shell脚本自动化
要注意:这里的环境是虚拟机的环境,生产环境需要替换ip为自己服务器的公网ip和域名
下面我写了一个shell脚本进行自动化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #!/bin/bash set -e if [ -z $1 ];then echo "请输入Docker服务器主机名" exit 0 fi HOST=$1 mkdir -p /opt/cert/docker cd /opt/cert/docker openssl genrsa -aes256 -out ca-key.pem 4096 openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem openssl genrsa -out server-key.pem 4096 openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr # 配置白名单,推荐配置0.0.0.0,允许所有IP连接但只有证书才可以连接成功 echo subjectAltName = DNS:$HOST,IP:0.0.0.0 > extfile.cnf openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem -extfile extfile.cnf openssl genrsa -out key.pem 4096 openssl req -subj '/CN=client' -new -key key.pem -out client.csr echo extendedKeyUsage = clientAuth > extfile.cnf openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf rm -v client.csr server.csr chmod -v 0400 ca-key.pem key.pem server-key.pem chmod -v 0444 ca.pem server-cert.pem cert.pem
|
保存为createcert.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #!/bin/bash
# 检查参数 if [ -z "$1" ]; then echo "Usage: $0 <hostname>" exit 1 fi
HOSTNAME=$1
# 定义一个错误处理函数 rollback() { echo "An error occurred. Rolling back changes..." if [ -f /usr/lib/systemd/system/docker.service.old ]; then cp /usr/lib/systemd/system/docker.service.old /usr/lib/systemd/system/docker.service systemctl daemon-reload systemctl restart docker fi exit 1 }
# 捕捉错误信号并调用 rollback 函数 trap rollback ERR
chmod +x /opt/sh/createcert.sh # 运行证书生成脚本 sh /opt/sh/createcert.sh $HOSTNAME || rollback
# 备份原始 docker.service 文件 cp /usr/lib/systemd/system/docker.service /usr/lib/systemd/system/docker.service.old || rollback
# 使用 sed 命令在 ExecStart 属性后追加参数 sed -i '/ExecStart=/ s|$| --tlsverify --tlscacert=/opt/cert/docker/ca.pem --tlscert=/opt/cert/docker/server-cert.pem --tlskey=/opt/cert/docker/server-key.pem -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock|' /usr/lib/systemd/system/docker.service || rollback
# 重新加载 systemd 配置并重启 Docker 服务 systemctl daemon-reload || rollback systemctl restart docker || rollback
# 更新 /etc/hosts 文件 if ! grep -q "$HOSTNAME" /etc/hosts; then echo "127.0.0.1 $HOSTNAME" >> /etc/hosts || rollback fi
# 测试 ping 和 curl 命令 ping -c 4 $HOSTNAME || rollback curl https://$HOSTNAME:2376/info --cert /opt/cert/docker/cert.pem --key /opt/cert/docker/key.pem --cacert /opt/cert/docker/ca.pem || rollback
echo "Script executed successfully."
|
上面的保存为complete-remote-protect-tls.sh
执行以下命令即可
1 2
| chmod +x complete-remote-protect-tls.sh ./complete-remote-protect-tls.sh <your-host-name>
|
最后显示成这样就成功了。
总结
tm这个折磨我一天了,网上的资料比较少,只能自己摸索。每次输入时都要重新复制粘贴,烦死了。所以我最后搞成自动化脚本一劳永逸。还好最后有发现一个大佬写的脚本启发了我,感谢大佬。👍👍
后记
我配了之后,能用了很久。但是有一天,我恢复虚拟机的快照,忽然发现连接不上了,像下图这样:
timeout 老问题了,我之前配docker的mysql的时候也遇到过,还以为是mysql配置出现了问题,然后一直在改配置。后来我才发现,虚拟机重启就能解决的了。但这次docker的重启了还是没用。折磨了一个晚上,终于在第二天发现,我虚拟机的防火墙没关。。。真是无语死了😢
参考资料