在 Debian 服务器上,我们应该将证书存储在 /etc/ssl/certs 目录中,将密钥文件存储在 /etc/ssl/private 目录中。
问题是 SSL 私钥文件只能由所有者读取。所以,我想知道如何让 Docker 容器可以读取它的最佳做法是什么?
我的意思是,我在 Docker 容器上运行一项服务,该服务需要准备好 SSL 证书和密钥文件才能通过 HTTPS 公开它。在其默认设置中,我访问 /etc/ssl/private/server.key 文件时被拒绝访问。
为了解决这个问题,我将这个文件移动到另一个目录并将其设置为 644。但是,这是对的吗?
任何帮助,将不胜感激
答案1
为了解决这个问题,我将这个文件移动到另一个目录并将其设置为 644。但是,这是对的吗?
不,这真是个坏主意。将其设置为 644 会使密钥文件可供所有人读取,这绝对是您不想做的事情。
首选方案是使用反向代理,如 nginx、haproxy 等,它们负责建立 https 连接。然后,此代理可以将连接转发到 docker 容器,而后者无需执行 https 部分。
这样做的好处是,像 nginx、haproxy 等反向代理在编写方式上会尽量减少有人窃取密钥的可能性。
如果出于某种原因确实需要容器能够读取密钥文件,则在容器主机上创建一个专用于 SSL 密钥的组。为该组选择一个在容器中也是空闲的 GID。将组/etc/ssl/private_dir
和密钥设置为这个专用组。并允许该组读取密钥。在每个应该能够读取该密钥的容器中创建具有相同 ID 的相同组,查看应该读取该密钥的进程正在运行的用户,然后将该用户添加到创建的组中。
但是,如果您允许应用程序读取该密钥(尤其是您自己编写的密钥),则需要确保密钥仍然保存。例如,如果您的应用程序使用第三方库,您需要完全信任这些库,确保它们不是恶意的,并搜索此类密钥以将一些密钥发送到外部服务器。)
答案2
我刚刚弄清楚如何使用 acme.sh 正确地执行此操作:
在容器上设置一个标签,稍后将使用该标签来查找容器
docker run --rm -it -d --label=sh.acme.autoload.domain=example.com nginx:latest
以 acme 可以识别的方式导出变量并将其部署到容器中
# 查找容器的标签值导出DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=example.com
# 容器中的目标文件路径。# 文件将被复制到容器中的位置。export DEPLOY_DOCKER_CONTAINER_KEY_FILE="/etc/nginx/ssl/example.com/key.pem" export DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/nginx/ssl/example.com/cert.pem" export DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/nginx/ssl/example.com/ca.pem" export DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/nginx/ssl/example.com/full.pem"
# 在容器中重新加载服务的命令。export DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload"
执行 acme 脚本,以便将其部署到容器镜像中
acme.sh --deploy --deploy-hook docker -d example.co
https://github.com/acmesh-official/acme.sh/wiki/deploy-to-docker-containers