整体思路
- 远程服务器上运行 Docker API,通过
2376
端口对外暴露,并开启 TLS 双向认证。 - 服务端证书绑定 远程服务器 IP 或域名。
- 客户端证书仅用于认证,不绑定 IP,所以客户端 IP 可变。
- 推荐使用 域名(固定或动态 DNS),防止 IP 变动导致证书不匹配。
1.在远程服务器生成证书
生成:
- CA 证书:用于签发服务端和客户端证书
- 服务端证书:给 Docker Daemon
- 客户端证书:给你的本地电脑
1.1 创建证书目录
1 | mkdir -p /etc/docker/certs |
1.2 生成 CA
1 | # 生成 CA 私钥(输入密码) |
Common Name
可以填My Docker CA
。
1.3 生成服务端证书
关键点:SAN 必须包含 服务器的公网 IP 或域名(推荐域名)。
1 | # 服务端私钥 |
1.4 生成客户端证书
1 | # 客户端私钥 |
最终文件分布
服务端:
/etc/docker/certs/ca.pem
/etc/docker/certs/server-cert.pem
/etc/docker/certs/server-key.pem
客户端:
ca.pem
、cert.pem
、key.pem
2.配置 Docker Daemon
编辑 /usr/lib/systemd/system/docker.service
:
1 | ExecStart=/usr/bin/dockerd \ |
重启 Docker:
1 | systemctl daemon-reload |
确认 Docker 在 5489
端口监听:
1 | netstat -tulnp | grep 5489 |
3.客户端配置(本地电脑)
把这三个文件复制到本地,例如 ~/.docker/certs/
:
ca.pem
cert.pem
key.pem
设置环境变量:
1 | DOCKER_HOST=tcp://192.168.1.100:5489 |
测试连接:
1 | docker info |
或者显式指定:
1 | docker --tlsverify \ |
注意事项
防火墙要放行 2376 端口
1
ufw allow 5489/tcp
限制来源 IP(安全)
1
ufw allow from <你的本地 IP>/32 to any port 2376 proto tcp
客户端 IP 可变没关系,因为客户端证书不绑定 IP。
TLS 原理
Docker 远程 API 默认是 HTTP,如果直接暴露 TCP 端口,没有认证和加密,任何能访问这个端口的人都可以 完全控制 Docker,相当于 root 权限。
TLS(Transport Layer Security)在 Docker 中的作用:
加密通信
- 客户端和服务端之间的数据通过 TLS 加密,防止中间人监听。
- 即使在公共网络,也不会泄露镜像名、命令或敏感信息。
身份验证(认证)
- 服务端验证客户端证书:通过
--tlsverify
,服务端只允许受信任的客户端连接。 - 客户端验证服务端证书:客户端验证服务器证书,防止连接到伪造的 Docker 服务。
- 服务端验证客户端证书:通过
完整性保护
- TLS 可以保证数据在传输过程中未被篡改。
Docker TLS 的实现方式
服务端:
dockerd --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem
- 开启 TLS,同时指定 CA 证书和服务端证书/私钥。
客户端:
- 使用 CA 签发的客户端证书:
cert.pem
+key.pem
- 客户端通过 TLS 连接到服务端时,服务端会验证客户端证书,拒绝未授权访问。
- 使用 CA 签发的客户端证书:
安全性分析
优点
通信加密:防止数据被截获
身份验证:保证只有持有客户端证书的人可以访问 Docker API
防中间人攻击:客户端验证服务端证书
操作安全:不像直接暴露 HTTP 那样任何人都可以控制 Docker
限制/风险
- 证书泄露
- 如果 CA 或客户端证书/私钥泄露,攻击者可以直接访问 Docker
- 端口暴露
- TCP 端口暴露在公网也可能被扫描,建议配合防火墙或 VPN 使用
- 配置错误
- TLS 证书路径错误或使用服务端证书当客户端证书,会导致连接失败或安全缺失
最佳实践:
1. 使用独立 CA 签发客户端证书
2. 不在公网暴露 Docker TCP 端口,建议 VPN/内网访问
3. 定期更新证书、不要共享私钥