【问题标题】:Kubernate Pod : How to import Certificate into Java Truststore?Kubernetes Pod:如何将证书导入 Java 信任库?
【发布时间】:2021-08-28 16:37:24
【问题描述】:

所以在我的环境中,我使用的是 Docker 和 Kubernetes,现在我必须在 Pods Java Keystore 中导入证书。 但是我的容器以NON-ROOT 用户身份运行。当我尝试将证书导入 Java Keystore 时,它​​无法访问 Java Keystore 用户只能是 root 用户。

keytool -importcert -alias keycloakTest -keystore $JAVA_HOME/lib/security/cacerts -file $WSO2_SERVER_HOME/keycloak.crt -storepass changeit -noprompt

现在如何将证书导入 Java 信任库?目前我正在手动执行此操作,但后来我必须通过 DockerFile 执行此操作

COPY /carFiles/keycloak.crt  $WSO2_SERVER_HOME/
CMD keytool -importcert -alias keycloakTest -keystore $JAVA_HOME/lib/security/cacerts -file $WSO2_SERVER_HOME/keycloak.crt -storepass changeit -noprompt

在 Kubernetes Pods 中,Java 仅作为 root 用户运行?

编辑

我在 Docker 文件中进行了类似的更改

COPY /carFiles/keycloak.crt /opt
CMD keytool -importcert -alias keycloakTest -keystore $JAVA_HOME/lib/security/cacerts -file /opt/keycloak.crt -storepass changeit -noprompt

所以从 Pods Shell 我可以看到证书已复制到 /opt 目录,但接下来的 CMD 命令将无法将证书添加到 java 的信任库中

输入密钥,否则您将在 101 分钟后随时退出。

spec:
      volumes:
        - name: certs
          emptyDir: {}
      initContainers:
        - name: {{ .Chart.Name }}-create-keystore-truststore
          securityContext:
            runAsNonRoot: true
            runAsUser: 100
          image: >-
            <HOST>/foapi-tools:20.0.1

 command:
            - sh
            - '-c'
            - >
             # Import Keycloak server certificate into truststore

              # Extract host name from ckey URL

              KEYCLOAK_HOST=$(echo
              "https://<HOST>/auth" | sed
              's|[^/]*//\([^/]*\)/.*|\1|')

              echo "Importing server cert of '${KEYCLOAK_HOST}'..."

              openssl s_client -connect ${KEYCLOAK_HOST}:443 2>/dev/null
              </dev/null | openssl x509 > keycloak.crt

              ls -lat /certs/truststore;
          workingDir: /certs/truststore
          resources:
            limits:
              cpu: 200m
              memory: 200Mi
            requests:
              cpu: 200m
              memory: 100Mi
          volumeMounts:
            - name: certs
              mountPath: /certs/truststore
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent

【问题讨论】:

  • 据我了解,您在容器初始化期间获得了 Keycloak 的公共证书,并试图将其添加到 Java 的cacerts。如果要访问/opt路径,执行Keytool命令的用户需要sudo权限。
  • 但是在 WSO2 中会有一个用户,但不是 root 用户。
  • 我可以知道,您使用的是哪个 WSO2 产品,以及为什么您尝试将 Keycloak 证书导入cacerts(没有合作的 WSO2 密钥库)?
  • 我正在使用/wso2/wso2mi:4.0.0,所以我们的产品建立在 WSO2 之上,所以我们将在下载 WSO2 图像后更新一些 jar 和 car 文件,然后重新创建图像。现在从这个修改后的产品中我们调用 SOAP当我们运行我们的 API 时,API 将获取 keycloak 令牌。
  • 是的,没错。如果 WSO2 MI 是唯一要从容器执行通信的应用程序,那么您可以直接将 Keycloak 的证书导入 MI 的client-truststore.jks。关注这些12 了解更多信息。

标签: java docker security kubernetes


【解决方案1】:

根据共享信息,您正在使用 WSO2 MI 并尝试使用 Keycloak 从中介序列生成令牌。在这种情况下,不需要将 Keycloak 的证书添加到 JDK 的cacerts。您可以使用 WSO2 MI 的client-truststore.jks 来导入证书。

要访问/opt 路径,用户需要root 权限。由于 WSO2 MI 本身包含一个信任库,并且不需要任何 root 权限来导入证书,您可以简单地在其中导入 Keycloak 的 TLS 公共证书。给定的是一个示例Dockerfile 来导入证书

COPY /carFiles/keycloak.crt $WSO2_SERVER_HOME/repository/resources/security/
RUN keytool -importcert -alias keycloakTest -keystore $WSO2_SERVER_HOME/repository/resources/security/client-truststore.jks -file $WSO2_SERVER_HOME/repository/resources/security/keycloak.crt -storepass changeit -noprompt

注意:将CMD 替换为RUN 命令,因为您正在尝试将证书导入到信任库作为构建映像的一部分。并且不将该命令设置为启动容器的入口点。

此外,如果您有验证者链,则必须在信任库中包含所有(根证书、中间证书和叶证书)。仅导入其中一个将再次导致 SSL 握手错误。

【讨论】:

  • 失败并出现错误keytool error: java.io.IOException: Keystore was tampered with, or password was incorrect The command '/bin/sh -c keytool -importcert -alias keycloakTesting -keystore $WSO2_SERVER_HOME/repository/resources/security/client-truststore.jks -file $WSO2_SERVER_HOME/repository/resources/security/keycloak.cer -storepass changeit -noprompt' returned a non-zero code: 1
  • 您输入的Keystore密码错误。在命令中,您使用了changeit 作为密码。您必须将其更改为密钥库的实际密码,然后重试
  • 但它是 Mi 密钥库的默认密码。
  • ok 密码在这种情况下是wso2carbon
  • 是的,client-truststore.jks 的默认密码是wso2carbon
【解决方案2】:

这取决于您的容器,或者更具体地说,取决于 jks 文件的文件权限。该文件是您的图像的一部分,并且可能归 uid 0 和模式 660 或其他东西所有,因此需要更改某些内容才能使其正常工作。在构建时执行此操作或更改文件的所有权/模式或使用不同的 jks 文件。

【讨论】:

  • 您的意思是应该在DockerFiledeployment.yaml 中完成。在这个文件中,如果是,我必须添加用户或文件权限?
  • 一般在Dockerfile中。但是您可以通过要求 cert-manager 以 JKS 格式生成内容(或使用 init 容器来转换内容)并使用 -Djavax.net.ssl.trustStore=/path/to/your.jks 系统参数来纯粹在运行时执行此操作。
  • 请查看已编辑的问题,我仅在 init 容器中从另一台服务器下载证书,让我在问题中也添加它
猜你喜欢
  • 1970-01-01
  • 2016-12-22
  • 2013-01-07
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 2019-02-26
  • 2017-01-10
相关资源
最近更新 更多