'How to configure openjdk for FIPS and simple postgres connection example
I have a simple Java application running in an openjdk Docker container that is executing on a FIPS enabled host system (on a Kubernetes cluster where all nodes have FIPS enabled).
I am running a kubectl apply -f simple-java-deployment.yaml
to add this as a Kubernetes pod/deployment to a namespace where a PostGres database is running.
My simple example/pod starts fine but when I look in the logs, it is failing to connect to Postgresql.
When I exec inside the container and run the command to get the Java version, I see: When I exec inside one of the java services pod (that connects to 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)
The error in the kubernetes pod logs is a long stack trace with this "Caused by"
Caused by: java.lang.RuntimeException: Platform error: unsupported key for HMAC algorithm
I am using the following jdbc driver: postgresql-42.3.3.jar
and my version of postgres is FIPS compliant: 12.7
In the FIPS enabled Kubernetes cluster, I am able to exec into a pod and run a "psql" command to connect to the postgresql database. This proves to me that postges can accept connections in a FIPS enabled host environment.
I have posted in a postgres forum and the experts there are suggesting there is something in the Java ecosystem that is not configured correctly. I am not a Java developer per say (just dabble in it). I work in DevOps and am using this simple example to work out the details because our larger application is having the same issue when deploying to FIPS enabled hosts.
Are there Java experts out there who can point me to how I can configure my Java/JVM environment such that this simple code example can work?
Here is my simple code (Note: I have an infinite loop trying to simulate an http service waiting for requests - I just delete the Kubernetes deployment when I want to stop it). Also note that I am using the same plain text username/password that works when I successfully connect from one pod to postgres using "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());
}
}
}
}
Solution 1:[1]
I had this exact problem, from a Red Hat UBI-8-based java container on an Openshift cluster connecting to a postgres-server outside of the cluster.
I "solved" it by disabling FIPS on the JVM in the container/pod via the JVM system property com.redhat.fips=false
. This can either be set by adding -Dcom.redhat.fips=false
when starting the JVM (e.g. via the container-image's entrypoint):
java -Dcom.redhat.fips=false -jar test.jar
or by setting the environment variable JDK_JAVA_OPTIONS
to -Dcom.redhat.fips=false
for example via
export JDK_JAVA_OPTIONS='-Dcom.redhat.fips=false'
or by setting this environment variable on your kubernetes manifests (e.g. directly in your deployment pod-specs, via configmaps, or by other means).
There are other ways to disable FIPS -- one way is to disable it on the hosts in your kubernetes cluster.
If disabling FIPS is not an option (e.g. due to compliance), I have no solution other than to run you java code with debugging enabled on a FIPS-enabled RHEL8 VM to locate the exact place in the postgres-driver where things fail and troubleshoot from there.
Some useful references -- some might require a red hat subscription :(
- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening#switching-the-system-to-fips-mode_using-the-system-wide-cryptographic-policies
- https://access.redhat.com/articles/3642912
- https://access.redhat.com/articles/5895481
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |