以非root用户身份启动容器,以root身份启动,然后降级为非root用户

我正在创build一些Docker镜像,我正在阅读其他人如何做这个。 当涉及到在容器中运行进程的用户时,我已经确定了三种一般模式:

  • 它使用root用户进行所有操作(在根目录下的容器内部产生的进程(es))。
  • 它使用root用户 ,做一些东西,然后降级到非root用户 (所以主进程在非root用户下运行,即使pid 1仍然是root)。 这发生在例如官方的nginx容器中: PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 5 nginx 0:00 nginx: worker process PID USER TIME COMMAND 1 root 0:00 nginx: master process nginx -g daemon off; 5 nginx 0:00 nginx: worker process
  • 它使用非root用户的一切。

我知道,一般来说,如果没有需要的话,应该避免在Docker容器中使用root用户 (虽然似乎这个build议被大量忽略,但这是其他一些主题)。

但是从安全angular度来看,第二个和第三个选项有什么不同?

使用选项1时,所有内容都以root身份运行,这对于多用户环境是不利的,因为使用不是彼此分开的。 它还为每个用户提供了系统pipe理员级访问权限。 然而,在一个容器内,这个问题不大,因为应该只有一个用户(单个应用程序),并且root的能力已经被限制,所以他们不能从容器中分离出来。 因此,大多数人忽略运行一个容器作为用户,因为相比于他们可能遇到的问题,例如卷上的文件的端口限制或权限,安全的附加值是最小的。 这就是说,作为一个用户运行是有一定的价值的,因为这是攻击者必须突破的一个限制。

如果您的容器有初始化代码运行,或者部分应用程序需要root用于打开端口80,则需要选项2.缺点是在初始化期间可以运行的任何漏洞利用都具有容器根权限。 这也意味着docker exec或覆盖docker命令,以root身份在容器内运行该命令。 对于那些寻求安全的人来说,这改进了选项1,他们可能无法做到选项3。

选项3是更改容器的默认用户。 应用程序具有root权限的容器中没有任何意义,所以攻击面减less,但这也意味着您不能使用低于1024的端口,并且主机用户与容器用户之间的主机卷内的文件权限可能不匹配。 默认情况下,覆盖docker命令或使用docker exec ,也将作为受限用户运行。

最大的问题是您可以用容器启动脚本覆盖图像中的默认用户。 因此,作为用户运行的容器可以通过docker run -u root ...切换到root。 而反过来也适用于所有使用默认root用户定义的容器。 您可以按原样使用这些上游映像,只需在启动命令中更改用户即可从选项1切换到选项3。