首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

保护Docker守护程序套接字 | Protect the Docker daemon socket (Engine)

默认情况下,Docker通过一个非联网的Unix套接字运行。它还可以选择使用HTTP套接字进行通信。

如果您需要以安全的方式通过网络联系到Docker,则可以通过指定tlsverify旗帜和指点码头tlscacert标记为可信CA证书。

在守护进程模式中,它将只允许来自由该CA签名的证书验证的客户端的连接。在客户端模式下,它将只连接到由该CA签名的证书的服务器。

警告使用TLS和管理CA是一个高级主题。在生产中使用OpenSSL、x 509和TLS之前,请熟悉它。警告这些TLS命令将只在Linux上生成一组有效的证书。MacOS附带的OpenSSL版本与Docker所需的证书不兼容。

使用OpenSSL创建CA、服务器和客户端密钥

*替换所有的实例$HOST在下面的示例中,使用Docker守护进程主机的DNS名称。

首先,在Docker守护进程的主机,生成CA私钥和公钥:

代码语言:javascript
复制
$ 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”(即服务器FQDN或您的姓名)与您将用于连接到Docker的主机名匹配:

*替换所有的实例$HOST在下面的示例中,使用Docker守护进程主机的DNS名称。

代码语言:javascript
复制
$ 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.20127.0.0.1*

代码语言:javascript
复制
$ echo subjectAltName = DNS:$HOST,IP:10.10.10.20,IP:127.0.0.1 > extfile.cnf

将Docker守护进程密钥的扩展使用属性设置为仅用于服务器身份验证:

代码语言:javascript
复制
$ echo extendedKeyUsage = serverAuth > extfile.cnf

现在,生成密钥:

代码语言:javascript
复制
$ 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守护进程的主机上执行这个步骤。

代码语言:javascript
复制
$ 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

要使密钥适合客户端身份验证,请创建一个扩展名配置文件:

代码语言:javascript
复制
$ echo extendedKeyUsage = clientAuth > extfile.cnf

现在签署私钥:

代码语言:javascript
复制
$ openssl x509 -req -days 365 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:

生成后cert.pemserver-cert.pem您可以安全地删除两个证书签名请求:

代码语言:javascript
复制
$ rm -v client.csr server.csr

在默认情况下umask022岁的时候,你的秘密钥匙世界可读性也可以为你和你的团队写。

为了保护您的密钥不受意外损坏,您需要删除它们的写权限。若要使它们仅供您阅读,请按以下方式更改文件模式:

代码语言:javascript
复制
$ chmod -v 0400 ca-key.pem key.pem server-key.pem

证书可以具有世界可读性,但您可能希望删除写入访问,以防止意外损坏:

代码语言:javascript
复制
$ chmod -v 0444 ca.pem server-cert.pem cert.pem

现在,您可以让Docker守护进程只接受来自客户端的连接,这些客户端提供了我们的CA信任的证书:

代码语言:javascript
复制
$ 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名称。

代码语言:javascript
复制
$ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
  -H=$HOST:2376 version

注意:通过TLS的Docker应该在TCP端口2376上运行。警告:如上例所示,当您使用证书身份验证时,不必docker使用sudodocker组运行客户端。这意味着任何拥有密钥的人都可以给你的Docker守护进程提供任何指令,让他们可以访问托管守护进程的机器。保护这些密钥,就像你使用root密码一样!

默认安全

如果您想默认保护您的Docker客户端连接,您可以将文件移动到.docker您的主目录中的目录 - 并设置DOCKER_HOSTDOCKER_TLS_VERIFY变量(而不是传递-H=tcp://$HOST:2376--tlsverify每次调用)。

代码语言:javascript
复制
$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1

默认情况下,Docker现在将安全地连接:

代码语言:javascript
复制
$ docker ps

其他模式

如果您不想拥有完全的双向身份验证,可以通过混合标志在其他各种模式下运行Docker。

守护进程模式

  • tlsverifytlscacerttlscerttlskey集:验证客户端
  • tlstlscerttlskey:不要验证客户端

客户模式

  • tls*基于公共/默认CA池的服务器身份验证
  • tlsverifytlscacert:根据给定的CA验证服务器
  • tlstlscerttlskey:以验证客户端证书,不验证服务器基于给定CA
  • tlsverifytlscacerttlscerttlskey:以验证客户端证书并认证服务器基于给定CA

如果找到,客户端将发送其客户端证书,因此您只需将钥匙放入~/.docker/{ca,cert,key}.pem。或者,如果您想将密钥存储在其他位置,则可以使用环境变量指定该位置DOCKER_CERT_PATH

代码语言:javascript
复制
$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps

使用curl

使用curl要发出测试API请求,需要使用三个额外的命令行标志:

代码语言:javascript
复制
$ curl https://$HOST:2376/images/json \
  --cert ~/.docker/cert.pem \
  --key ~/.docker/key.pem \
  --cacert ~/.docker/ca.pem

相关信息

  • 使用证书进行存储库客户端验证
  • 使用可信映像

扫码关注腾讯云开发者

领取腾讯云代金券