如何在 Docker 容器中向 Tomcat 添加 SSL 证书?

Posted

技术标签:

【中文标题】如何在 Docker 容器中向 Tomcat 添加 SSL 证书?【英文标题】:How to add SSL certificates to Tomcat in Docker container? 【发布时间】:2018-04-06 00:41:13 【问题描述】:

我是 Docker 新手,正在努力学习它。我在 Windows 7 上使用 Docker 快速启动终端。 我有一个简单的要求,我在 Docker 容器中使用 Tomcat。我的 DockerFile 如下:

FROM tomcat:8.0.47-jre7
RUN cd /usr/local/tomcat/webapps
COPY test.war /usr/local/tomcat/webapps/test.war

然后我在 Docker 控制台中发出简单的构建和运行命令。

test.war 是一个 Java 网络服务。此 Web 服务使用 HTTPS 在内部调用远程主机上的其他 Web 服务。 我有远程主机的证书。

我尝试了互联网上可用的几种方法来将这些证书导入或复制到不同的位置,如不同论坛/博客中提到的那样,但徒劳无功。每当我使用 HTTPS 从 test.war 调用外部 Web 服务时,都会出现 SSL 握手错误。

我还有一个 Java 密钥库。我也尝试在我的 Docker 文件中使用 Java,并尝试使用密钥库,但同样徒劳无功。

当我在直接安装在我机器上的 tomcat 上使用相同的 test.war 时,它工作得非常好。

有人可以通过提供在这种情况下能够导入/使用 SSL 证书/密钥库的步骤来帮助我吗?另外,如何导入多个证书?

【问题讨论】:

您按照哪些步骤导入证书? 根据您的描述,您需要将证书添加到信任库(不要与密钥库混淆)。根据您用于拨打电话的技术,有不同的方法可以做到这一点。例如,对于 Spring Boot,它可能是这样的 ***.com/a/43235569/2065796 您还可以使用受信任的证书等更新容器内的 jvm。提供有关您如何拨打电话的更多详细信息,以便我们能够为您提供帮助。 与您的问题无关的评论,但您可以/应该使用WORKDIR /usr/local/tomcat/webapps 代替RUN cd /usr/local/tomcat/webapps 以使其更轻量级和最佳实践友好:) @Rao,我尝试了以下方法: FROM registry.access.redhat.com/rhel7.1 ENV JAVA_HOME=/usr/lib/jvm/jre COPY ./certs/My_Root_CA.cer / etc/ssl/certs/ COPY ./certs/My_Issuing_CA.cer /etc/ssl/certs/ RUN $JAVA_HOME/bin/keytool -storepasswd -new mysecretpassword -keystore $JAVA_HOME/lib/security/cacerts -storepass changeit ... @Rao,还尝试了以下操作: ADD your_ca_root.crt /usr/local/share/ca-certificates/foo.crt RUN update-ca-certificates 以下位置提供的步骤:docs.docker.com/engine/security/https/… docs.docker.com/engine/security/https/#secure-by-default 【参考方案1】:

=> 在 Docker 位置的情况下使用 classpath:/some/location/cerkey.jks 来引用 docker 实例。

=> 在主机位置的情况下使用file:/some/location/cerkey.jks,docker 正在运行。

提示:server.ssl.key-store 的值

【讨论】:

【参考方案2】:

您可以尝试将证书导入 docker 内的 jvm 可信存储中。

我有远程主机的证书。

您可以使用这些证书,但实际上您不需要它们,您只需要颁发证书的机构的根证书。你可以从网上下载。

通常它们以pem 格式给出,但你需要der 用于jvm。

首先你需要转换证书:

openssl x509 -in ca.pem -inform pem -out ca.der -outform der

然后将其安装到 jvm 密钥库中:

keytool -importcert -alias startssl -keystore \
    $JAVA_HOME/lib/security/cacerts -storepass changeit -file ca.der 

此命令询问您是否真的要添加证书,您应该输入“是”。

大家一起Dockerfile

FROM tomcat:8.0.47-jre7

COPY ca.pem ca.pem

RUN openssl x509 -in ca.pem -inform pem -out ca.der -outform der

RUN echo yes | keytool -importcert -alias startssl -keystore \
    /docker-java-home/jre/lib/security/cacerts -storepass changeit -file ca.der 

COPY test.war /usr/local/tomcat/webapps/test.war

WORKDIR /usr/local/tomcat/webapps

注意:如果您已经有der格式的证书,则不需要openssl调用,直接复制证书即可。

要验证证书是否真的被应用,你可以运行容器,ssh 进入它

$ docker exec -it <CONTAINER-ID> bash

并检查密钥库:

$ keytool -keystore "/docker-java-home/jre/lib/security/cacerts" -storepass changeit -list | grep <NAME-OF-YOUR-CERT-AUTHORITY>

【讨论】:

非常感谢 Oleksandr、Rao 和 Samprog,它成功了 ** 你不需要 DER; keytool(更确切地说是CertificateFactory)至少从 2008 年的 j6 起就能够读取 PEM 证书,尽管 PEM 与无关文本(如“cmets”OpenSSL 经常放置)直到 2012 年的 j7。FWIW 你也可以避免echo yes |-noprompt【参考方案3】:

For Java apps in RHEL/Centos images, you can use update-ca-trust,它将为您更新您的信任存储,从您放置到/etc/pki/ca-trust 中的文件。它还直接接受.pem 文件:

FROM ...

USER root
COPY yourcertificate.pem /etc/pki/ca-trust/source/anchors/yourcertificate.pem
RUN update-ca-trust

这将自动为您更新/etc/pki/java/cacerts,以便Java 信任新证书。

或者,如果您的证书托管在网络服务器上,那么您可以使用 curl 下载它而不是复制文件 - 例如:

RUN curl -k https://badssl.com/certs/ca-untrusted-root.crt -o /etc/pki/ca-trust/source/anchors/ca-untrusted-root.crt && \
    update-ca-trust

【讨论】:

以上是关于如何在 Docker 容器中向 Tomcat 添加 SSL 证书?的主要内容,如果未能解决你的问题,请参考以下文章

docker添加tomcat容器成功无法访问首页

docker添加tomcat容器成功无法访问首页

如何获取在docker容器中运行的tomcat的CPU使用率[关闭]

在 extjs 中向容器添加 iframe

如何设置Docker容器中Java应用的内存限制

如何在 PrimeNG 中向手风琴添加滚动条?