Docker API如何开启TLS认证

wen 网络安全 2

本文目录导读:

Docker API如何开启TLS认证

  1. 核心目标
  2. 第一步:生成证书颁发机构(CA)和密钥
  3. 第二步:生成服务端证书(用于配置 Docker 守护进程)
  4. 第三步:生成客户端证书(用于 Docker 客户端连接)
  5. 第四步:配置 Docker 守护进程启用 TLS
  6. 第五步:配置客户端连接(以另一台机器为例)
  7. 安全强化建议(可选但推荐)
  8. 常见问题排查

开启 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

  1. 编辑 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。
  2. 重启 Docker 服务

    systemctl daemon-reload
    systemctl restart docker
  3. 验证服务端状态

    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

安全强化建议(可选但推荐)

  1. 使用自定义 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
  2. 限制绑定地址:将 0.0.0 改为特定 IP(如 内网IP),避免暴露到公网。

  3. 避免使用 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 端口。

抱歉,评论功能暂时关闭!