我可以将哪些功能放入Docker Nginx容器中?

时间:2017-04-18 08:50:47

标签: linux security docker linux-capabilities

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

我可以放弃哪些功能?

图像类似于标准Docker Nginx Alpine图像:https://github.com/nginxinc/docker-nginx/blob/0c7611139f2ce7c5a6b1febbfd5b436c8c7d2d53/mainline/alpine/Dockerfile,以root身份启动Nginx,然后以用户'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会丢弃所有功能,除了那些需要的功能”,这可能意味着一个人不需要放弃任何功能? ...

...但是有this Red Hat blog post关于丢失这些功能的丢失 - 所以似乎(某些)默认功能不需要。不知道该相信什么,我想知道人们是否知道可以(应该)删除哪些功能。

(我也许可以测试一下自己,但是即使我测试掉了一个功能并且事情似乎在几个小时或几天内都能正常工作 - 我可能仍然会放弃错误的功能?问题可能会出现,甚至更晚?所以看起来像比起测试我自己更安全地问我在这里和测试我自己)

(我很惊讶这已经没有在其他地方得到解答了吗?难道很多人在Docker中使用Nginx,因此想要删除功能吗?)

1 个答案:

答案 0 :(得分:1)

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

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

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

您可以使用这些命令检查是否在端口8080上本地拥有欢迎页面,如果您删除了启动时进程崩溃的任何功能。 (注意,根据Secure Your Containers with this One Weird Trick,需要dac_override意味着他们可能做错了。)

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

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

仍然有效。

通过将nginx作为非root用户运行,也可以删除其他权限。在这种情况下,您无法使用user nginx;指令,而是使用USER nginx中的Dockerfile。这也会阻止您使用特权端口。

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