为 Docker 配置 TLS

引言

Docker 默认通过 Unix Socket 对外提供接口,也支持 HTTP 的方式,后者允许我们能够在本地控制远程服务器中的 Docker。如果你想让远程服务器中的 Docker 以安全的方式被访问,可为其配置 TLS,做到服务端和客户端的双向验证。本文由我的同事 @like 投稿,其中总结了他在配置 Docker TLS 过程中的实践经验。更多相关文章和其他文章均收录于贝贝猫的文章目录

安装 cfssl

这里我们使用 CloudFlare 的 PKI 工具集 cfssl 来创建证书。

安装 cfsslcfssljson 以及 cfssl-certinfo(假设已有GoLang环境):

go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson
go get -u github.com/cloudflare/cfssl/cmd/cfssl-certinfo

另外也可以直接下载二进制包:

curl -o cfssl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64

该网站上的 cfssl 好久没更新啦,建议通过 GO 方式安装。

创建证书

根证书(CA)

首先我们需要创建一个 CA 证书,后续利用它去生成其他证书。

配置文件
cat > ca-config.json << EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "docker": {
        "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ],
        "expiry": "87600h"
      }
    }
  }
}
EOF
  • profiles: 可以定义多个 profile,分别指定不同的过期时间、使用场景等参数,在签名证书时使用某个 profile;
  • server auth: 服务端证书,表示 client 可以用该 CA 对 server 提供的证书进行验证;
  • client auth: 客户端证书,表示 server 可以用该 CA 对 client 提供的证书进行验证
生成根证书

证书请求文件(CSR):

cat > ca-csr.json << EOF
{
  "CN": "LiKe Personal CA",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "LiaoNing",
      "L": "DaLian",
      "O": "My Org",
      "OU": "My Org Unit"
    }
  ],
  "ca": {
    "expiry": "87600h"
 }
}
EOF

生成根证书和私钥:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

得到:

ca-key.pem
ca.pem

服务端证书

CSR 配置:

cat > server-csr.json << EOF
{
  "CN": "Docker Server",
  "hosts": [
    "127.0.0.1",
    "x.x.x.x",
    "my.docker.server",
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "LiaoNing",
      "L": "DaLian",
      "O": "My Org",
      "OU": "My Org Unit"
    }
  ]
}
EOF
  • CN: Common Name,通常为域名或服务器的 FQDN(完全限定域名)
  • hosts: 如果该证书能被多域名使用,可在这里添加 DNSIP

生成服务端证书和私钥:

cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile docker server-csr.json | cfssljson -bare server

得到:

server-key.pem
server.pem

客户端证书

客户端证书的配置中除了没有 hosts 字段,其他与生成服务端证书一样。

cat > client-csr.json << EOF
{
  "CN": "Docker Client",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "LiaoNing",
      "L": "DaLian",
      "O": "My Org",
      "OU": "My Org Unit"
    }
  ]
}
EOF

生成客户端证书和私钥:

cfssl gencert -ca ca.pem -ca-key ca-key.pem -config ca-config.json -profile docker client-csr.json | cfssljson -bare client

得到:

client-key.pem
client.pem

最后为了保护 key 文件,需要移除其写权限,并保证只有自己可读:

chmod -v 0400 ca-key.pem server-key.pem client-key.pem

另外证书是任何人都可以访问的:

chmod -v 0444 ca.pem server.pem client.pem

配置docker

修改 dockerd 的启动命令:

dockerd --tlsverify --tlscacert=ca.pem --tlscert=server.pem --tlskey=server-key.pem -H=0.0.0.0:2376

为了连接远端 Docker 并验证服务端证书,需要提供客户端 key、客户端证书以及信任的 CA:

docker --tlsverify --tlscacert=ca.pem --tlscert=client.pem --tlskey=client-key.pem -H=$HOST:2376 version

每次执行 docker 命令时都提供证书是很麻烦的,我们可以把证书和密钥放在 ~/.docker 目录下,并设置 DOCKER_HOSTDOCKER_TLS_VERIFY 环境变量,这样默认就走 TLS 的方式。

mkdir -p ~/.docker
cp -v {ca,cert,key}.pem ~/.docker
export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1

docker ps

注意: .docker目录下的证书文件名必须为 ca.pem, cert.pem, key.pem

另外还可以利用 curl 来发送 Docker 请求:

curl https://$HOST:2376/images/json \
  --cert ~/.docker/cert.pem \
  --key ~/.docker/key.pem \
  --cacert ~/.docker/ca.pem

参考内容

[1] generate-self-signed-certificates
[2] Docker security

stun

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
您好!以下是DockerTLS配置文档: 1. 首先,确保您已经安装了Docker。如果没有安装,请参考Docker官方文档进行安装。 2. 生成TLS证书和密钥: - 创建一个用于存储证书和密钥的目录,例如 `/etc/docker/certs.d`。 - 使用以下命令生成CA证书和私钥: ``` $ 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 ***.pem -out server.csr $ echo subjectAltName = IP:<your-server-ip>,IP:127.0.0.1 > 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 *** $ echo extendedKeyUsage = clientAuth > extfile-client.cnf $ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile-client.cnf ``` 3. 配置Docker守护进程: - 编辑或创建 `/etc/docker/daemon.json` 文件,并添加以下内容: ``` { "tls": true, "tlscacert": "/etc/docker/certs.d/ca.pem", "tlscert": "/etc/docker/certs.d/server-cert.pem", "tlskey": "/etc/docker/certs.d/server-key.pem", "tlsverify": true } ``` - 重新启动Docker守护进程,使配置生效。 4. 配置Docker客户端: - 将客户端证书和密钥复制到客户端机器上的适当位置,例如 `/etc/docker/certs.d/client.pem` 和 `/etc/docker/certs.d/key.pem`。 - 设置环境变量 `DOCKER_TLS_VERIFY` 为 `1`。 - 设置环境变量 `DOCKER_CERT_PATH` 为证书和密钥的存储路径,例如 `/etc/docker/certs.d`。 现在,您已经完成了DockerTLS配置。通过使用TLS证书和密钥,您可以保护Docker守护进程和与之通信的客户端之间的通信安全性。请确保妥善保管生成的证书和密钥文件,并仅将其提供给受信任的实体。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贝克街的流浪猫

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值