如何为FIPS配置openjdk和简单的postgres连接示例



我有一个简单的Java应用程序在openjdk Docker容器中运行,该容器在启用FIPS的主机系统上执行(在Kubernetes集群上,所有节点都启用了FIPS(。

我正在运行一个kubectl apply -f simple-java-deployment.yaml,将其作为Kubernetes pod/部署添加到运行PostGres数据库的命名空间中。

我的简单示例/pod一开始很好,但当我查看日志时,它无法连接到Postgresql。

当我在容器内执行并运行命令以获得Java版本时,我会看到:当我在一个java服务pod(连接到postgres(内执行时:

$ java --version
openjdk 11.0.14 2022-01-18 LTS
OpenJDK Runtime Environment 18.9 (build 11.0.14+9-LTS)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.14+9-LTS, mixed mode, sharing)

kubernetes pod日志中的错误是一个长堆栈跟踪;由";

Caused by: java.lang.RuntimeException: Platform error: unsupported key for HMAC algorithm

我正在使用以下jdbc驱动程序:postgresql-42.3.3.jar

我的postgres版本符合FIPS:12.7

在启用FIPS的Kubernetes集群中,我能够执行到一个pod中,并运行一个";psql";命令连接到postgresql数据库。这向我证明了postges可以在启用FIPS的主机环境中接受连接。

我在一个postgres论坛上发帖,那里的专家建议Java生态系统中有一些配置不正确的地方。我不是一个Java开发人员(只是涉猎一下(。我在DevOps工作,使用这个简单的例子来计算细节,因为我们的大型应用程序在部署到启用FIPS的主机时也有同样的问题。

有没有Java专家可以指导我如何配置Java/JVM环境,使这个简单的代码示例能够工作?

这是我的简单代码(注意:我有一个无限循环,试图模拟一个等待请求的http服务——我只是在想停止Kubernetes部署时删除它(。还要注意的是,我使用的是当我成功地从一个pod连接到postgres时使用的相同的纯文本用户名/密码;psql";(psql-h postgresql app-p 5432-d app-U application_user(

package com.example.postgresqljdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.concurrent.TimeUnit;
public class PostgreSQLJDBC {
private final String url = "jdbc:postgresql://postgresql-app:5432/app";
private final String user = "application_user";
private final String password = "eb993cac-ee92-4df1-8429-a7a168a0ed21";
public Connection connect()  {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
System.out.println("Connected to the PostgreSQL server successfully");
}
catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace(System.out);
}
return conn;
}
public static void main(String[] args)  {
PostgreSQLJDBC app = new PostgreSQLJDBC();
int idx = 1;
System.out.println("About to try connecting to postreSQL database ...");
Connection db_con = app.connect();
if (db_con == null) {
System.out.println("Unable to connect to the database ... check the logs for the exception message");
}
else {
System.out.println("Successfully connected to the database!!  Try running a query");
}
System.out.println("Inside main - about to enter a long loop");
while (true) {
System.out.printf("Looping a set number of times ... Loop Iteration:  %d%n", idx);
idx++;
try {
TimeUnit.SECONDS.sleep(5);
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}

我遇到了这个问题,因为Openshift集群上的一个基于Red Hat UBI-8的java容器连接到集群外的postgres服务器。

我"已解决";通过JVM系统属性CCD_ 2禁用容器/pod中JVM上的FIPS。这可以通过在启动JVM时添加-Dcom.redhat.fips=false来设置(例如,通过容器映像的入口点(:

java -Dcom.redhat.fips=false -jar test.jar

或者例如通过将环境变量JDK_JAVA_OPTIONS设置为-Dcom.redhat.fips=false

export JDK_JAVA_OPTIONS='-Dcom.redhat.fips=false'

或者通过在kubernetes清单上设置这个环境变量(例如,直接在部署pod规范中,通过configmap或其他方式(。

还有其他方法可以禁用FIPS——一种方法是在kubernetes集群中的主机上禁用它。

如果禁用FIPS不是一个选项(例如,由于合规性(,我没有其他解决方案,只能在启用FIPS的RHEL8虚拟机上运行启用调试的java代码,以在postgres驱动程序中找到故障的确切位置,并从那里进行故障排除。

一些有用的参考资料——有些可能需要红帽子订阅:(

  • https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening#switching-系统到文件模式的加密策略
  • https://access.redhat.com/articles/3642912
  • https://access.redhat.com/articles/5895481

对于其他面临此问题的人,请在Bug 2007331(适用于Java 17(中找到详细信息,以及此问题是否已经修复和交付。

提前测试修复:

  1. 定位nss.fips.cfg
    # For Java 8
    java_version='1.8.0'
    # For Java 11
    java_version='11'
    # For Java 17
    java_version='17'
    rpm -ql java-${java_version}-openjdk-headless | grep nss.fips.cfg
    
  2. 如果不存在,请在末尾添加以下行:
    attributes(*,CKO_SECRET_KEY,CKK_GENERIC_SECRET)={ CKA_SIGN=true }