0

在我的团队中,我们正在尝试在 OpenShift (4.2) 上部署基于 JHipster (6.8.0) 的微服务堆栈。

我们目前在网关启动并尝试通过 HTTPS 与 Keycloak 通信时遇到问题(准确地说,使用基于 Keycloak 的 Red Hat Single Sign On 7.3)。

这是引发的异常:

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

我们认为这是因为我们的网关不信任来自 Keycloak 的证书。确实,这是使用组织证书。我们已经登录到网关尝试连接的领域的 Keycloak 管理界面。我们已将证书提取为 X.509 二进制编码的 DER 文件;感谢 Chrome 浏览器功能。

我们首先尝试简单地将这些证书添加到etc/ssl/certs/java/cacerts网关容器的文件夹中。为此,我们在项目 jib 存储库中创建了这些文件夹src/main/jib/etc/ssl/certs/java/cacerts,并将证书复制到其中。

我们已经使用 Maven 和jib:dockerBuild选项生成了网关 Docker 映像。我们将它推送到我们的 Docker 注册表并将其部署到 OpenShift。检查 OpenShift pod 后,证书已在etc/ssl/certs/java/cacerts. 但是我们仍然得到与以前相同的错误。

然后我们尝试使用信任库。因此,我们使用以下命令为每个证书创建了一个:

keytool -import -file path/to/certificate.cer -alias certificateAlias -keystore applicationTrustStore.jks

由于以下命令,我们检查了所有证书是否已正确添加:

keytool -list -v -keystore applicationTrustStore.jks

然后我们将此 applicationTrustStore.jks 文件添加到 src/main/jib/etc/ssl/certs/java/cacerts我们项目的文件夹中,并将其添加到 pom.xml 中:

<plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>${jib-maven-plugin.version}</version>
    <configuration>
        <from>
            <image>adoptopenjdk:11-jre-hotspot</image>
        </from>
        <to>
            <image>application:latest</image>
        </to>
        <container>
            …
            <jvmFlags>
                <jvmFlag>-Djavax.net.ssl.trustStore=etc/ssl/certs/java/cacerts/applicationTrustStore.jks</jvmFlag>
                <jvmFlag>-Djavax.net.ssl.trustStoreType=jks</jvmFlag>
                <jvmFlag>-Djavax.net.ssl.trustStorePassword=password</jvmFlag>
            </jvmFlags>
        </container>
        …
    </configuration>
</plugin>

再一次,我们生成并重新部署到 OpenShift,但没有成功;仍然是完全相同的问题。

我们当然遗漏了一些明显的东西,但我们不能指望它。

4

3 回答 3

1

默认情况下,JREadoptopenjdk:11-jre-hotspot从不读取/etc/ssl/certs/java/cacerts。大多数 JRE 实际上默认读取<JRE>/lib/security/cacerts(除非您设置-Djavax.net.ssl.trustStore)。

只是在许多 Linux 发行版上,通常<JRE>/lib/security/cacerts是指向/etc/ssl/certs/java/cacerts. 例如,

# ls -l /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts
lrwxrwxrwx    1 root     root            27 Jan  1  1970 /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/cacerts -> /etc/ssl/certs/java/cacerts

在这种情况下,随意放置cacerts/etc/ssl/certs/java可以了。但是, in adoptopenjdk:11-jre-hotspot<JRE>/lib/security/cacerts不是符号链接,如下所示:

# ls -l /opt/java/openjdk/lib/security/cacerts 
-rw-r--r-- 1 root root 101001 Jul 15 09:07 /opt/java/openjdk/lib/security/cacerts

正如@deduper 解释的那样,我会将文件放入/opt/java/openjdk/lib/security/.

如果您想设置-Djavax.net.ssl.trustStore指定不同的位置,我认为路径应该是@deduper 指出的绝对路径。

于 2020-10-12T16:37:44.143 回答
1
于 2020-10-11T01:16:30.707 回答
0

感谢@deduper 和@Chanseok 的帮助哦,我能够解决这个问题。

如果一些 JHipster/Openshift 用户在这里走动,很少有解释。

首先,我尝试使用 keytool 命令在/opt/java/openjdk/lib/security/cacerts中导入组织证书。所以我在 src/main/jib 文件夹中创建 tmp/cert 子文件夹,将组织证书放入其中并像这样更新 src/main/jib/entrypoint.sh 文件:

#!/bin/sh

echo "The application will start in ${JHIPSTER_SLEEP}s..." && sleep ${JHIPSTER_SLEEP}
exec keytool -noprompt -import -alias alias -storepass changeit -keystore /opt/java/openjdk/lib/security/cacerts -file /tmp/cert/organization.cer

exec java ${JAVA_OPTS} -noverify -XX:+AlwaysPreTouch -Djava.security.egd=file:/dev/./urandom -cp /app/resources/:/app/classes/:/app/libs/* "com.your.company.App"  "$@"

它似乎在本地工作,但是在 Openshift 上启动它时,我在调用 keytool 时收到了Permission denied,因为默认情况下 Openshift 不使用 root 用户。所以,我终于删除了我的修改,回到原来的 entrypoint.sh 文件

我使用的解决方法是:

  • 从采用openjdk:11-jre-hotspot中提取cacerts文件(使用 docker cp 命令,更多信息:将文件从 Docker 容器复制到主机
  • 在我的工作站上使用 keytool 命令在cacerts中添加证书
  • 在 src/main/jib 中创建这些子文件夹:opt/java/openjdk/lib/security
  • 复制cacerts文件里面

使用 jib 创建 Docker 映像时,opt/java/openjdk/lib/security 中的cacerts包含您的组织证书,并且在 Openshift 上启动时,与 Keycloak 的通信正常。

于 2020-10-13T16:10:47.600 回答