Monday, April 21, 2014

Setting up a simple WSO2 AS cluster when custom keystores are used

When we setup cluster deployments, people are reluctant to use the default keystore that is shipped with WSO2 products due to security reasons. Therefore, we can use a different keystore within our products other than what is shipped by default (wso2carbon.jks).

Lets see how this is possible and what changes we need to do in addition to the normal cluster configuration we do.

NOTE: I'm demonstrating on how to setup a simple cluster with one WSO2 Application Server Manager node and one WSO2 ELB node.

1. Download a fresh WSO2 Application Server pack from the product page. 


2. Remove the default wso2carbon.jks that is shipped with the product. This file resides in $PRODUCT_HOME/repository/resources/security folder and drop the custom keystore that you created.

keytool -genkey -alias appserverks -keyalg RSA -keystore appserver.jks -storepass appserver


3. Change the following configuration files of the App server pack so that it refers the custom keystore file.
- $PRODUCT_HOME/repository/conf/carbon.xml
- $PRODUCT_HOME/repository/conf/identity.xml


4. Follow the instructions listed under the section Configuring the Manager Node and setup the Application server manager node.


5. Follow the instructions given in WSO2 Clustering & Deployment Guide and configure a WSO2 ELB as explained in Configuring the Load Balancer section.


6. Start the WSO2 ELB node


7. Start the WSO2 Application Server node & access the Management Console and it would throw an exception as below.



[2014-04-21 23:34:40,530] ERROR - TargetHandler I/O error: General SSLEngine problem javax.net.ssl.SSLHandshakeException: General SSLEngine problem at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1362) at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:513) at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1177) at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1149) at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469) at org.apache.http.nio.reactor.ssl.SSLIOSession.doWrap(SSLIOSession.java:220) at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:254) at org.apache.http.nio.reactor.ssl.SSLIOSession.isAppInputReady(SSLIOSession.java:380) at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:118) at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:160) at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:342) at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:320) at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280) at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:106) at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:604) at java.lang.Thread.run(Thread.java:724)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1683) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:278) at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1341) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:153) at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868) at sun.security.ssl.Handshaker$1.run(Handshaker.java:808) at sun.security.ssl.Handshaker$1.run(Handshaker.java:806) at java.security.AccessController.doPrivileged(Native Method) at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1299) at org.apache.http.nio.reactor.ssl.SSLIOSession.doRunTask(SSLIOSession.java:238) at org.apache.http.nio.reactor.ssl.SSLIOSession.doHandshake(SSLIOSession.java:270) ... 9 more Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:385) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292) at sun.security.validator.Validator.validate(Validator.java:260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:326) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:283) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:138) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1328) ... 17 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:196) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:268) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:380) ... 23 more

To overcome this issue, you need to import the public certificate of the custom keystore that you used at the App server node, to the $ELB_HOME/repository/resources/security/client-truststore.jks of the WSO2 ELB instance.

Extracting the public certificate
 
keytool -export -alias appserverks -keystore appserver.jks -file appserverks.cert


Importing the public certificate to the client-truststore.jks of the WSO2 ELB instance


keytool -import -file appserverks.cert -keystore client-truststore.jks -storepass wso2carbon -alias appserverks



Restart the WSO2 ELB instance and then the WSO2 Appserver node and then you will be able to access the Management Console successfully

No comments: