Introduction
Enabling SSL/TLS in a Fabric is slightly more complex than securing a jetty in a standalone Karaf container. In the following article, we are providing feedback on the overall process. For clarity and simplification, the article will be divided into two parts.
Part1: The Management Console
Part2: Securing Web Service:including gateway-http
For the purpose of this PoC, the following environment will be used.
Environment
- Host fabric1.example.com (192.168.56.1), localhost MacOS
- Host fabric2.example.com (192.168.56.101), RHEL 7.2 Virtual Box VM
- Host fabric3.example.com (192.168.56.102), RHEL 7.2 Virtual Box VM
With the following components
- jboss-fuse-6.3.0.redhat-187
- jdk1.8.0_102
Part1: Put the Management Console in HTTPS in a Fuse Fabric 6.3 Cluster.
STEP1: Prepare/Generate a valid certificate/Keystore
If you setup a fabric with three ensemble servers, each ensemble server should trust the two others; the most practical approach to do this is to create a certificate authority to sign all the individual certificates. For the purpose of this demo we are creating a self signed certificate with all the fabricXX.example.com in the Subject Alternative section.
keytool -genkeypair -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -validity 365 -keystore san.demo.jks -storepass Cluster01# -keypass Cluster01# -dname cn=fabric1.example.com -alias demo -ext SAN=dns:fabric1.example.com,dns:fabric2.example.com,dns:fabric3.example.com
This certificate should be populated on the three hosts in the same folder location, for this demo the file is stored in /shared/fuse/certs/
STEP2: Edit the EXTRA_JAVA_OPTS on all hosts.
p class="p1">vi $FUSE_HOME/bin/setenv
export EXTRA_JAVA_OPTS="-Djavax.net.ssl.trustStore=/shared/fuse/certs/san.demo.jks -Djavax.net.ssl.trustStorePassword=Cluster01# -Djavax.net.ssl.keyStore=/shared/fuse/certs/san.demo.jks -Djavax.net.ssl.keyStorePassword=Cluster01# "
This will make your certs trusted by client code in fuse also. for debugging purpose you can add the options
-Djavax.net.debug=ssl to have all the exception trace if any during the SSL handshake process.
-Djava.rmi.server.logCalls=true , to get all RMI Exceptions
STEP 3: Start Fuse and create the Fabric
./fuse JBossFuse:karaf@fabric1> fabric:create --clean --resolver manualip --global-resolver manualip --manual-ip fabric1.example.com --force
Waiting for container: fabric1
It may take a couple of seconds for the container to provision...
You can use the --wait-for-provisioning option, if you want this command to block until the container is provisioned.
JBossFuse:karaf@fabric1> fabric:wait-for-provisioning
SUCCESS
JBossFuse:karaf@fabric1> fabric:info Fabric Release: 1.2.0.redhat-630187 Web Console: http://fabric1.example.com:8181/hawtio Rest API: Git URL: http://fabric1.example.com:8181/git/fabric/ Jolokia URL: http://fabric1.example.com:8181/jolokia ZooKeeper URI: fabric1.example.com:2181 Maven Download URI: http://fabric1.example.com:8181/maven/download/ Maven Upload URI: http://fabric1.example.com:8181/maven/upload/
From fabric2.example.com and fabric3.example.com, run the fabric join command
JBossFuse:karaf@fabric2>fabric:join --resolver manualip --manual-ip fabric2.example.com --force fabric1.example.com:2181 JBossFuse:karaf@fabric3>fabric:join --resolver manualip --manual-ip fabric3.example.com --force fabric1.example.com:2181
The --resolver --global-resolver and --manual-ip are very important, if they do not match , certificate validation will failed
JBossFuse:karaf@fabric1> container-resolver-list [id] [resolver] [local hostname] [local ip] [public hostname] [public ip] [manual ip] fabric1 manualip fabric1.example.com 192.168.56.1 fabric1.example.com fabric2 manualip fabric2.example.com 192.168.56.101 fabric2.example.com fabric3 manualip fabric3.example.com 192.168.56.102 fabric3.example.com
STEP 4: Create the secure SSL profile
Create a secure profile ssl
JBossFuse:karaf@root> profile-create --parent default ssl profile-edit --pid org.ops4j.pax.web/org.osgi.service.http.enabled=false ssl profile-edit --pid org.ops4j.pax.web/org.osgi.service.http.secure.enabled=true ssl profile-edit --pid org.ops4j.pax.web/org.osgi.service.http.port.secure='${port:8443,8543}' ssl profile-edit --pid org.ops4j.pax.web/org.ops4j.pax.web.ssl.keystore='/shared/fuse/certs/san.demo.jks' ssl profile-edit --pid org.ops4j.pax.web/org.ops4j.pax.web.ssl.password=Cluster01# ssl profile-edit --pid org.ops4j.pax.web/org.ops4j.pax.web.ssl.keypassword=Cluster01# ssl
Check the created profile
JBossFuse:karaf@fabric1> profile-display ssl
Profile id: ssl
Version : 1.0
Attributes:
parents: default
Containers:
Container settings
----------------------------
Configuration details
----------------------------
PID: org.ops4j.pax.web org.ops4j.pax.web.ssl.password Cluster01# org.osgi.service.http.enabled false org.ops4j.pax.web.ssl.keypassword Cluster01# org.osgi.service.http.secure.enabled true org.osgi.service.http.port.secure ${port:8443,8543} org.ops4j.pax.web.ssl.keystore /shared/fuse/certs/san.demo.jks
Other resources
----------------------------
STEP 5: Put the fabric in HTTPS
By adding the ssl profile to the fabric1, for example, the fabric turns in https. You can repeat the operation for fabric2 and fabric3.
JBossFuse:karaf@fabric1> container-add-profile fabric1 ssl JBossFuse:karaf@fabric1> container-add-profile fabric2 ssl JBossFuse:karaf@fabric1> container-add-profile fabric3 ssl
JBossFuse:karaf@fabric1> log:tail | grep "Pax Web available"
2016-11-15 11:29:59,802 | INFO | onfig-1-thread-3 | JettyServerImpl | 117 - org.ops4j.pax.web.pax-web-jetty - 4.3.0 | Pax Web available at [0.0.0.0]:[8443]
JBossFuse:karaf@fabric1> fabric:info Fabric Release: 1.2.0.redhat-630187 Web Console: https://fabric1.example.com:8443/hawtio Rest API: Git URL: https://fabric1.example.com:8443/git/fabric/ Jolokia URL: https://fabric1.example.com:8443/jolokia ZooKeeper URI: fabric1.example.com:2181 Maven Download URI: https://fabric1.example.com:8443/maven/download/ Maven Upload URI: https://fabric1.example.com:8443/maven/upload/
STEP 6: Creating Child containers
Connections from child containers also need to be trusted (e.g. Maven proxy, communication with fabric ensemble.) To create a child container with the ssl profile follow the following steps:
- create the child container with ssl profile container-create-child --profile ssl fabric1 node1
- edit the child container JVM Options : pass the trustStore file and password
container-edit-jvm-options node1 '-Djavax.net.ssl.trustStore=/shared/fuse/certs/san.demo.jks -Djavax.net.ssl.trustStorePassword=Cluster01#'
- restart the container
container-stop node1 container-start node1
More Information
https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.3/pdf/Security_Guide/JBoss_Enterprise_Application_Platform-6.3-Security_Guide-en-US.pdf
Last updated: February 26, 2024