保护 Docker 守护程序套接字
默认情况下,Docker 通过非网络化的 UNIX 套接字运行。它还可以 (可选)使用 SSH 或 TLS (HTTPS) 套接字进行通信。
使用 SSH 保护 Docker 守护程序套接字
注意
给定的
USERNAME
必须具有访问 远程计算机。请参阅以非 root 用户身份管理 Docker,了解如何为非 root 用户提供对 docker 套接字的访问权限。
以下示例创建一个docker context
使用遥控器连接dockerd
守护进程host1.example.com
使用 SSH,以及
作为docker-user
用户:
$ docker context create \
--docker host=ssh://docker-user@host1.example.com \
--description="Remote engine" \
my-remote-engine
my-remote-engine
Successfully created context "my-remote-engine"
创建上下文后,使用docker context use
要将docker
命令行界面
要使用它并连接到远程引擎,请执行以下作:
$ docker context use my-remote-engine
my-remote-engine
Current context is now "my-remote-engine"
$ docker info
<prints output of the remote engine>
使用default
context 切换回默认(本地)守护进程:
$ docker context use default
default
Current context is now "default"
或者,使用DOCKER_HOST
用于临时切换的环境变量
这docker
CLI 使用 SSH 连接到远程主机。这不需要
创建上下文,这对于创建具有不同
发动机:
$ export DOCKER_HOST=ssh://docker-user@host1.example.com
$ docker info
<prints output of the remote engine>
SSH 提示
为了获得最佳的 SSH 用户体验,请配置~/.ssh/config
如下以允许
重用 SSH 连接多次调用docker
命令行界面:
ControlMaster auto
ControlPath ~/.ssh/control-%C
ControlPersist yes
使用 TLS (HTTPS) 保护 Docker 守护程序套接字
如果您需要以安全的方式通过 HTTP 而不是 SSH 访问 Docker,
您可以通过指定tlsverify
标志并指向 Docker 的tlscacert
标志添加到受信任的 CA 证书中。
在 daemon 模式下,它只允许来自客户端的连接 由该 CA 签名的证书进行身份验证。在 client 模式下, 它仅连接到具有该 CA 签名的证书的服务器。
重要
使用 TLS 和管理 CA 是一个高级主题。熟悉自己 在 OpenSSL、x509 和 TLS 中使用它。
使用 OpenSSL 创建 CA、服务器和客户端密钥
注意
替换 的所有实例
$HOST
在以下示例中,使用 Docker 守护程序主机的 DNS 名称。
首先,在 Docker 守护程序的主机上,生成 CA 私钥和公钥:
$ openssl genrsa -aes256 -out ca-key.pem 4096
Generating RSA private key, 4096 bit long modulus
..............................................................................++
........++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Sales
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.au
现在您拥有了 CA,您可以创建服务器密钥和证书 签名请求 (CSR)。确保 “Common Name” 与您使用的主机名匹配 要连接到 Docker,请执行以下作:
注意
替换 的所有实例
$HOST
在以下示例中,使用 Docker 守护程序主机的 DNS 名称。
$ openssl genrsa -out server-key.pem 4096
Generating RSA private key, 4096 bit long modulus
.....................................................................++
.................................................................................................++
e is 65537 (0x10001)
$ openssl req -subj "/CN=$HOST" -sha256 -new -key server-key.pem -out server.csr
接下来,我们将使用 CA 对公钥进行签名:
由于 TLS 连接可以通过 IP 地址和 DNS 名称进行,因此 IP 地址
需要在创建证书时指定。例如,要允许连接
用10.10.10.20
和127.0.0.1
:
$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 >> extfile.cnf
将 Docker 守护程序密钥的扩展使用属性设置为仅用于 服务器身份验证:
$ echo extendedKeyUsage = serverAuth >> 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
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
授权插件提供更多 精细控制,以补充来自双向 TLS 的身份验证。另外 对于上述文档中描述的其他信息,授权插件 在 Docker 守护程序上运行,接收用于连接的证书信息 Docker 客户端。
对于客户端身份验证,请创建客户端密钥和证书签名 请求:
注意
为了简化接下来的几个步骤,您可以执行以下作 在 Docker 守护程序的主机上。
$ openssl genrsa -out key.pem 4096
Generating RSA private key, 4096 bit long modulus
.........................................................++
................++
e is 65537 (0x10001)
$ openssl req -subj '/CN=client' -new -key key.pem -out client.csr
要使密钥适合客户端身份验证,请创建新的扩展 配置文件:
$ 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
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
生成后cert.pem
和server-cert.pem
您可以安全地删除
两个证书签名请求和扩展配置文件:
$ rm -v client.csr server.csr extfile.cnf extfile-client.cnf
使用默认的umask
的 022 中,您的密钥是全球可读的,并且
为您和您的组写入。
为了保护您的密钥免受意外损坏,请移除其 写入权限。要使它们仅供您读取,请按如下方式更改文件模式:
$ chmod -v 0400 ca-key.pem key.pem server-key.pem
证书可以是全局可读的,但您可能希望删除对 防止意外损坏:
$ chmod -v 0444 ca.pem server-cert.pem cert.pem
现在,您可以使 Docker 守护进程仅接受来自客户端的连接 提供 CA 信任的证书:
$ dockerd \
--tlsverify \
--tlscacert=ca.pem \
--tlscert=server-cert.pem \
--tlskey=server-key.pem \
-H=0.0.0.0:2376
要连接到 Docker 并验证其证书,请提供您的客户端密钥 证书和受信任的 CA:
提示
此步骤应在 Docker 客户端计算机上运行。因此,您 需要复制您的 CA 证书、服务器证书和客户端 证书。
注意
替换 的所有实例
$HOST
在以下示例中,使用 Docker 守护程序主机的 DNS 名称。
$ docker --tlsverify \
--tlscacert=ca.pem \
--tlscert=cert.pem \
--tlskey=key.pem \
-H=$HOST:2376 version
注意
基于 TLS 的 Docker 应在 TCP 端口 2376 上运行。
警告
如上例所示,您无需运行
docker
客户 跟sudo
或docker
组。 这意味着任何拥有密钥的人都可以向您的 Docker 提供任何指令 守护进程,授予他们对托管守护进程的机器的 root 访问权限。警卫 这些密钥就像 root 密码一样!
默认安全
如果要默认保护 Docker 客户端连接,可以将
将文件复制到.docker
目录中的 ---,并将DOCKER_HOST
和DOCKER_TLS_VERIFY
变量(而不是传递-H=tcp://$HOST:2376
和--tlsverify
每次通话)。
$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
Docker 现在默认安全连接:
$ docker ps
其他模式
如果您不想进行完整的双向身份验证,可以运行 Docker 通过混合标志。
守护程序模式
tlsverify
,tlscacert
,tlscert
,tlskey
set:对客户端进行身份验证tls
,tlscert
,tlskey
:不对客户端进行身份验证
客户端模式
tls
:基于公共/默认 CA 池对服务器进行身份验证tlsverify
,tlscacert
:根据给定的 CA 对服务器进行身份验证tls
,tlscert
,tlskey
:使用客户端证书进行身份验证,不要 根据给定的 CA 对服务器进行身份验证tlsverify
,tlscacert
,tlscert
,tlskey
:使用客户端进行身份验证 证书并根据给定的 CA 对服务器进行身份验证
如果找到,客户端会发送其客户端证书,因此您只需要
将密钥放入~/.docker/{ca,cert,key}.pem
.或者
如果要将密钥存储在其他位置,可以指定
location 使用环境变量DOCKER_CERT_PATH
.
$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps
使用连接到安全的 Docker 端口curl
要使用curl
要发出测试 API 请求,您需要使用三个额外的命令行
标志:
$ curl https://$HOST:2376/images/json \
--cert ~/.docker/cert.pem \
--key ~/.docker/key.pem \
--cacert ~/.docker/ca.pem