问题描述
某用户的本地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功能来管理敏感信息。这允许你将凭据存储在一个安全的地方,然后在容器内部引用这些凭据,而不会在环境变量中明文传递。下面是一个步骤的示例:
- 创建一个Docker secret来存储代理凭据。假设代理凭据是
username:password
,可以通过以下命令创建一个secret:
bash
echo "username:password" | docker secret create proxy_credentials -
- 修改你的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_FILE
和HTTPS_PROXY_FILE
环境变量指向了代理凭据的文件路径,这些文件路径在容器内部是通过Docker secret挂载的。
- 在容器内部,你可以通过读取
HTTP_PROXY_FILE
和HTTPS_PROXY_FILE
文件来获取代理凭据,而不会在环境变量中明文传递。
这样一来,即使普通用户查看环境变量,也无法直接获取代理凭据。同时,代理凭据也不会以明文形式出现在systemd环境中。
解决方案2
另一种方法是使用访问控制,确保只有具有特定权限的用户才能查看代理凭据。你可以通过设置文件的权限,将代理凭据文件限制为只有特定用户或组可以读取。这样,普通用户将无法读取代理凭据文件。
- 创建一个代理凭据文件,并设置合适的权限。假设代理凭据是
username:password
,可以通过以下命令创建文件并设置权限:
bash
echo "username:password" > /path/to/proxy_credentials
chmod 600 /path/to/proxy_credentials
- 修改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
- 在你的应用程序内部,读取
HTTP_PROXY_FILE
和HTTPS_PROXY_FILE
文件来获取代理凭据。
这种方法依赖于操作系统的文件访问控制机制,确保只有特定用户或组可以访问代理凭据文件。这样,普通用户将无法直接获取代理凭据,也不会在环境变量中明文传递。
解决方案3(警告:仅供参考,可能存在安全风险)
以下解决方案可能存在安全风险,使用时请谨慎。
如果你不希望修改docker-compose文件,你也可以通过修改systemd unit文件来解决这个问题。但是,请注意这样做可能会存在一定的安全风险,因为它涉及到修改系统级别的配置。
- 编辑docker守护程序的systemd unit文件。在终端中运行以下命