Friday, October 2, 2015

Configuring Dynamic SSL Profiles with Client Connections - WSO2 ESB 4.9.0

In order to establish connections with ESB from client services/applications, Client needs to have ESB's public key in it's trust store file. Also, if Mutual SSL is required, ESB must need client's public key in it's trust store file.

Create Key Store and Trust Store files for SSL



First create keystore and truststore files required for SSL connections as follows.

ESB
  • Key Store
    • Name - esb.jks
    • Contains ESB’s Private Key
  • Trust Store
    • Name - esbtruststore.jks
    • Contains backend's certificate
Client
  • Key Store/Trust Store
    • Name - client.jks
    • Contains Client's Private Key
    • Contains ESB's certificate
Generate Key Stores


esb.jks
keytool -keystore esb.jks -genkey -alias esb


client.jks

keytool -keystore client.jks -genkey -alias client

Export Certificates


esb.jks
keytool -export -keystore esb.jks -alias esb -file esb.crt


client.jks
keytool -export -keystore client.jks -alias client -file client.crt


Import Certificates and Create TrustStores

esbtruststore.jks
keytool -import -file client.crt -alias client -keystore esbtruststore.jks
client.jks
keytool -import -file esb.crt -alias esb -keystore client.jks


SSL with Clients


  1. We will use echo service of Backend ESB (WSO2 ESB-4.8.1) as the back end service and create Pass Through Proxy in ESB (WSO2 ESB-4.9.0).
  1. Change port offset of the Backend ESB using below configuration of carbon.xml in {ESB_HOME}/repository/conf/ folder. It will allow to start two ESB instances at once.
<Offset>1</Offset>
  1. Start Backend ESB.
  2. Go to https://localhost:9444/carbon/ and it will show “echo” service as a default deployed axis2 service in Backend ESB.


  1. Now to configure ESB to use above backend service through a Pass Through Proxy, start the server.
  2. Admin console can be access through https://localhost:9443/carbon/
  3. Go to proxy services and create a new Pass Through Proxy service to access “echo” service mentioned above (http://localhost:8281/services/echo) using http.


  1. Now configure ESB for Dynamic SSL Profiles for listeners. Create new XML file “listenerprofiles.xml” in {ESB_HOME}/repository/conf/sslprofiles/ folder. (this path is configurable)
  2. Include below configuration block in newly created file to enable Dynamic SSL Profiles. This will configure wso2carbon.jks as Key Store for all incoming connections to 127.0.0.1:8243. (8243 is the port configured in axis2.xml for SSL Listener)

<parameter name="SSLProfiles">
<profile>
<bindAddress>127.0.0.1</bindAddress>
<KeyStore>
<Location>repository/resources/security/wso2carbon.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
    </KeyStore>
<profile>
</parameter>

  1. To enable dynamic loading of this configuration, change the PassThroughSSLListener to PassThroughHttpMultiSSLListener in axis2.xml in {ESB_HOME}/repository/conf/
  2. Add below configurations to the Transport Listener configuration of the same config above . Set “listenerprofiles.xml” file’s path as “filePath” parameter.

<parameter name="dynamicSSLProfilesConfig">
<filePath>repository/conf/sslprofiles/listenerprofiles.xml</filePath>
<fileReadInterval>3600000</fileReadInterval>
</parameter>

  1. Now the ESB is configured to use default key stores and load dynamic SSL profiles for listeners.
  2. Restart ESB. It will show below message in the console confirming that dynamic configurations loaded.
ServerConnFactoryBuilder SSLProfile configuration is loaded from path:

  1. To test the connection, this sample client mentioned Step 6 in this blog [1] is used.
  2. Change following values in the sample program to match with above configurations
    1. keyStore=”client.jks”
    2. keyStorePassword = "123456";
    3. endPoint = "http://localhost:8281/services/echo";

  1. Copy client.jks file to the key store path of above sample program.
  2. Run the sample client. It will give below error
Exception in thread "main" org.apache.axis2.AxisFault: Connection has been shutdown: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430)
This happens due to key mismatches in ESB and Sample Client. ESB uses “wso2carbon.jks” while the client is using “client.jks” which is a custom keystore.

  1. Now change ESB keystore dynamically to “client.jks”. To do that, change “listenerprofiles.xml” configurations as follows;
<parameter name="SSLProfiles">
<profile>
<bindAddress>127.0.0.1</bindAddress>
<KeyStore>
<Location>repository/resources/security/esb.jks</Location>
<Type>JKS</Type>
<Password>123456</Password>
<KeyPassword>123456</KeyPassword>
    </KeyStore>
<profile>
</parameter>

  1. Copy esb.jks and esbtruststoe.jks files to {ESB_HOME}/repository/resources/security/ folder.
  2. New configurations can be applied using two methods. (mentioned earlier in this document) Here we can use JMX method. Start JConsole and connect it to ESB  instance. It will show “ListenerSSLProfileReloader” under org.apache.synapse menu in MBeans tab.

Here, “ConfigFilePath” attribute shows the path of the configuration file. Make sure it is the same file changed in Step 17. Once confirmed, execute “notifyFileUpdate” operation.

  1. ESB console will show below messages confirming that new SSL configuration loaded and applied.

INFO - PassThroughListeningIOReactorManager Pass-through HTTPS Listener started on localhost:8243
INFO - PassThroughHttpMultiSSLListener HTTPS Reloaded

  1. Run the sample client again, the connection will be established using new keys loaded dynamically. Now it will connect and display the echo message “Hello”.

Mutual SSL with Clients



  1. To test mutual SSL with clients, change “listenerprofile.xml” file as follows;
<parameter name="SSLProfiles">
<profile>
<bindAddress>127.0.0.1</bindAddress>
<KeyStore>
<Location>repository/resources/security/esb.jks</Location>
<Type>JKS</Type>
<Password>123456</Password>
<KeyPassword>123456</KeyPassword>
    </KeyStore>
<TrustStore>
<Location>repository/resources/security/esbtruststore.jks
</Location>
<Type>JKS</Type>
<Password>123456</Password>
</TrustStore>
<SSLVerifyClient>require</SSLVerifyClient>
<profile>
</parameter>

  1. Make sure “esbtruststore.jks” file is in {ESB_HOME}/repository/resources/security/ folder.
  2. Reload configurations same as in Step 19 above.
  3. Run the sample client again, it will successfully connect and print the echo message “Hello”.



References