简体   繁体   English

如何将SSL证书添加到Docker容器中的Tomcat?

[英]How to add SSL certificates to Tomcat in Docker container?

I'm new to Docker and trying to learn it.我是 Docker 的新手,正在尝试学习它。 I'm using Docker Quickstart Terminal on Windows 7. I've a simple requirement where I'm using Tomcat in a Docker container.我在 Windows 上使用 Docker 快速启动终端 7. 我有一个简单的要求,我在 Docker 容器中使用 Tomcat。 My DockerFile is as following:我的 DockerFile 如下:

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

Then I issue simple build and run commands in the Docker console.然后,我在 Docker 控制台中发出简单的构建和运行命令。

test.war is a Java web-service. test.war 是一个 Java 网络服务。 This web-service internally calls other web-services on remote hosts using HTTPS. I've the certs for the remote hosts.此 Web 服务在内部使用 HTTPS 调用远程主机上的其他 web-services。我有远程主机的证书。

I tried several ways available on the inte.net to import or copy those certs to different locations as mentioned on different forums/blogs, but in vain.我尝试了 inte.net 上可用的几种方法来将这些证书导入或复制到不同论坛/博客上提到的不同位置,但没有成功。 Whenever I use HTTPS to call the external web-service from test.war, it gives me SSL Handshake error.每当我使用 HTTPS 从 test.war 调用外部网络服务时,它都会给我 SSL 握手错误。

I also have a Java keystore.我还有一个 Java 密钥库。 I tried to use Java also in my Docker file and tried to use the keystore, but again, in vain.我也尝试在我的 Docker 文件中使用 Java 并尝试使用密钥库,但再次失败。

When I use the same test.war on the tomcat installed directly on my machine, it works absolutely fine.当我在直接安装在我机器上的 tomcat 上使用相同的 test.war 时,它工作得非常好。

Can someone help me by providing the steps to be able to import/use SSL certs/keystore in this scenario.有人可以通过提供能够在这种情况下导入/使用 SSL 证书/密钥库的步骤来帮助我。 Also, how can I import more than one certs?另外,如何导入多个证书?

You can try importing the certificate into jvm trusted store inside docker.您可以尝试将证书导入 docker 内的 jvm 可信存储。

I've the certs for the remote hosts.我有远程主机的证书。

You can use these certificates but in fact you don't need them, you only need the root certificate of the authority that issued the certificates.您可以使用这些证书,但实际上您不需要它们,您只需要颁发证书的机构的根证书。 You can download it from the internet.您可以从互联网上下载它。

Usually they are given in pem format, but you'll need der for jvm.通常它们以pem格式给出,但是对于 jvm,您需要der

First you need to convert the certificate:首先你需要转换证书:

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

Then install it into jvm keystore:然后将其安装到 jvm 密钥库中:

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

This command asks if you really want to add the certificate, you shoudl type "yes".此命令询问您是否真的要添加证书,您应该输入“是”。

And all together in a Dockerfile :全部放在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

Note: if you already have certificate in der format you don't need openssl call, just copy the certificate directly.注意:如果您已经有der格式的证书,则不需要openssl调用,直接复制证书即可。

To verify that the certificate is really applied you can run the container, ssh into it要验证证书是否真的被应用,您可以运行容器,通过 ssh 进入它

$ docker exec -it <CONTAINER-ID> bash

and check the keystore:并检查密钥库:

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

For Java apps in RHEL/Centos images, you can use update-ca-trust , which will update your trust stores for you, from files you place into /etc/pki/ca-trust . 对于 RHEL/Centos 映像中的 Java 应用程序,您可以使用update-ca-trust ,它将从您放入/etc/pki/ca-trust文件中为您更新您的信任存储。 It also accepts .pem files directly:它还直接接受.pem文件:

FROM ...

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

This will update /etc/pki/java/cacerts for you automatically, so that Java will trust the new certificate.这将自动为您更新/etc/pki/java/cacerts ,以便 Java 信任新证书。

Or, if your cert is hosted on a web server, then you can use curl to download it instead of copying the file - for example:或者,如果您的证书托管在 Web 服务器上,那么您可以使用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

=> Use classpath:/some/location/cerkey.jks in case of Docker location, to refer the docker instance. => 在 Docker 位置的情况下使用classpath:/some/location/cerkey.jks来引用classpath:/some/location/cerkey.jks实例。

=> Use file:/some/location/cerkey.jks in case of host location, where the docker is running. => 使用file:/some/location/cerkey.jks在主机位置的情况下,泊坞窗正在运行。

Hint: Value of server.ssl.key-store提示:server.ssl.key-store 的值

Building on Sasha Shpota's answer , we can do the same using Docker Compose (without needing to create a new image):基于Sasha Shpota 的回答,我们可以使用 Docker Compose 做同样的事情(无需创建新图像):

service:
  image: tomcat:9.0.62-jdk17
  volumes:
    - ./myapp.war:/usr/local/tomcat/webapps/myapp.war
    - /path/to/public.pem:/tmp/public.pem
  command: bash -c "keytool -importcert -alias startssl -keystore /usr/local/openjdk-17/lib/security/cacerts -storepass changeit -file /tmp/public.pem -noprompt && catalina.sh run"

The disadvantage is that one has to add the certificate every time the container is recreated.缺点是每次重新创建容器时都必须添加证书。 On the other hand, the certificate can be changed without having to rebuild the image.另一方面,无需重建映像即可更改证书。 Useful for development.对开发有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM