JBoss EAP 7 with FIPS 140-2 Configuration
Version History
Version | Date | Modified By | Description of Modification |
---|---|---|---|
1.0 | 12/19/2016 | Minh-Hai Nguyen | Initial |
2.0 | 11/28/2018 | Minh-Hai Nguyen | Update to use standalone.xml and troubleshooting steps |
2.1 | 01/07/2019 | Minh-Hai Nguyen | Add JVM arguments |
Introduction
Motivation & Scope
The typical CONNECT installation uses Java keystores, but implementers may wish to use PKCS11 stores for FIPS 140-2 compliance. The instructions cover an example setup and deployment of CONNECT to JBoss EAP 7.0.0.GA on RedHat Enterprise Server Release 6.2 (Santiago), using Mozilla Network Security Services (NSS).
Document Audience
This document is intended for system administrators experienced with JBoss EAP 7.0.0.GA and RedHat Enterprise Server Release 6.2 (Santiago)
Prerequisites
- JBoss EAP 7.0.0.GA is unpackaged, and a ManagementRealm administrative user exists.
- The "nss.x86_64" package is installed via the package manager.
- CONNECT is deployed on the server. Make sure the Connection Validation Suite runs successfully before attempting to configure FIPS.
- Deploy the latest version of CONNECT to the the server. Follow the JBOSS EAP 7 Deployment Instruction
- Connection Validation Suite instruction: Validation Test Suite
NSS Configuration
Prepare the Database Configuration File and Directories
Create two folders designated for NSS, one to hold the configuration, and one to hold the keystore database; this document will use/nhin/nss/fips/config and /nhin/nss/fips/db respectively. Give ownership of these folders to Jboss user. Under the config folder, create a file called pkcs11.cfg with the following content
name = nss-fips nssLibraryDirectory = /usr/lib64 nssSecmodDirectory = /nhin/nss/fips/db nssModule = fips
Configure FIPS mode
Create the FIPS database:
modutil -create -dbdir /nhin/nss/fips/db
Convert JKS into p12:
- Navigate to {JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main/
- To convert gateway.jks to PKCS12 format, execute the following: keytool -importkeystore -srckeystore gateway.jks -srcstoretype JKS -deststoretype PKCS12 -destkeystore gateway.p12
- To import the cert keypair into the FIPS database, execute the following: pk12util -i gateway.p12 -n gateway -d /nhin/nss/fips/db
Modify Java.securityby editing ${JAVA_HOME}/jre/lib/security/java.security as follows:
- As the first provider line, add: security.provider.1=sun.security.pkcs11.SunPKCS11 /nhin/nss/fips/config/pkcs11.cfg
- Increment the number of every other provider by 1.
Java Policy:
- Make sure you have the correct Java Cryptography Extension (JCE) unlimited jurisdiction strength policy files
- Download from this url: https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
- Installation instructions are in the README.txt file.
Enable FIPS mode:
modutil -fips true -dbdir /nhin/nss/fips/db
List PKCS#11 modules:
modutil -list -dbdir /nhin/nss/fips/db
List the private keys available:
keytool -list -storetype pkcs11 -v
Display certificate content:
certutil -K -d /nhin/nss/fips/db
Note: It should prompt for a password or error out. If it prompts for password enter password. If it errors then do below steps to change the NSS database password:
- Disable nss_db first by executing the following: modutil -fips false -dbdir /nhin/nss/fips/db
- Execute the following: modutil -changepw "NSS FIPS 140-2 Certificate DB" -dbdir /nhin/nss/fips/db/
Module Setup - org.connectopensource.configuration
Navigate to folder ${JBOSS_HOME}/modules/system/layers/base/org/connectopensource/configuration/main.
Edit saml.properties and modify the following lines to reflect the name and password of the key in the NSS database:
org.apache.ws.security.saml.issuer.key.name=gateway org.apache.ws.security.saml.issuer.key.password=changeit
Edit signature.properties and modify the following lines to reflect PKCS11 settings; note that some properties may need to be added, uncommented, or blanked out from the default template:
org.apache.ws.security.crypto.merlin.keystore.type=PKCS11 org.apache.ws.security.crypto.merlin.keystore.provider=SunPKCS11-nss-fips org.apache.ws.security.crypto.merlin.keystore.password=changeit org.apache.ws.security.crypto.merlin.keystore.alias=gateway org.apache.ws.security.crypto.merlin.file=
Edit truststore.properties and modify the following lines to reflect PKCS11 settings; note that any properties here should match their counterparts in signature.properties:
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=PKCS11 org.apache.ws.security.crypto.merlin.keystore.provider=SunPKCS11-nss-fips org.apache.ws.security.crypto.merlin.keystore.password=changeit org.apache.ws.security.crypto.merlin.truststore.file=
Server Configuration: JAVA_OPTS
- In the standalone configuration file ${JBOSS_HOME}/bin/standalone.conf, append the following:
# Use standalone-full.xml instead of standalone.xml JAVA_OPTS="$JAVA_OPTS -Djboss.server.default.config=standalone-full.xml" # Increase memory allocation JAVA_OPTS="$JAVA_OPTS -Xmx8000m" # configuration directory JAVA_OPTS="$JAVA_OPTS -Dnhinc.properties.dir=$JBOSS_HOME/modules/system/layers/base/org/connectopensource/configuration/main" # Keystore and Truststore JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStore=NONE" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=NONE" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreProvider=SunPKCS11-nss-fips" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreProvider=SunPKCS11-nss-fips" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreType=PKCS11" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreType=PKCS11" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStorePassword=<nss_db_password>" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=<nss_db_password" JAVA_OPTS="$JAVA_OPTS -DCLIENT_KEY_ALIAS=gateway" JAVA_OPTS="$JAVA_OPTS -Djdk.tls.useExtendedMasterSecret=false"
Edit jboss-cli file in ${JBOSS_HOME}/bin/jboss-cli.sh, append the following:
jboss-cli.sh#JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,address=8787,server=y,suspend=n" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStore=NONE" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStore=NONE" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreProvider=SunPKCS11-nss-fips" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreProvider=SunPKCS11-nss-fips" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStoreType=PKCS11" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStoreType=PKCS11" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.keyStorePassword=<nss_db_password>" JAVA_OPTS="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=<nss_db_password"
Configure SSL
Open ${JBOSS_HOME}/standalone/configuration/standalone-full.xml and do the following:
1. Replace https-listener under subsystem/undertow:
<https-listener name="https" socket-binding="connect" security-realm="ApplicationRealm" verify-client="REQUIRED"/>
with this:
<https-listener name="https" enabled-protocols="TLSv1.1" enabled-cipher-suites="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_AES_256_CBC_SHA" verify-client="REQUIRED" security-realm="ApplicationRealm" socket-binding="connect"/>
2. Replace security realm under management/security-realms:
<security-realm name="ApplicationRealm"> <server-identities> <ssl> <keystore path="modules/system/layers/base/org/connectopensource/configuration/main/gateway.jks" relative-to="jboss.home.dir" keystore-password="changeit" alias="gateway"/> </ssl> </server-identities> <authentication> <truststore path="modules/system/layers/base/org/connectopensource/configuration/main/cacerts.jks" relative-to="jboss.home.dir" keystore-password="changeit"/> <local default-user="$local" allowed-users="*" skip-group-loading="true"/> <properties path="application-users.properties" relative-to="jboss.server.config.dir"/> </authentication> <authorization> <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> </authorization> </security-realm>
with this:
<security-realm name="ApplicationRealm"> <server-identities> <ssl> <keystore provider="PKCS11" keystore-password="<nss_db_password>" alias="gateway"/> </ssl> </server-identities> <authentication> <local default-user="$local" allowed-users="*" skip-group-loading="true"/> <properties path="application-users.properties" relative-to="jboss.server.config.dir"/> </authentication> <authorization> <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> </authorization> </security-realm>
Verify FIPS Installation:
The following steps verify that CONNECT has been set up to run in FIPS mode. Before beginning, make sure the application server is not running:
- Disable FIPS mode: modutil -fips false -dbdir /nhin/nss/fips/db
Restart the Jboss server. During startup, you should be given this error message and the server should not start:
FIPS is not available10:48:22,845 INFO [org.jboss.modules] (main) JBoss Modules version 1.5.1.Final-redhat-1 10:48:23,069 INFO [org.jboss.msc] (main) JBoss MSC version 1.2.6.Final-redhat-1 10:48:23,176 INFO [org.jboss.as] (MSC service thread 1-2) WFLYSRV0049: JBoss EAP 7.0.0.GA (WildFly Core 2.1.2.Final-redhat-1) starting 10:48:23,287 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-2) MSC000001: Failed to start service jboss.as: org.jboss.msc.service.StartException in service jboss.as: Failed to start service at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1904) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.security.ProviderException: NSS module not available: fips at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:272) at sun.security.pkcs11.SunPKCS11.<init>(SunPKCS11.java:103) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:224) at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:206) at java.security.AccessController.doPrivileged(Native Method) at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:206) at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:187) at sun.security.jca.ProviderList.getProvider(ProviderList.java:233)
- Enable FIPS mode: modutil -fips true -dbdir /nhin/nss/fips/db
- Try to start the server again. It should start this time.
- Deploy CONNECT and make sure the validation suite can be executed successfully.
Troubleshooting
Below is an error we encountered that was related to invalid NSS DB password:
10:53:33,300 ERROR [org.jboss.msc.service.fail] (MSC service thread 1-1) MSC000001: Failed to start service jboss.server.controller.management.security_realm.ApplicationRealm.key-manager: org.jboss.msc.service.StartException in service jboss.server.controller.management.security_realm.ApplicationRealm.key-manager: WFLYDM0018: Unable to start service at org.jboss.as.domain.management.security.ProviderKeyManagerService.start(ProviderKeyManagerService.java:68) at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948) at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Caused by: java.io.IOException: load failed at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:763) at java.security.KeyStore.load(KeyStore.java:1445) at org.jboss.as.domain.management.security.ProviderKeyManagerService.start(ProviderKeyManagerService.java:58) ... 5 more Caused by: javax.security.auth.login.FailedLoginException at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1234) at sun.security.pkcs11.P11KeyStore.login(P11KeyStore.java:849) at sun.security.pkcs11.P11KeyStore.engineLoad(P11KeyStore.java:753) ... 7 more Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_PIN_INCORRECT at sun.security.pkcs11.wrapper.PKCS11.C_Login(Native Method) at sun.security.pkcs11.SunPKCS11.login(SunPKCS11.java:1222) ... 9 more
Solution: Please enter correct password in ${JBOSS_HOME}/standalone/configuration/standalone-full.xml under <ssl> section.
Issue: java.security.InvalidAlgorithmParameterException: Key format must be RAW
Solution: Try either of one of those approaches:
- Add the following line to $JBOSS_HOME/bin/standalone.conf
- JAVA_OPTS="$JAVA_OPTS -Djdk.tls.useExtendedMasterSecret=false"
Future Document Enhancements
- Update the JBoss 7 EAP instructions to be more modular / generic, and follow a better format / layout, to make referencing that document cleaner.
- Update the troubleshooting section to document solutions to common errors, misconfigurations, etc.
- Test configuring datasource driver by copying the connector jar into the <jboss_root>/standalone/deployments directory to auto-deploy the MySQL JDBC driver, OR, using jboss cli deploy command.