7

我在 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

监听端口 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",
}

从这里: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,因此想要放弃功能吗?)

4

1 回答 1

8

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

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

ajhaydock /nginx nginx 镜像特别推荐--cap-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

您可以使用这些命令检查您是否会在端口 8080 上本地拥有欢迎页面,如果您删除任何功能,该进程在启动时会崩溃。(注意,根据Secure Your Containers with this One Weird Trick的说法,需要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

仍然有效。

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

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

于 2017-08-08T13:56:00.337 回答