将ca证书添加到由指定用户运行的Tomcat Docker容器中



我有一个Docker卷直接安装到/usr/local/share/ca certificates-文件夹中。

certificate-folder:/usr/local/share/ca-certificates:ro

我使用Tomcat进行此设置,但其他框架也可能遇到类似的问题。Dockerfile的基础是这样的:

FROM       tomcat:8.5-jre8
# other Dockerfile configuration
CMD ["/start.sh"]

start.sh包含关键行

#!/usr/bin/env bash
update-ca-certificates 
# other startup related tasks
catalina.sh run

这个设置的问题是,只要我以root用户身份运行容器,它就可以工作。然而,如果我试图在Dockerfile的末尾用类似的东西更改为指定用户

ENV TOMCAT_USER="tomcat" 
TOMCAT_UID="8080" 
TOMCAT_GROUP="tomcat" 
TOMCAT_GID="8080"
RUN groupadd -r --gid $TOMCAT_GID $TOMCAT_GROUP && 
useradd -r --uid $TOMCAT_UID --gid $TOMCAT_GID $TOMCAT_USER
RUN chown -R $TOMCAT_USER:$TOMCAT_GROUP /usr/local/tomcat
USER $TOMCAT_USER

因此:

  • 因为shell脚本是以$TOMCAT_USER运行的,所以它无法运行"更新ca证书"来安装证书
  • 因为证书没有添加到Dockerfile中,所以更新ca证书不能在Dockerfile内运行

正因为如此,我最终会遇到像这样的SSL问题

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: 
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

那么,如果我仍然希望将容器作为指定的$TOMCAT_USER运行,那么处理此类问题的正确方法是什么呢?

由于update-ca-certificates需要root权限来更新/etc/ssl/certs中的证书,我只看到三种可能的方法(以及一种有效的解决方案——下面的第三种(:

  1. 从入口点删除update-ca-certificates,并在USER $TOMCAT_USER行之前添加一个RUN update-ca-certificates命令。(然而,您使用的卷在构建时不可用,因此这不起作用…(

  2. sudo权限(无密码(授予您的$TOMCAT_USER,并将update-ca-certificates替换为sudo update-ca-certificates。(然而,从安全角度来看,这种解决方案可能不令人满意…(

  3. 从Dockerfile中删除USER $TOMCAT_USER;保留CMD ["/start.sh"]ENTRYPOINT ["/start.sh"](如果您愿意(;并依赖gosu工具,其主要用例正是从root降级为非特权用户,同时享受比sudow.r.t.TTY和信号转发更好的行为。

    您只需要通过执行以下操作来安装gosu

    RUN apt-get update -y -q && 
    DEBIAN_FRONTEND=noninteractive 
    apt-get install -y -q --no-install-recommends gosu
    

    (因为tomcat:8.5-jre8是基于Debian的(,并通过编写来使用它

    start.sh

    #!/usr/bin/env bash
    update-ca-certificates 
    # other startup related tasks
    exec gosu $TOMCAT_UID:$TOMCAT_GID catalina.sh run
    

最新更新