Java 服务无法识别将自签名证书导入 Docker 的 JRE cacert
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/41497871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Importing self-signed cert into Docker's JRE cacert is not recognized by the service
提问by Zeigeist
- A Java Service is running inside the Docker container, which access the external HTTPS url and its self-sign certificate is unavailable to the service/ JRE cacert keystore and therefore connection fails.
- Hence imported the self-signed certificate of HTTPS external URL into Docker container's JRE cacert keystore. (after checking the
$JAVA_HOME
env. variable) - Restarted the Docker container (using
docker restart
command), hoping that the service is also get restarted and pick the changes from JRE cacert. But this didn't happen, the Java service still fails to access external HTTPS URL.
- Java 服务在 Docker 容器内运行,它访问外部 HTTPS url,其自签名证书对服务/JRE cacert 密钥库不可用,因此连接失败。
- 因此将 HTTPS 外部 URL 的自签名证书导入到 Docker 容器的 JRE cacert 密钥库中。(检查
$JAVA_HOME
env. 变量后) - 重新启动 Docker 容器(使用
docker restart
命令),希望服务也重新启动并从 JRE cacert 中选择更改。但这并没有发生,Java 服务仍然无法访问外部 HTTPS URL。
Any idea how a Java service running inside the Docker container pick the JRE cacert changes with new certificate import?
知道在 Docker 容器内运行的 Java 服务如何通过新证书导入来选择 JRE cacert 更改吗?
采纳答案by VonC
Hence imported the self-signed certificate of HTTPS external URL into Docker container's JRE cacert keystore.
因此将 HTTPS 外部 URL 的自签名证书导入到 Docker 容器的 JRE cacert 密钥库中。
No: you need to import it into the Docker imagefrom which you run your container.
否:您需要将其导入到运行容器的 Docker映像中。
Importing it into the container would only create a temporary writable data layer, which will be discarded when you restart your container.
将其导入容器只会创建一个临时的可写数据层,当您重新启动容器时,它将被丢弃。
Something like this answer:
像这样的答案:
USER root
COPY ldap.cer $JAVA_HOME/jre/lib/security
RUN \
cd $JAVA_HOME/jre/lib/security \
&& keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias ldapcert -file ldap.cer
回答by Volker Seibt
For using already configured java based containers like jenkins, sonarqubeor nexus(e. g. if you run your own build server) I find it more convenient to mount a suitable cacerts
-file into these containers with a parameter for docker run .
对于使用已经配置的基于 Java 的容器,如jenkins、sonarqube或nexus(例如,如果您运行自己的构建服务器),我发现将合适的cacerts
文件挂载到这些容器中并带有 docker run 参数更方便。
I use the cacerts
file from openjdkas base:
我使用cacerts
来自openjdk的文件作为基础:
- extracting
cacerts
from openjdkimage using a temporary container:
- 使用临时容器
cacerts
从openjdk图像中提取:
docker pull openjdk:latest
docker run --rm --entrypoint cat openjdk:latest /etc/ssl/certs/java/cacerts > cacerts
- adding certificate to the extracted
cacerts
using a temporary container started from the same folder which also containsldap.cer
:
cacerts
使用从同一文件夹启动的临时容器向提取的证书添加证书,该文件夹还包含ldap.cer
:
docker run --rm -v `pwd`:/tmp/certs openjdk:latest bash -c 'cd /tmp/certs && keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias buenting-root -file ldap.cer'
- run your target docker container(s) mounting the extracted
cacerts
with a run-parameter, e. g. forsonarqube
:
- 运行您的目标 docker 容器
cacerts
,使用运行参数安装提取的内容,例如sonarqube
:
docker run ... -v /path/to/your/prepared/cacerts:/etc/ssl/certs/java/cacerts:ro ... sonarqube:lts
If there is a new version of openjdkyou can update the cacerts
-file on the host with commands from 1. and 2.
如果有新版本的openjdk,您可以cacerts
使用 1. 和 2 中的命令更新主机上的 -file。
For updating the target image (e. g. sonarqube
) you do not need to create your own image using Dockerfile
and docker build
.
要更新目标图像(例如sonarqube
),您不需要使用Dockerfile
和创建自己的图像docker build
。
回答by povisenko
Here is my solution that worked for me within an image based on OpenJDK Java 11.
这是我在基于OpenJDK Java 11的图像中对我有用的解决方案。
The very first thing to mention that use can use either JDK image or JRE with required ca-certificates-java
installed for the second choice
首先要提到的是,使用可以使用 JDK 映像或 JRE 并ca-certificates-java
为第二选择安装所需
Here is the solution for JDK based image:
以下是基于 JDK 的映像的解决方案:
FROM openjdk:11-jdk-slim
WORKDIR /opt/workdir/
#.crt file in the same folder as your Dockerfile
ARG CERT="certificate.crt"
#import cert into java
COPY $CERT /opt/workdir/
RUN keytool -importcert -file $CERT -alias $CERT -cacerts -storepass changeit -noprompt
...
And here is JREbased image:
这是基于JRE的图像:
FROM openjdk:11-jre-slim
WORKDIR /opt/workdir/
#installing ca-certificates-java to import the certificate
RUN mkdir -p /usr/share/man/man1 \
&& apt-get update \
&& apt-get install -y ca-certificates-java
#.crt file in the same folder as your Dockerfile
ARG CERT="certificate.crt"
#import cert into java
COPY $CERT /opt/workdir/
RUN keytool -importcert -file $CERT -alias $CERT -cacerts -storepass changeit -noprompt
...