Docker 入口点脚本根权限
Docker Entrypoint Script Root Permission
我有一个包含 3 个约束的 Dockerfile:
1.) 出于安全目的,Dockerfile 中的最终 USER 语句必须是 USER tomcat
(它基于 tomcat:8.5.23-jre8-alpine 图像构建)
2.) 它不能在 /root/
目录或 $JAVA_HOME
上 运行 chmod
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"]
我认为将文件的所有权赋予 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
我收到以下错误:
keytool error: java.io.FileNotFoundException: /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts (Permission denied)
似乎入口点实际上并不是 运行 root,正如 chown/chmod 暗示的那样。我知道我的所有文件都在正确的位置,因为当我从 Dockerfile 中删除 USER tomcat
时,一切正常。我在设置入口点权限时缺少什么?
在这两个步骤中:
RUN chown root:root /usr/local/bin/entrypoint.sh
RUN chmod 4755 /usr/local/bin/entrypoint.sh
您正在确保您的 entrypoint.sh
脚本归 root
所有,然后您试图设置 setuid
位。不幸的是,这第二步是行不通的:您不能将 shell 脚本(或实际上任何解释的脚本)标记为 setuid
;该位将被忽略。参见,例如 this question.
但是,如果这有效,您将遇到另一个问题:您的 ENTRYPOINT
脚本负责处理通过 docker run
命令行或 CMD
Dockerfile 中的指令。如果 setuid
尝试成功,您的 ENTRYPOINT
脚本将作为 root 运行ning...这意味着您最终将 运行ning catalina.sh run
作为 root,这意味着您的 USER
指令完全没有意义。
您可以通过简单地删除 USER
指令到达相同的位置,允许 运行 的入口点作为 root
,然后让您的 ENTRYPOINT
脚本 运行 CMD
作为 tomcat
用户(例如,使用 su
或 sudo
):
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"]
在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 "$*"
这是一种非常常见的处理初始设置任务的机制,这些任务必须 运行 作为 root 用户,而 运行 以非 root 用户身份执行其他所有操作。
这里还有很多问题:底层tomcat:8.5.23-jre8-alpine
没有tomcat
用户,/usr/local/tomcat/bin
中的脚本只能由[=14=执行].因此,如果您希望此特定图像与非 root 用户一起使用,您可能需要先进行大量配置更改。
我有一个包含 3 个约束的 Dockerfile:
1.) 出于安全目的,Dockerfile 中的最终 USER 语句必须是 USER tomcat
(它基于 tomcat:8.5.23-jre8-alpine 图像构建)
2.) 它不能在 /root/
目录或 $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"]
我认为将文件的所有权赋予 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
我收到以下错误:
keytool error: java.io.FileNotFoundException: /usr/lib/jvm/java-1.8-openjdk/jre/lib/security/cacerts (Permission denied)
似乎入口点实际上并不是 运行 root,正如 chown/chmod 暗示的那样。我知道我的所有文件都在正确的位置,因为当我从 Dockerfile 中删除 USER tomcat
时,一切正常。我在设置入口点权限时缺少什么?
在这两个步骤中:
RUN chown root:root /usr/local/bin/entrypoint.sh
RUN chmod 4755 /usr/local/bin/entrypoint.sh
您正在确保您的 entrypoint.sh
脚本归 root
所有,然后您试图设置 setuid
位。不幸的是,这第二步是行不通的:您不能将 shell 脚本(或实际上任何解释的脚本)标记为 setuid
;该位将被忽略。参见,例如 this question.
但是,如果这有效,您将遇到另一个问题:您的 ENTRYPOINT
脚本负责处理通过 docker run
命令行或 CMD
Dockerfile 中的指令。如果 setuid
尝试成功,您的 ENTRYPOINT
脚本将作为 root 运行ning...这意味着您最终将 运行ning catalina.sh run
作为 root,这意味着您的 USER
指令完全没有意义。
您可以通过简单地删除 USER
指令到达相同的位置,允许 运行 的入口点作为 root
,然后让您的 ENTRYPOINT
脚本 运行 CMD
作为 tomcat
用户(例如,使用 su
或 sudo
):
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"]
在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 "$*"
这是一种非常常见的处理初始设置任务的机制,这些任务必须 运行 作为 root 用户,而 运行 以非 root 用户身份执行其他所有操作。
这里还有很多问题:底层tomcat:8.5.23-jre8-alpine
没有tomcat
用户,/usr/local/tomcat/bin
中的脚本只能由[=14=执行].因此,如果您希望此特定图像与非 root 用户一起使用,您可能需要先进行大量配置更改。