Docker Entrypoint脚本根权限

lit*_*ce3 2 sh chmod keytool chown docker

我有一个具有3个约束的Dockerfile:

1.)Dockerfile中的最终USER语句必须USER tomcat出于安全目的(它是基于tomcat:8.5.23-jre8-alpine映像构建的)

2.)它不能在/root/目录或目录下运行chmod$JAVA_HOME

3.)它必须能够$JAVA_HOME/lib/security在入口点内而不是在Dockerfile中修改目录(因为证书是在容器启动时传递的)

截至目前,我已经

FROM tomcat:8.5.23-jre8-alpine

#### OTHER IMAGE COMMANDS ####

COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh

RUN chown root:root /usr/local/bin/entrypoint.sh

RUN chmod 4755 /usr/local/bin/entrypoint.sh

USER tomcat

ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["catalina.sh", "run"]
Run Code Online (Sandbox Code Playgroud)

我认为将文件所有权授予root和chmod 4755将允许tomcat用户执行入口点,但让入口点以root身份运行,以便它可以根据需要修改文件系统。但是,当我在入口点运行此行时

$JAVA_HOME/bin/keytool -import -alias ca_local -keystore $JAVA_HOME/lib/security/cacerts -storepass XXXXX -noprompt -trustcacerts -file /usr/local/tomcat/certificates/ca-local.cer
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

keytool error: java.io.FileNotFoundException: /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts (Permission denied)
Run Code Online (Sandbox Code Playgroud)

好像切入点实际上并没有以root身份运行,如chown / chmod所暗示的那样。我知道我所有的文件都放在正确的位置,因为当我USER tomcat从Dockerfile中删除时,一切正常。在设置入口点的权限时我缺少什么?

lar*_*sks 6

在这两个步骤中:

RUN chown root:root /usr/local/bin/entrypoint.sh
RUN chmod 4755 /usr/local/bin/entrypoint.sh
Run Code Online (Sandbox Code Playgroud)

您确保自己的entrypoint.sh脚本归拥有root,然后尝试设置该setuid位。不幸的是,第二步将无法进行:您无法将shell脚本(或实际上是任何解释性脚本)标记为setuid;该位将被忽略。参见例如这个问题

但是,如果这行得通,那么您将面临另一个问题:您的ENTRYPOINT脚本负责处理通过docker run命令行或通过CMDDockerfile中的指令传递到容器中的任何命令。如果setuid尝试成功,您的ENTRYPOINT脚本将以root身份运行...这意味着您最终catalina.sh run将以root身份运行,这意味着您的USER指令完全没有意义。

您可以通过简单地删除USER指令,使入口点以身份运行root,然后让您的ENTRYPOINT脚本CMDtomcat用户身份运行(例如,使用susudo)来到达同一位置:

FROM tomcat:8.5.23-jre8-alpine

#### OTHER IMAGE COMMANDS ####

COPY ./entrypoint.sh /usr/local/bin/entrypoint.sh
ENTRYPOINT ["sh", "/usr/local/bin/entrypoint.sh"]
CMD ["catalina.sh", "run"]
Run Code Online (Sandbox Code Playgroud)

entrypoint.sh

#!/bin/sh

# Do stuff as root here.
$JAVA_HOME/bin/keytool -import -alias ca_local \
  -keystore $JAVA_HOME/lib/security/cacerts 
  -storepass XXXXX -noprompt -trustcacerts \
  -file /usr/local/tomcat/certificates/ca-local.cer

# Now run everything else as a non-root user
exec su - tomcat -c "$*"
Run Code Online (Sandbox Code Playgroud)

这是用于处理初始设置任务的非常通用的机制,这些任务必须以root用户身份运行,而其他所有用户都必须以非root用户身份运行。

这里仍然存在许多问题:底层tomcat:8.5.23-jre8-alpine没有tomcat用户,并且其中的脚本/usr/local/tomcat/bin只能由执行root。因此,如果您希望该特定映像与非root用户一起使用,则可能首先需要进行一系列配置更改。

  • 许多镜像构建使用 [gosu](https://github.com/tianon/gosu) 而不是 `su` 或 `sudo` 来与 Docker 更加兼容 (2认同)