本文目录导读:

- 核心目标
- 第一步:生成证书颁发机构(CA)和密钥
- 第二步:生成服务端证书(用于配置 Docker 守护进程)
- 第三步:生成客户端证书(用于 Docker 客户端连接)
- 第四步:配置 Docker 守护进程启用 TLS
- 第五步:配置客户端连接(以另一台机器为例)
- 安全强化建议(可选但推荐)
- 常见问题排查
开启 Docker API 的 TLS 认证主要分为两个步骤:生成证书和配置 Docker 守护进程,以下是基于 Linux (Ubuntu/CentOS) 环境的详细操作指南。
核心目标
让 Docker 守护进程只接受经过客户端证书验证的 HTTPS 连接,防止未授权访问。
第一步:生成证书颁发机构(CA)和密钥
在 Docker 宿主机 上操作。
# 1. 创建存放证书的目录 mkdir -p /etc/docker/certs && cd /etc/docker/certs # 2. 生成 CA 私钥(有效期 10 年) openssl genrsa -aes256 -out ca-key.pem 4096 # 注意:会提示输入密码,请记住该密码。 # 3. 生成 CA 公钥(证书) openssl req -new -x509 -days 3650 -key ca-key.pem -sha256 -out ca.pem # 按提示填写信息,Common Name 可填主机名或 IP
第二步:生成服务端证书(用于配置 Docker 守护进程)
# 1. 生成服务端私钥 openssl genrsa -out server-key.pem 4096 # 2. 生成证书签名请求 (CSR) openssl req -subj "/CN=<你的宿主机IP或域名>" -sha256 -new -key server-key.pem -out server.csr # 3. 创建 extfile.cnf(指定允许连接的 IP 或域名) echo subjectAltName = DNS:your-domain.com,IP:你的宿主机IP,IP:127.0.0.1 > extfile.cnf # echo subjectAltName = DNS:docker.example.com,IP:192.168.1.100,IP:127.0.0.1 > extfile.cnf # 4. 使用 CA 签署服务端证书 openssl x509 -req -days 3650 -in server.csr -CA ca.pem -CAkey ca-key.pem \ -CAcreateserial -out server-cert.pem -extfile extfile.cnf
第三步:生成客户端证书(用于 Docker 客户端连接)
# 1. 生成客户端私钥 openssl genrsa -out key.pem 4096 # 2. 生成客户端 CSR openssl req -subj '/CN=client' -new -key key.pem -out client.csr # 3. 创建 extfile 用于客户端认证(使用 extended key usage) echo extendedKeyUsage = clientAuth > extfile-client.cnf # 4. 签署客户端证书 openssl x509 -req -days 3650 -in client.csr -CA ca.pem -CAkey ca-key.pem \ -CAcreateserial -out cert.pem -extfile extfile-client.cnf
完成后,清理无用文件:
rm -v client.csr server.csr extfile.cnf extfile-client.cnf
第四步:配置 Docker 守护进程启用 TLS
-
编辑 Docker 配置文件
/etc/docker/daemon.json:{ "tlsverify": true, "tlscacert": "/etc/docker/certs/ca.pem", "tlscert": "/etc/docker/certs/server-cert.pem", "tlskey": "/etc/docker/certs/server-key.pem", "hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"] }- 端口
2376是默认 TLS 端口(非 TLS 默认是2375)。 hosts允许同时监听 TCP 和本地 Socket。
- 端口
-
重启 Docker 服务:
systemctl daemon-reload systemctl restart docker
-
验证服务端状态:
netstat -tulpn | grep 2376 # 应显示 listen 状态
第五步:配置客户端连接(以另一台机器为例)
将客户端所需文件复制到客户端机器:
# 在宿主机打包三个文件 scp ca.pem cert.pem key.pem user@client-ip:~/
在客户端测试连接(必须指定证书):
docker --tlsverify \ --tlscacert=ca.pem \ --tlscert=cert.pem \ --tlskey=key.pem \ -H=宿主机IP:2376 version
若使用环境变量简化:
export DOCKER_HOST=tcp://宿主机IP:2376 export DOCKER_TLS_VERIFY=1 export DOCKER_CERT_PATH=/path/to/certs docker version
安全强化建议(可选但推荐)
-
使用自定义 uid/gid 保护证书:
chown -R root:docker /etc/docker/certs chmod 0600 /etc/docker/certs/server-key.pem /etc/docker/certs/ca-key.pem chmod 0444 /etc/docker/certs/*.pem
-
限制绑定地址:将
0.0.0改为特定 IP(如内网IP),避免暴露到公网。 -
避免使用
tcp://0.0.0.0,除非你真的需要从任意网络访问。
常见问题排查
| 问题 | 解决 |
|---|---|
连接报错 bad certificate |
检查客户端 cert.pem 是否与当前连接的服务端 CA 匹配 |
服务端无法启动,日志显示 permission denied |
检查 server-key.pem 权限(应改为 0600) |
客户端连接报 unauthorized |
确认客户端证书的 extendedKeyUsage 包含了 clientAuth |
| 证书过期 | 重新运行生成步骤,并重启 Docker |
通过以上步骤,你的 Docker API 就开启了双向 TLS 认证,只有持有合法客户端证书的机器才能访问 Docker 守护进程的 TCP 端口。