- Configuring Two-way SSL Authentication on EAP 7
- Enforcing HTTPS
Configuring Two-way SSL Authentication on EAP 7
In this example, a single jks file is used as both the keystore and the truststore for both the client and server. It is useful to call attention to this detail as it would be common to use separate jks files or in some cases to simply append the trusted certificates or certificate authoricity certs into the jre’s truststore.
Creating certificates
It is possible to create certificates using other methods (e.g. openssl); however, the java keytool utility is used in this example. Throughout the example, it is important to keep in mind that you should replace the parameter values being passed to be values that makes sense for your environment.
Creating the server certificate
keytool -genkeypair -alias server -keyalg RSA -keystore server_keystore.jks -keysize 2048 -dname "CN=sslExample,OU=redhat-consulting,O=redhat,L=US,ST=NJ,C=US" -keypass asd56jko -storepass asd56jko
Creating the client certificate
keytool -genkeypair -alias client -keyalg RSA -keystore client_keystore.jks -keysize 2048 -dname "CN=sslExample,OU=redhat-consulting,O=redhat,L=US,ST=NJ,C=US" -keypass asd56jko -storepass asd56jko
Exporting the client certificate
keytool -exportcert -rfc -alias client -file client.cer -keypass asd56jko -keystore client_keystore.jks -storepass asd56jko
Exporting the server certificate
keytool -exportcert -rfc -alias server -file server.cer -keypass asd56jko -keystore server_keystore.jks -storepass asd56jko
Importing the server certificate to the client
keytool -importcert -alias server -file server.cer -keystore client_keystore.jks -storepass asd56jko -noprompt
Importing the client certificate to the server
keytool -importcert -alias client -file client.cer -keystore server_keystore.jks -storepass asd56jko -noprompt
Asciinema Demo
Configure Two Way SSL for the management Interface in EAP 7
This step assumes the server keystore generated above has been moved to the following location:
$EAP_HOME/ssl/server_keystore.jks
Using the CLI to configure the management interface
Updating the ManagementRealm for SSL
/core-service=management/security-realm=ManagementRealm/server-identity= \
ssl:add(keystore-path=${jboss.home.dir}/ssl/server_keystore.jks, keystore-password=asd56jko, \
alias=server)
/core-service=management/security-realm=ManagementRealm/authentication= \
truststore:add(keystore-path=${jboss.home.dir}/ssl/server_keystore.jks,keystore-password=asd56jko)
/core-service=management/management-interface=http-interface:undefine-attribute(name=socket-binding)
Resulting XML
<server-identities>
<ssl>
<keystore path="${jboss.home.dir}/ssl/server_keystore.jks" keystore-password="asd56jko" alias="server"/>
</ssl>
</server-identities>
<authentication>
<truststore path="${jboss.home.dir}/ssl/server_keystore.jks" keystore-password="asd56jko"/>
<local default-user="$local" skip-group-loading="true"/>
<properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/>
</authentication>
<authorization map-groups-to-roles="false">
<properties path="mgmt-groups.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
Configure https listener for the undertow subsystem on EAP 7 for SSL and enforce client certificate verification
For simplicity, we will use the ManagementRealm in this step. In practice, you may want to setup a new realm for applications or configure the ApplicationRealm.
/subsystem=undertow/server=default-server/https-listener=https:add(socket-binding=https, security-realm=ManagementRealm, verify-client=REQUIRED)
Configuring the jboss-cli.sh for two-way SSL
Update jboss-cli.xml.
<ssl>
<alias>client</alias>
<key-store>../ssl/client_keystore.jks</key-store>
<key-store-password>asd56jko</key-store-password>
<key-password>asd56jko</key-password>
<trust-store>../ssl/client_keystore.jks</trust-store>
<trust-store-password>asd56jko</trust-store-password>
<modify-trust-store>false</modify-trust-store>
</ssl>
Running the CLI after adding ssl configuration:
sh jboss-cli.sh -c --controller=https-remoting://localhost:9993
Update jboss-cli.xml defaults (Optional)
<default-controller>
<protocol>https-remoting</protocol>
<host>localhost</host>
<port>9993</port>
</default-controller>
After changing the defaults, it is possible to run the cli without additional parameters.
Enforcing HTTPS
Configuring HTTPS does not enforce the use of https. To prevent the possibility of unsecure connections, you can do a number of things.
Completely remove https listener (preferred approach)
To completely remove http as an option, you can remove the undertow http listener and update the references to it. When an edge approapriate proxy is sitting in front of EAP (e.g. apache/nginx), this configuration typically makes the most sense. If there was no proxy redirecting http to https, this setup may not be ideal since it would prevent http redirects to https.
Cli commands
/subsystem=undertow/server=default-server/http-listener=default:remove
Enforcing HTTPS
Add Strict-Transport-Security header
/subsystem=undertow/configuration=filter/response-header=hsts-header:add(header-name="Strict-Transport-Security", header-value="max-age=31536000;")
/subsystem=undertow/server=default-server/host=default-host/filter-ref=hsts-header:add()
Use servlet api transport guarantee
At the applcation level, you can also add a CONFIDENTIAL transport guarantee to web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.0"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
...
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure URLs</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
...
</web-app>