Deploying an Open Liberty application to OpenShift with FIPS enabled
In this post, we’ll show you how to run an Open Liberty application with Federal Information Processing Standards (FIPS) enabled and deploy it to an OpenShift cluster. First, let’s cover some key concepts about FIPS and running Open Liberty with FIPS enabled.
What is FIPS and why is it important?
Federal Information Processing Standards (FIPS) are standards and guidelines that are issued by the National Institute of Standards and Technology (NIST) for federal government computer systems. Federal agencies and other industries rely on cryptography to protect digital information (data at rest) and communications (data in motion). FIPS specifies the security requirements that a cryptographic module must satisfy to protect sensitive information. The FIPS certification process requires testing by a NIST-accredited lab and assures users that a specific technology can be used to secure sensitive information.
Because United States government agencies and other healthcare and financial firms use only products that support FIPS, it can be important to enable FIPS when you deploy an application to a Kubernetes cluster.
Considerations for enabling FIPS
-
Kubernetes cluster considerations
First, you need to decide whether to install your Kubernetes cluster in FIPS mode. In this post, we’ll use OpenShift 4.6. Starting in version 4.3, you can install an OpenShift cluster that uses FIPS Validated / Modules in Process cryptographic libraries. A FIPS-enabled Open Liberty image can be installed on a Kubernetes cluster that isn’t FIPS-enabled.
-
Open Liberty considerations
Open Liberty can run with any compliant Java runtime environment (JRE) or Java software development kit (SDK). When you enable FIPS, it is important to pick correct Java withs FIPS validated providers. In this post, we’ll use Open Liberty with the IBM JDK 8 with IBMJSSE2 FIPS provider. Open Liberty supports FIPS 140-2, SP800-131, and Suite B security standards. It is important to consider all the dependencies of your application on other software. It’s possible that your application could stop working after enabling FIPS if the other software that your application interacts with isn’t FIPS-compliant.
Enabling FIPS and deploying the application container image
Let’s explore the steps to enable FIPS for an Open Liberty application that’s running on a FIPS-enabled OpenShift cluster:
Creating an Open Liberty application container image that has FIPS enabled
First, create an Open Liberty application container image.
To enable FIPS for Open Liberty, we’re using the Open Liberty image that uses the IBM JDK 8.
You also need to ensure that Transport Layer Security (TLS) is enabled for your Open Liberty server by adding the Transport Security feature (transportSecurity-1.0
) to your server.xml
file.
Set the correct property to enable FIPS mode for the IBMJSSE2 provider.
For FIPS140-2, set the -Dcom.ibm.jsse2.usefipsprovider
property to true
.
We also need to set the com.ibm.jsse2.usefipsProviderName
property to specify the correct FIPS provider.
In this example, we’ll set this property to IBMJCEPlusFIPS
.
To set these system properties, create or update the jvm.options
file:
$ cat jvm.options -Dcom.ibm.jsse2.usefipsprovider=true -Dcom.ibm.jsse2.usefipsProviderName=IBMJCEPlusFIPS
Next, add the Java Cryptography Extension (JCE) FIPS provider in the java.security
file, which is located in the JAVA_HOME/jre/lib/security
directory.
You can extract the java.security
file from the Open Liberty running pod by running the following command:
$ docker cp <container>:/opt/ibm/java/jre/lib/security/java.security .
By default, the java.security
file doesn’t include a FIPS provider.
After you extract the java.security
file, add the FIPS provider and adjust the provider number in the file.
This example uses the com.ibm.crypto.plus.provider.IBMJCEPlusFIPS
FIPS provider:
$ vi java.security # List of providers and their preference orders (see above): #Added the security.provider.1=com.ibm.crypto.plus.provider.IBMJCEPlusFIPS security.provider.1=com.ibm.crypto.plus.provider.IBMJCEPlusFIPS security.provider.2=com.ibm.jsse2.IBMJSSEProvider2 security.provider.3=com.ibm.crypto.provider.IBMJCE ...
Next, update the Dockerfile with updated server.xml
, jvm.options
, and java.security
files, as shown in the following example Dockerfile:
FROM openliberty/open-liberty:21.0.0.1-full-java8-ibmjava-ubi COPY --chown=1001:0 server.xml /config/ COPY --chown=1001:0 jvm.options /config/ COPY --chown=1001:0 <app> /config/apps COPY --chown=1001:0 java.security /opt/ibm/java/jre/lib/security RUN configure.sh
Now you can build the application image:
$ docker build -t <image_name> -f Dockerfile .
If you want, you can verify the application container image that you created to make sure that the correct FIPS provider is being used.
To verify the image, enable JSSE trace by using the -Djavax.net.debug=all
property:
$ docker run -e JVM_ARGS=-Djavax.net.debug=all -p 9443:443 <image_name> ... ******************************************************************************** product = Open Liberty 21.0.0.1 (wlp-1.0.48.cl210120210113-1459) ... IBMJSSE2 will use FIPS provider IBMJCEPlusFIPS Installed Providers = IBMJCEPlusFIPS IBMJSSE2 IBMJCE ...
Finally, log in to your image registry and push the image. In this example, we’re using the OpenShift internal registry:
$ docker login <registry> $ docker tag <image_name> default-route-openshift-image-registry.apps.example.ibm.com/ol-app/<image_name> $ docker push default-route-openshift-image-registry.apps.example.ibm.com/ol-app/<image_name>
Deploying the Open Liberty image to your OpenShift Cluster
Start off by deploying an OpenShift cluster.
Then, install the Open Liberty Operator if it’s not already installed.
Next, log in to your OpenShift cluster with the oc login
command, and create a project for your Open Liberty application:
$ oc new-project ol-app
Create an OpenLibertyApplication custom resource (CR) to deploy your application.
It’s important that route for the application is enabled so that TLS can use FIPS.
The following example file shows how you might configure the Open Liberty Operator for deployment to an OpenShift cluster.
Make sure to replace <image_name>
with the name of your image:
$ cat app-deploy.yaml apiVersion: openliberty.io/v1beta1 kind: OpenLibertyApplication metadata: name: inventory-ibmjdk spec: replicas: 1 applicationImage: default-route-openshift-image-registry.apps.example.ibm.com/ol-app/<image_name> expose: true route: termination: reencrypt service: annotations: service.beta.openshift.io/serving-cert-secret-name: inventory-ibmjdk-svc-tls certificateSecretRef: inventory-ibmjdk-svc-tls port: 9443
Now you’re ready to deploy the application to OpenShift by running the following command:
$ oc apply -f app-deploy.yaml
You can also use the oc get pods
and oc get routes
commands to check the pod and route of your application:
$ oc get pods inventory-ibmjdk-687487479-4rxk7 1/1 Running 0 36h $ oc get routes|grep jdk inventory-ibmjdk inventory-ibmjdk-ol-app.apps.example.ibm.com inventory-ibmjdk 9443-tcp reencrypt None
You can open a browser and access the route that was returned by the oc get routes
command, for example, https://inventory-ibmjdk-ol-app.apps.example.ibm.com.
Summary
Security is obviously a high priority for any organization with growing number of security threats. Running your enterprise applications in a FIPS-enabled runtime and Kubernetes cluster ensures that validated cryptographic modules are used. It’s important to consider all the dependencies of an application before you enable FIPS to make sure that the application will continue to work when it’s FIPS-compliant. If you’re already running Open Liberty applications with FIPS enabled on-premises, you can move to Kubernetes. Just make sure that you pick the Open Liberty image with FIPS-supported Java and update the container image with FIPS-enabled files.
We’d like to convey thanks to Alasdair Nottingham for all the help and advice in writing this post.