How can I configure JBoss EAP 7.1 so that EJB connections use 2-way SSL with PicketBox legacy security?
Environment
- Red Hat JBoss Enterprise Application Platform
- 7.1
Issue
- How can I configure JBoss EAP 7.1 so that EJB connections use 2-way SSL?
Resolution
Server side configuration
-
Generate the keystore and truststores required for the 2-way SSL connection the standalone client and the JBoss server. If you don't already have certificates, you can generate self signed certificates by running the
create_keystores_truststores.shscript (see below). This script creates keystores for the client and server as well as truststores for the client and server that correctly trust each other. For example, theclient.truststorecontains the public key from theserver.keystore. Likewise, theserver.truststorecontains the public key from theclient.keystore. These keystore/truststores are built this way to establish trust between the two servers. On the standalone client use theclient.keystoreandclient.truststore. Copy theserver.keystoreandserver.truststoreto the configuration folder of the server (e. g.$JBOSS_HOME/standalone/configaution)#!/bin/sh # create_keystores_truststores.sh function create_keystore { KEY_FILE=$1 ALIAS=$2 DN=$3 PASS=$4 keytool -genkey -alias $ALIAS -keyalg RSA -keystore $KEY_FILE -storepass $PASS -keypass $PASS -dname $DN } function export_cert { KEY_FILE=$1 ALIAS=$2 EXPORT_FILE=$3 PASS=$4 keytool -export -alias $ALIAS -keystore $KEY_FILE -storepass $PASS -file $EXPORT_FILE } function import_cert { KEY_FILE=$1 ALIAS=$2 IMPORT_FILE=$3 PASS=$4 keytool -import -alias $ALIAS -keystore $KEY_FILE -storepass $PASS -file $IMPORT_FILE } PASSWORD="123456" create_keystore "server.keystore" "server" "CN=localhost" $PASSWORD create_keystore "client.keystore" "client" "CN=client" $PASSWORD export_cert "server.keystore" "server" "server_pub.key" $PASSWORD export_cert "client.keystore" "client" "client_pub.key" $PASSWORD import_cert "server.keystore" "client" "client_pub.key" $PASSWORD import_cert "client.keystore" "server" "server_pub.key" $PASSWORD import_cert "server.truststore" "client" "client_pub.key" $PASSWORD import_cert "client.truststore" "server" "server_pub.key" $PASSWORD -
Add a keystore and truststore to the
ApplicationRealm, for example using the CLI on a standalone server like:[standalone@host.example.com:9990 /] /core-service=management/security-realm=ApplicationRealm/server-identity=ssl:remove() [standalone@host.example.com:9990 /] /core-service=management/security-realm=ApplicationRealm/server-identity=ssl:add(keystore-path=server.keystore, keystore-password=123456, keystore-relative-to=jboss.server.config.dir) [standalone@host.example.com:9990 /] /core-service=management/security-realm=ApplicationRealm/authentication=local:remove() [standalone@host.example.com:9990 /] /core-service=management/security-realm=ApplicationRealm/authentication=truststore:add(keystore-path=server.truststore, keystore-relative-to=jboss.server.config.dir, keystore-password=123456)XML:
<security-realm name="ApplicationRealm"> <server-identities> <ssl> <keystore path="server.keystore" relative-to="jboss.server.config.dir" keystore-password="123456"/> </ssl> </server-identities> <authentication> <truststore path="server.truststore" relative-to="jboss.server.config.dir" keystore-password="123456"/> <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> -
Configure the remoting http-connector to use
httpsusing the CLI on a standalone server like:[standalone@host.example.com:9990 /] /subsystem=remoting/http-connector=http-remoting-connector:write-attribute(name=connector-ref, value=https)XML:
<subsystem xmlns="urn:jboss:domain:remoting:4.0"> <endpoint/> <http-connector name="http-remoting-connector" connector-ref="https" security-realm="ApplicationRealm"/> </subsystem> -
Enable
verify-clienton the https listener using the CLI on a standalone server like:[standalone@host.example.com:9990 /] /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=verify-client, value=REQUIRED)XML:
<subsystem xmlns="urn:jboss:domain:undertow:4.0"> : <server name="default-server"> <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/> <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" verify-client="REQUIRED" enable-http2="true"/> : </server> : </subsystem>
Client side configuration
-
If you're implementing the client part as explained in How configure an EJB client in EAP 7.1 1, you need to change the
PROVIDER_URLto useremote+httpsand theportconfiguration should be changed to thejboss.https.portwhich is8443by default, see:import org.jboss.ejb.client.EJBClient; public void callRemoteEjb() { HelloRemote remote = getInitialContext(host, port, user, pass).lookup("ejb:helloWorld/helloWorld-ejb/HelloWorldSLSB!org.jboss.examples.ejb.HelloRemote"); remote.helloWorld(); } public static Context getInitialContext(String host, Integer port, String username, String password) { Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, "org.wildfly.naming.client.WildFlyInitialContextFactory"); props.put(Context.PROVIDER_URL, String.format("%s://%s:%d", "remote+https", host, port)); if(username != null && password != null) { props.put(Context.SECURITY_PRINCIPAL, username); props.put(Context.SECURITY_CREDENTIALS, password); } return new InitialContext(props); } -
When running the standalone Java application the following system properties must be set (either directly in the code or as show below, as command line parameters):
-Djavax.net.ssl.trustStore=${path.to}/client.truststore -Djavax.net.ssl.trustStorePassword=123456 -Djavax.net.ssl.keyStore=${path.to}/client.keystore -Djavax.net.ssl.keyStorePassword=123456
Diagnostic Steps
Enable TRACE level logging on the following categories, reproduce the issue and upload the server.log file:
<logger category="org.jboss.as.domain.management.security">
<level name="TRACE"/>
</logger>
<logger category="org.jboss.remoting">
<level name="TRACE"/>
</logger>
<logger category="org.jboss.sasl">
<level name="TRACE"/>
</logger>
<logger category="org.jboss.as.security">
<level name="TRACE"/>
</logger>
<logger category="org.jboss.security">
<level name="TRACE"/>
</logger>
<logger category="org.undertow">
<level name="TRACE"/>
</logger>
Enable SSL/TLS debug logging by adding the following System Property to the JVM:
- Djavax.net.debug=ssl:handshake
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.