上一篇文章中的警告在这里展开,警告内容如下:
1 | WARNING: API is accessible on http://0.0.0.0:2376 without encryption. |
这样所有 ip 都能通过 docker -H <remote-dcoker-server_ip>:6379 [OPTION]命令与远程的 docker 守护进程通信,操作 docker 容器,生产上不提倡这种做法。
TLS
传输层安全性协议(英语:Transport Layer Security,缩写作TLS),及其前身安全套接层(Secure Sockets Layer,缩写作SSL)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。
CA是证书的签发机构。CA是负责签发证书、认证证书、管理已颁发证书的机关。它要制定政策和具体步骤来验证、识别用户身份,并对用户证书进行签名,以确保证书持有者的身份和公钥的拥有权。
CA 也拥有一个证书(内含公钥)和私钥。网上的公众用户通过验证 CA 的签字从而信任 CA ,任何人都可以得到 CA 的证书(含公钥),用以验证它所签发的证书。
证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA 的信息、有效时间、证书序列号等信息的明文,同时包含一个签名。
签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA 的私钥对信息摘要进行加密,密文即签名。
整个过程为:
1.服务器向CA机构获取证书,当浏览器首次请求服务器的时候,服务器返回证书给浏览器。(证书包含:公钥+申请者与颁发者的相关信息+签名)
2.浏览器得到证书后,开始验证证书的相关信息。
3.验证完证书后,如果证书有效,客户端是生成一个随机数,然后用证书中的公钥进行加密,加密后,发送给服务器,服务器用私钥进行解密,得到随机数。之后双方便开始用该随机数作为钥匙,对要传递的数据进行加密、解密。
我们需要在远程 docker 服务器使用CA 认证来生成客户端和服务端证书、服务器密钥,然后自签名,再颁发证书给需要连接远程 docker ademon 的客户端。
以上内容部分摘自https://www.cnblogs.com/yunlongaimeng/p/9417276.html
TLS验证
文档中指出:Docker over TLS should run on TCP port 2376.
服务端(CA机构、Docker Daemon在同一台服务器)
1 | #1.生成CA私钥ca-key.pem(rsa加密) |
使用scp将ca.pem,ca-key.pem发送到客户端服务器。其实应该先将服务器和客户端的申请文件发送至CA,由CA认证后向二者发放CA证书。
客户端
对于客户端身份验证,应创建客户端密钥和证书签名请求
1 | #1.生成客户端私钥client-key.pem |
默认安全连接
为简化操作,不必每次都对-H tcp://$host,–tls等参数进行调用,可以按下面步骤更改
服务端:将安全验证添加到/lib/systemd/system/docker.service中
1 | root@admin-dsq:~/.docker# ls # 此处为CA自签名证书、服务器证书、服务器密钥 |
客户端:如果要在默认情况下保护Docker客户端连接,可以将文件移动到.docker目录中,并设置 DOCKER_HOST和DOCKER_TLS_VERIFY变量
1 | [root@docker-study .docker]# ls #此处为CA自签名证书、客户端证书、客户端密钥 |
Docker现在默认安全连接
过程中出现的错误
- CA自签名证书默认路径为/root/.docker,服务器或客户端的CA证书和密钥也应该放在此目录下
1 | [root@docker-study ~]# docker --tlsverify -H 172.18.74.62 info |
- info:x509: cannot validate certificate for 172.18.74.62 because it doesn’t contain any IP SANs
1 | [root@docker-study /]# docker --tlsverify -H 172.18.74.62 info |
在指定证书的过程中要指定IP地址,参照:https://stackoverflow.com/questions/42116783/x509-cannot-validate-certificate-because-it-doesnt-contain-any-ip-sans 或者可以按照Docker文档中所给出的步骤即上述中的过程。
- 在客户端连接Docker Daemon时未成功,在Docker Daemon端报出如下信息:
1 | 客户端: |
Docker Daemon 使用 dockerd –tlsverify –tlscacert=/root/CA/ca.pem –tlscert=server-cert.pem –tlskey=server-key.pem -H 0.0.0.0:2376 启动后仅接受来自提供CA信任的客户端的连接,所以客户端也需要进行CA认证,二者所使用的CA自签名证书是一样的。
当ca.pem不同时有如下报错:
1 | [root@docker-study .docker]# docker info |
- 报错为私钥和公钥不匹配
1 | [root@docker-study client]# docker --tlsverify --tlscacert=../ca.pem --tlscert=../server-cert.pem --tlskey=key.pem -H 172.18.74.62 info |
- curl: (60) Peer’s Certificate issuer is not recognized.
1 | [root@docker-study ~]# curl https://172.18.74.62:2376/info |
报错为无法识别证书颁发者,因为是自己制作的证书,系统对CA没有认证,所以无法识别。
解决办法是将签发该证书的私有CA公钥cacert.pem文件内容,追加到/etc/pki/tls/certs/ca-bundle.crt下。
1 | #ubuntu下 |
- curl: (58) NSS: client certificate not found (nickname not specified)
1 | [root@docker-study .docker]# curl https://172.18.74.62:2376/version |
没有找到客户端认证,加–cert参数指定下路径就行了
- NSS error -8178 (SEC_ERROR_BAD_KEY)
1 | [root@docker-study .docker]# curl --cert /root/.docker/cert.pem https://172.18.74.62:2376/version |
参考:https://stackoverflow.com/questions/22499425/ssl-certificate-generated-with-openssl-not-working-on-nss?answertab=active#tab-top
我尝试了无密码和另外的des3 加密算法都没有成功,仍然是这个错误,待更新。