成功最有效的方法就是向有经验的人学习!

docker 配置远程加密调用

默认情况下,docker使用sock文件形式启动,不对外提供访问接口,想要使用类似 docker-py 这种包来远程调用docker的 API,则必须将docker监听在某个端口来提供服务,但直接暴露HTTP接口是很危险的,攻击者可以很轻松的通过docker暴露的端口进入某个容器,进而获取高级权限,所以必须使用 tlsverify 参数和 tlscacert 参数指向一个受信任的CA,这样客户端必须通过使用CA签名的证书访问docker接口才可以

为方便批量配置,整理脚本如下

#!/bin/bash
#
set -e

certs_dir=docker_certs  # 存放证书的路径
HOSTNAME=$(hostname)
DOCKER_PORT=2376  # 暴露的docker端口

if [ ! -d $certs_dir ];then
  mkdir -p $certs_dir
fi
您暂时无权查看此隐藏内容!
systemctl daemon-reload systemctl restart docker

直接执行脚本即可

验证:
如下所示,如果出现 API listen on [::]:2376API listen on /var/run/docker.sock 表示修改成功了

[root@localhost certs]# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Tue 2020-04-21 22:10:13 CST; 6min ago
     Docs: https://docs.docker.com
 Main PID: 21419 (dockerd)
   Memory: 30.7M
   CGroup: /system.slice/docker.service
           └─21419 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H=0.0.0.0:2376 --tlsverify --tlscacert=/root/certs/docker_certs/ca.pe...

Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.308119401+08:00" level=info msg="[graphdriver] using prior storage driver: overlay2"
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.335533645+08:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.336893667+08:00" level=info msg="Loading containers: start."
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.533743541+08:00" level=info msg="Default bridge (docker0) is assigned with an IP addres...P address"
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.584586725+08:00" level=info msg="Loading containers: done."
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.614190810+08:00" level=info msg="Docker daemon" commit=d14af54 graphdriver(s)=overlay2 ...on=18.09.4
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.614297021+08:00" level=info msg="Daemon has completed initialization"
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.621970279+08:00" level=info msg="API listen on [::]:2376"
Apr 21 22:10:13 myecs dockerd[21419]: time="2020-04-21T22:10:13.622030438+08:00" level=info msg="API listen on /var/run/docker.sock"
Apr 21 22:10:13 myecs systemd[1]: Started Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost certs]# 

客户端连接
首先需要将 CA 证书以及 client 证书拷贝到客户端机器上

使用命令行连接

[root@localhost docker_certs]# docker --tlsverify --tlscacert=ca.pem --tlscert=client-cert.pem --tlskey=client-key.pem -H=52.99.139.56:2376 version
Client:
 Version:           18.09.4
 API version:       1.39
 Go version:        go1.10.8
 Git commit:        d14af54266
 Built:             Wed Mar 27 18:34:51 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          18.09.4
  API version:      1.39 (minimum version 1.12)
  Go version:       go1.10.8
  Git commit:       d14af54
  Built:            Wed Mar 27 18:04:46 2019
  OS/Arch:          linux/amd64
  Experimental:     false
[root@localhost docker_certs]# 

注意:当使用证书连接docker时,即使是普通用户执行,也不需要使用 sudo,这也就意味着任何用户使用证书连接docker都能发送任何指令,甚至获取 root 权限,所以要将证书相关文件妥善保管

设置客户端默认使用证书连接
在用户家目录下创建 .docker 目录

mkdir -pv $HOME/.docker

将 CA 证书以及 client 证书拷贝到 .docker 目录下

cp -a {ca,client-cert,client-key}.pem $HOME/.docker

配置环境变量

export DOCKER_HOST=tcp://52.99.139.56:2376 DOCKER_TLS_VERIFY=1

验证

[root@localhost docker_certs]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@localhost docker_certs]# 

如果想把证书文件放在其他位置,比如 /docker/certs 目录,则需要配置 DOCKER_CERT_PATH 环境变量,比如:

export DOCKER_CERT_PATH=/docker/certs/

docker --tlsverify ps

使用 docker-py 连接

import docker

tls_config = docker.tls.TLSConfig(
    client_cert=('/root/certs/docker_certs/client-cert.pem', '/root/certs/docker_certs/client-key.pem'),
    ca_cert='/root/certs/docker_certs/ca.pem',
    verify='/root/certs/docker_certs/ca.pem'
)

client = docker.DockerClient(base_url='tcp://52.99.139.56:2376', tls=tls_config)

print(client.version())

正常会输出docker版本信息:

{'Platform': {'Name': 'Docker Engine - Community'}, 'Components': [{'Name': 'Engine', 'Version': '18.09.4', 'Details': {'ApiVersion': '1.39', 'Arch': 'amd64', 'BuildTime': '2019-03-27T18:04:46.000000000+00:00', 'Experimental': 'false', 'GitCommit': 'd14af54', 'GoVersion': 'go1.10.8', 'KernelVersion': '3.10.0-1062.18.1.el7.x86_64', 'MinAPIVersion': '1.12', 'Os': 'linux'}}], 'Version': '18.09.4', 'ApiVersion': '1.39', 'MinAPIVersion': '1.12', 'GitCommit': 'd14af54', 'GoVersion': 'go1.10.8', 'Os': 'linux', 'Arch': 'amd64', 'KernelVersion': '3.10.0-1062.18.1.el7.x86_64', 'BuildTime': '2019-03-27T18:04:46.000000000+00:00'}

使用 curl 连接

curl https://52.99.139.56:2376/images/json --cert ./client-cert.pem --key client-key.pem --cacert ca.pem

注意:指定 client-cert.pem 的时候,不能直接使用相对路径,会报错:curl: (58) NSS: client certificate not found: client-cert.pem

必须使用 ./client-cert.pem 指定

使用 -vvv 排查:

[root@localhost docker_certs]# curl https://52.99.139.56:2376/images/json --cert client-cert.pem --key client-key.pem --cacert ca.pem -vvv   
* About to connect() to 127.0.0.1 port 12345 (#0)
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 12345 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: ca.pem
  CApath: none
* warning: certificate file name "client-cert.pem" handled as nickname; please use "./client-cert.pem" to force file name
* NSS: client certificate not found: client-cert.pem
* NSS error -12271 (SSL_ERROR_BAD_CERT_ALERT)
* SSL peer cannot verify your certificate.
* Closing connection 0
curl: (58) NSS: client certificate not found: client-cert.pem
内容查看本文隐藏内容查看需要消耗3土豆币,请先
土豆币按需购买,不退换,请考虑清楚后购买。
赞(0) 打赏
未经允许不得转载:陈桂林博客 » docker 配置远程加密调用
分享到

大佬们的评论 抢沙发

全新“一站式”建站,高质量、高售后的一条龙服务

微信 抖音 支付宝 百度 头条 快手全平台打通信息流

橙子建站.极速智能建站8折购买虚拟主机

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

登录

找回密码

注册