我可以在 Docker Nginx 容器中加入哪些功能?

Kaj*_*nus 6 linux security docker linux-capabilities

我在 Docker 容器中运行 Nginx,出于安全原因,我希望尽可能多地删除 Linux 功能。

然后我可以放弃哪些能力?

该镜像类似于此处的标准 Docker Nginx Alpine 镜像:https : //github.com/nginxinc/docker-nginx/blob/0c7611139f2ce7c​​5a6b1febbfd5b436c8c7d2d53/mainline/alpine/Dockerfile,它以 root 身份启动 Nginx,然后以 root 身份运行工作进程用户'nginx',看:

root@instance-1:/opt/ed# docker-compose exec web bash
bash-4.3# # Now we're inside the container.
bash-4.3# ps aux
PID   USER     TIME   COMMAND
    1 root       0:00 /bin/sh -c /etc/nginx/run-envsubst.sh && nginx
   10 root       0:00 nginx: master process nginx
   11 nginx      0:00 nginx: worker process
   12 nginx      0:00 nginx: cache manager process
   14 root       0:00 bash
   18 root       0:00 ps aux
Run Code Online (Sandbox Code Playgroud)

侦听端口 80 和 443,+ 使用 Docker-Compose 的 'volume: ....' 指令挂载一些目录。

显然,这些是 Docker 默认授予容器的能力:

s.Process.Capabilities = []string{
    "CAP_CHOWN",
    "CAP_DAC_OVERRIDE",
    "CAP_FSETID",
    "CAP_FOWNER",
    "CAP_MKNOD",
    "CAP_NET_RAW",
    "CAP_SETGID",
    "CAP_SETUID",
    "CAP_SETFCAP",
    "CAP_SETPCAP",
    "CAP_NET_BIND_SERVICE",
    "CAP_SYS_CHROOT",
    "CAP_KILL",
    "CAP_AUDIT_WRITE",
}
Run Code Online (Sandbox Code Playgroud)

从这里:https : //github.com/docker/docker/blob/master/oci/defaults_linux.go#L62-L77

我在这里找到了链接:https : //docs.docker.com/engine/security/security/#linux-kernel-capabilities,该页面说:“默认情况下,Docker 会删除除所需功能之外的所有功能”,这可能意味着那个不需要放弃任何能力?...

... 然而,有一篇 Red Hat 博客文章关于删除丢失的这些功能 - 所以似乎(一些)默认功能然后是不需要的。不确定该相信什么,我想知道人们是否知道可以(应该)放弃哪些功能。

(我也许可以测试自己,但即使我测试了一个功能并且事情似乎可以正常工作几个小时或几天 - 我可能仍然放弃了错误的功能?问题可能会出现,甚至更晚?所以似乎对两者都更安全在这里提问并测试自己,而不是测试自己)

(我很惊讶这还没有在其他地方得到回答?不是很多人在 docker 中使用 Nginx,因此想要放弃功能吗?)

col*_*fix 6

我也在想同样的事情,所以我做了一些研究。请注意,这不是专家的答案。

简短回答:如果您以用户身份启动 nginx 并使用非特权端口(> 1024),则可以放弃所有特权。这在没有 Root 的 Docker中的Nginx 中有描述,一些附加信息可以在以非 root 用户身份运行 Nginx 中找到。

ajhaydock / nginx的nginx的图像特别建议--cop-drop=ALL(虽然我不建议使用这种图像,因为它是目前相当大:700MB)。

更长的答案:所需的特权可能会因您的配置以及您是否要以 root 身份启动 nginx 而有所不同。

让我们从官方 docker 镜像及其默认配置开始。最低能力如下:

docker pull nginx:alpine
docker run -p 8080:80 --cap-drop=all \
    --cap-add=chown --cap-add=dac_override \
    --cap-add=setgid --cap-add=setuid \
    --cap-add=net_bind_service \
    nginx:alpine
Run Code Online (Sandbox Code Playgroud)

您可以使用这些命令检查您是否将在端口 8080 上本地拥有欢迎页面,并且如果您删除任何功能,则该进程在启动时会崩溃。(注意,根据使用这个奇怪的技巧保护您的容器,需要dac_override意味着他们可能做错了..)

显然,net_bind_service只有在监听 80 和 443 等特权端口时才需要。 由于我们可以根据需要自由重定向,因此可以通过简单地监听更高的端口来删除它:

docker cp nginx:/etc/nginx/conf.d/default.conf .
sed -i 's/listen\s*80;/listen 8080;/' default.conf
docker rm nginx
docker run -p 8080:8080 --cap-drop=all \
    --cap-add=chown --cap-add=dac_override \
    --cap-add=setgid --cap-add=setuid \
    -v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf \
    nginx:alpine
Run Code Online (Sandbox Code Playgroud)

仍然有效。

其他权限也可以通过以非 root 用户身份运行 nginx 来删除。在这种情况下,您不能使用该user nginx;指令,而是USER nginxDockerfile. 这也可以防止您使用特权端口。

可能对其他人有帮助的更多资源: