Sunday, August 12, 2012

Secure plain text passwords in WSO2 Carbon configuration files


Please visit new my blog for this blog post from here


If you go through the conf directory of WSO2 products, there are some configuration file, that contains secret informations such as passwords...This blog post describes how we can secure the plain text passwords in these configuration files. This [1] document gives you clear understanding about secure vault implementation. But here i am going step by step to configure it. Please note this configurations only valid for carbon 3.2.X products.  But with 4.0.X release, steps are same..  but there are new configurations files....  as an example,  we have "master-datasources.xml" file which can be found in "conf/datasources".  In this file, we are configuring all data source related configurations...  Therefore database configuring passwords would be in this file.   



First, let see what are the secret information that can be secured. Following are the alias names and secrets of carbon configuration files.  

1. in user-mgt.xml  

UserManager.AdminUser.Password -> Admin User password in user-mgt.xml
UserManager.Configuration.Property.password -> User Manager database connection password in user-mgt.xml  
(Only in 3.2.X)
UserStoreManager.Property.ConnectionPassword -> User store connection password in user-mgt .xml 

2. in registry.xml (Only in 3.2.X )

wso2registry.[Registry Name].password -> Registry database connection password in registry.xml 

3. in carbon.xml

Carbon.Security.KeyStore.Password- > Keystore password of Carbon server in carbon.xml
Carbon.Security.KeyStore.KeyPassword -> Private key password of Carbon server in carbon.xml
Carbon.Security.TrustStore.Password -> Trust store password of Carbon server in carbon.xml 

4. in mgt-transport.xml   (Only in 3.2.X )

transports.https.keystorePass -> SSL key and keystore password in mgt-transport.xml 

5.  master-datasources.xml  (With Carbon 4.0.X Only)

Datasources.[Data source name].Configuration.Password  ->  Database connection password of defined data source.  There can be more than one datasource configurations in this file.

Also by using secure vault you can secure the passwords in axis2.xml file, i.e.

Axis2.Https.Listener.TrustStore.Password -> NIO Listener SSL trust store password in axis2.xml
Axis2.Https.Listener.KeyStore.Password -> NIO Listener SSL keystore store password in axis2.xml
Axis2.Https.Listener.KeyStore.KeyPassword -> NIO Listener SSL key password in axis2.xml
Axis2.Https.Sender.TrustStore.Password -> NIO Sender SSL trust store password in axis2.xml
Axis2.Https.Sender.KeyStore.Password -> NIO Sender SSL key store password in axis2.xml
Axis2.Https.Sender.KeyStore.KeyPassword -> NIO Sender SSL key password in axis2.xml
Axis2.Mailto.Parameter.Password -> Email sender password in axis2.xml 


Step 1.   Locate cipher-text.properties which can be found at <CARBON_HOME>/repository/conf directory in your WSO2 product.  This file contains the alias names and the corresponding plain text password in square brackets. 

If you can not find this file in your product, Please download it from this svn location [2]  and copy to above location. 

Step 2.  Configure cipher-text.properties file with your passwords. 

As an example, I want to secure keystore passwords of carbon.xml file (You should secured them as encryption is done with it) ,  both database and LDAP connection password of user-mgt.xml file.  My cipher-text.properties would be as follows,


Carbon.Security.KeyStore.Password=[mykeystorepass]

Carbon.Security.KeyStore.KeyPassword=[mykeystorepass]

Carbon.Security.TrustStore.Password=[mytruststorepass]
UserManager.Configuration.Property.password=[myuserdbpass]
UserStoreManager.Property.ConnectionPassword=[myldappass]

Step 3. Locate  "ciphertool" script which can be found at <CARBON_HOME>/bin directory. If you can not find this file in your product, Please download it from this svn location [3]  and copy to above location.

Step 4. Run "ciphertool" script with -Dconfigure option.  

as an example in UNIX,

>ciphertool.sh  -Dconfigure

This script does followings 
1. encrypt the passwords defined in cipher-text.properties file
2. remove plain text passwords in conf files.
3. configure  secret-conf.properties file

Step 5. Check above mentioned files, are properly configured. 

Step 6. Start server.     in startup, server would promote for  master password (i.e is key store password) you need to provide it. 


Personally, I do not like to provide master password each server startup,  although it is one of a secured way to provide it....  This is the default way of providing the master password according to this [4].  You can write your own implementation for this. Therefore i just write a simple implementation for this where i have hard coded my master password. Please find the my project from here [5]. 

Let see how we can configure new master password callback handler

1. Replace the default password handler class name (org.wso2.carbon.securevault.DefaultSecretCallbackHandler) from secret-conf.properties file and configure my own one (com.sample.password.callback.handler.HardCodedSecretCallbackHandler). 

2. Copy own implementations as a jar file in to <CARBON_HOME>/repository/components/lib directory 

3. If you have secured the passwords in mgt-transport.xml file, Please Copy your jar file to <CARBON_HOME>/lib/api directory.

4. Restart the server.


Links again :) 





  

Wednesday, August 8, 2012

Enable Mutual SSL for Proxy services in WSO2ESB - II

This is my second blog post about enabling mutual SSL for ESB  proxy services. In my previous blog post,  we enabled mutual SSL for all deployed proxy services. But in this blog post,  we are going  to enable it for only selected proxy services. Let assume we have proxy service call "TestProxy" and also there are many other proxy services that have been deployed in WSO2ESB.  We want to enable mutual SSL for "TestProxy" only. Let see how we can do it. Here we are using transport binding in WS-Security. 

I assume that you have gone through my previous blog post,  therefore i am not going to much details  in some configurations

Step 1 : Configure  "SSLVerifyClient" property to optional in NIO transport receiver and Restart the server. 

Step 2. Secure TestProxy using security scenario 1 (Username Token authentication) 

Step 3. Modify applied policy in to this policy using policy editor.  Here we have remove the user name token validation and forced the client certificated.

Step 4. Apply these patched jars to WSO2ESB 4.0.3 distribution. Copy and Replace in to <ESB_HOME>/repository/components/plugins.  Actually we have done small modification  to bring the client certificate in to rampart level and validate it at that level 
 
Step 5. Step you key stores and trust stores as described in my previous post

Step 6. Invoke the "TestProxy" using sample client which can be found at here

If you have not used  a key store or your certificate does not contain in the NIO transport receiver's trust store file; you would probably experience following error.
 
[2012-08-08 18:02:47,879] ERROR - AxisEngine Service requires SSL mutual authentication
org.apache.axis2.AxisFault: Service requires SSL mutual authentication
at org.apache.rampart.handler.RampartReceiver.setFaultCodeAndThrowAxisFault(RampartReceiver.java:180)
at org.apache.rampart.handler.RampartReceiver.invoke(RampartReceiver.java:99)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)

 

Enable Mutual SSL for Proxy services in WSO2ESB - I

Please visit new my blog for this blog post from here




Lets see how we can enable mutual SSL (two-way SSL) for all the proxy services that are deployed in WSO2 ESB

Step 1 :  Enable mutual SSL for NIO transport receiver


WSO2 ESB uses NIO transport for sending and receiving messages.  You can find NIO transport  receiver and sender configuration  from axis2.xml file which can be found at <ESB_HOME>/repository/conf directory. Under the transport receiver,  there are key store and trust store configurations as follows.  

By default 
1. mutual authentication is not enabled
2. for keystore and trust store,  WSO2ESB is using the default wso2carbon.jks and client-truststore.jks file

Therefore you need to change those default parameters. Here i have changed only the "SSLVerifyClient" parameter to "require" to enable mutual authentication for all services that has been exposed via NIO

    <transportReceiver name="https" class="org.apache.synapse.



transport.nhttp.

HttpCoreNIOSSLListener">
        <parameter name="port" locked="false">8243</
parameter>
        <parameter name="non-blocking" locked="false">true</
parameter>
        <parameter name="keystore" locked="false">
            <KeyStore>
                <Location>repository/
resources/security/wso2carbon.


jks</Location>
                <Type>JKS</Type>
                <Password>wso2carbon</
Password>
                <KeyPassword>wso2carbon</
KeyPassword>
            </KeyStore>
        </parameter>
        <parameter name="truststore" locked="false">
            <TrustStore>
                <Location>repository/
resources/security/client-


truststore.jks</Location>
                <Type>JKS</Type>
                <Password>wso2carbon</
Password>
            </TrustStore>
        </parameter>
          <parameter name="SSLVerifyClient">
require</parameter>
    </transportReceiver>


After configuration is finished, Restart WSO2ESB server, if you have already started. Then just create a simple pass through proxy service call "TestProxy". 



Step 2 :  Writing Axis2 client to invoke  

You can find the client program for here. To run the client program you need to setup your key store and trust store properly.  Actually we can use same key store file as both key store (which contains private key) and trust store (which contains trusted certificates)

First we need to import the NIO transport receiver's certificate to client's trust store file

Please export NIO transport receiver's 
certificate from key store.  As a sample, you can use keytool command as follows.

> keytool -export -keystore wso2carbon.jks -alias localhost -file wso2.crt

Please import NIO certificate in to client trust store.

> keytool -import -keystore client.jks -alias wso2carbon -file wso2.crt

Now you have setup the SSL properly. If this is not properly done,  when you tries with sample client, you would receive following error in client side.
 


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)  

Then we need to import client's certificate in to the NIO transport receiver's trust store file. Please go through above keytool command for this also
Now you have setup the SSL properly.  If not, when you tries with sample client, you would receive following error in client side.

Exception in thread "main" org.apache.axis2.AxisFault: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
at org.apache.axis2.AxisFault.
makeFault(AxisFault.java:430)
at org.apache.axis2.transport.
http.SOAPMessageFormatter.


writeTo(SOAPMessageFormatter.

java:78)

And in server side.

[2012-08-08 17:29:56,390] ERROR - ServerHandler I/O error: null cert chain
javax.net.ssl.
SSLHandshakeException: null cert chain
at com.sun.net.ssl.internal.ssl.
Handshaker.checkThrown(


Handshaker.java:1015)

Now you know how to secure  WSO2ESB  proxy  services using mutual SSL and invoke them.  In my next blog post let see,  how we can secure only the one or two WSO2ESB  proxy  services using mutual SSL(Not all)