如何保护由systemd运行的本地docker守护程序的代理凭据,以防止普通用户查看?

93次阅读
没有评论

问题描述

某用户的本地Docker CLI二进制文件通过局域网连接到一台运行在同一台机器上的Docker守护程序。为了某些任务,这个守护程序需要通过公司的防火墙/代理系统连接到互联网。这个问题是基于Ubuntu 16.04 LTS的(类似的系统也可能遇到类似问题)。

用户根据《Docker HTTP代理配置终极指南》中的情况#2配置了守护程序,具体配置如下:

在文件 /etc/systemd/system/docker.service.d/http-proxy.conf 中添加以下内容:

[Service]
Environment="HTTP_PROXY=http://your.proxy:8080"
Environment="HTTPS_PROXY=http://your.proxy:8080"
Environment="NO_PROXY=127.0.0.1,localhost"

但为了使这个配置生效,用户必须在“your.proxy”部分的服务器名称之前添加“username:password@”(需要使用sudo权限)。然后用户执行以下操作来操作/重启systemd和Docker:

sudo systemctl daemon-reload
sudo systemctl restart docker

最终,用户以普通用户身份执行以下命令来检查结果:

systemctl show --property=Environment docker

这会显示类似以下内容的环境变量(代理凭据以明文形式列出):

Environment=HTTP_PROXY=http://username:password@your.proxy:8080 HTTPS_PROXY=http://username:password@your.proxy:8080 NO_PROXY=127.0.0.1,localhost

用户明确不希望普通用户能够查看这组代理凭据。那么,如何防止任何普通用户获取这些代理凭据?是否有一种方法适用于systemd环境的概念?或者是否需要使用其他方法?以下将提供解决方案。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

解决方案1

为了防止普通用户获取代理凭据,可以使用docker的secrets功能来管理敏感信息。这允许你将凭据存储在一个安全的地方,然后在容器内部引用这些凭据,而不会在环境变量中明文传递。下面是一个步骤的示例:

  1. 创建一个Docker secret来存储代理凭据。假设代理凭据是username:password,可以通过以下命令创建一个secret:

bash
echo "username:password" | docker secret create proxy_credentials -

  1. 修改你的docker-compose文件,将代理凭据作为一个secret引用。在你的服务定义中,添加一个secrets部分,如下所示:

yaml
version: '3'
services:
your_service:
image: your_image
environment:
- HTTP_PROXY_FILE=/run/secrets/proxy_credentials
- HTTPS_PROXY_FILE=/run/secrets/proxy_credentials
secrets:
- source: proxy_credentials
target: /run/secrets/proxy_credentials
secrets:
proxy_credentials:
external: true

在上面的示例中,HTTP_PROXY_FILEHTTPS_PROXY_FILE环境变量指向了代理凭据的文件路径,这些文件路径在容器内部是通过Docker secret挂载的。

  1. 在容器内部,你可以通过读取HTTP_PROXY_FILEHTTPS_PROXY_FILE文件来获取代理凭据,而不会在环境变量中明文传递。

这样一来,即使普通用户查看环境变量,也无法直接获取代理凭据。同时,代理凭据也不会以明文形式出现在systemd环境中。

解决方案2

另一种方法是使用访问控制,确保只有具有特定权限的用户才能查看代理凭据。你可以通过设置文件的权限,将代理凭据文件限制为只有特定用户或组可以读取。这样,普通用户将无法读取代理凭据文件。

  1. 创建一个代理凭据文件,并设置合适的权限。假设代理凭据是username:password,可以通过以下命令创建文件并设置权限:

bash
echo "username:password" > /path/to/proxy_credentials
chmod 600 /path/to/proxy_credentials

  1. 修改docker-compose文件,将代理凭据文件的路径传递给容器作为环境变量。

yaml
version: '3'
services:
your_service:
image: your_image
environment:
- HTTP_PROXY_FILE=/path/to/proxy_credentials
- HTTPS_PROXY_FILE=/path/to/proxy_credentials

  1. 在你的应用程序内部,读取HTTP_PROXY_FILEHTTPS_PROXY_FILE文件来获取代理凭据。

这种方法依赖于操作系统的文件访问控制机制,确保只有特定用户或组可以访问代理凭据文件。这样,普通用户将无法直接获取代理凭据,也不会在环境变量中明文传递。

解决方案3(警告:仅供参考,可能存在安全风险)

以下解决方案可能存在安全风险,使用时请谨慎。

如果你不希望修改docker-compose文件,你也可以通过修改systemd unit文件来解决这个问题。但是,请注意这样做可能会存在一定的安全风险,因为它涉及到修改系统级别的配置。

  1. 编辑docker守护程序的systemd unit文件。在终端中运行以下命

正文完