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)
   

Monday, May 28, 2012

Login to WSO2 Carbon servers via Shibboleth SAML2 IDP


 
In my previous post,  I went through step by step to configure the shibboleth as a SAML2 IDP.  Now lets try to use Shibboleth SAML2 IDP in a real word use case. In this blog post i am going to configure WSO2 Carbon product as a SSO service provider for  Shibboleth IDP. Any WSO2 Carbon server can act as a SAML2 SSO relying party components. 

This type of scenario actually useful when you want to login to management console of several WSO2 Carbon products that had been deployed as cluster; where users want to experience SSO. 

User experience would be as follows. 

1. User type WSO2 Carbon product management console url
2. User redirected to  the shibboleth login console 
3. User enter his user name and password associate with shibboleth IDP account   
4. User now has redirected to WSO2 Carbon product management console.

(But still i could not setup single logout with Shibboleth :( . Therefore you want to exit from the browser to logout from Shibboleth)

Here we want to understand one thing very carefully.  i.e User, who has an account in shibboleth IDP, must be also exist in the user store of the WSO2 Carbon server. Why?  For authentication, we do not want to duplicate the user accounts. Yes...!  Actually authentication would be successful at the WSO2 Carbon server without even a user store. But;  to login to the WSO2 Carbon management console, authentication is not enough, users are needed to authorize to access the management console.  Therefore after successful  authentication by using SSO,  WSO2 Carbon server performs an authorization check with respect to its own user store.  Therefore user must be in that user store also. (basically user Id and access control list).  But credentials do not want to be there. 

Therefore basically, you need to syn shibboleth IDP with WSO2 Carbon user store. For this we can have two options. 

1. Use provisioning mechanism such as SCIM (SCIM would be supported by WSO2Carbon server 4.0.0 version) 
2. Share same user store for shibboleth IDP and WSO2 Carbon servers. Most of the cases,  shibboleth IDP is backed by LDAP or AD. Therefore we can easily configure WSO2 Carbon servers to connect to that LDAP or AD.   But authentication check would be always happened at the shibboleth IDP. 



Now lets go with configurations. 

First configure at shibboleth IDP side,

Step 1.  Configure new relying party for carbon servers under the "RelyingPartyGroup"  in relying-party.xml which can be found at IPD_HOME/conf directory.   Sample configuration would be as follows 

<rp:RelyingParty id="carbonServer"
        defaultSigningCredentialRef="IdPCredential" defaultAuthenticationMethod="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport">
    <rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" signResponses="always" signAssertions="never" 
                                 encryptAssertions="never" encryptNameIds="never"/>
</rp:RelyingParty>


Here i have configured only to sign the SAML2 response.


Step 2. Configure SAML2 meta data configuration by using a new meta data config file at IPD_HOME/metadata directory.  In this directory, I created a new file called carbon.xml and configure followings.

<EntityDescriptor entityID="carbonServer" xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
    <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
        <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</NameIDFormat>
        <AssertionConsumerService index="1" Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
            Location="https://localhost:9443/acs" />
    </SPSSODescriptor>
</EntityDescriptor> 

Please make sure  NameIDFormat, Binding in ACS and Location of ACS are configured according to your own configurations

Step 3. Configure new meta data configuration file under the "RelyingPartyGroup"  in relying-party.xml which can be found at IPD_HOME/conf directory.   Sample configuratio cn would be as follows 
Here we have pointed to the new meta data config file.

<MetadataProvider id="carbonMD" xsi:type="FilesystemMetadataProvider" xmlns="urn:mace:shibboleth:2.0:metadata"
    metadataFile="/home/asela/shibboleth/metadata/carbon.xml" maintainExpiredMetadata="true" />


Now lets configure Service provider side,  WSO2 Carbon server.

WSO2 Carbon server can be configured with different authenticators.   AuthenticationAdmin (which uses user name and password) is the default Carbon Server Authenticator. Therefore we need to change those configurations and enable Shibboleth related SAML2 SSO authenticator.  Actually there is existing SAML2 SSO authenticator that can be found at this SVN location. But it seems to be that default SAML2 SSO authenticator would not work with Shibboleth out of the box. Therefore you need to write a new authenticator for shibboleth. It would be really easy, because we only need to do small modifications to the existing SAML2 SSO authenticator source code.  Therefore I did that simple modification.  You can find the modified source from here.  And the patched jar files from here.  

Lets see how we can do this.  please note here i am using Carbon 3.2.3 based servers.


Step 1.  Install following patched SAML SSO authenticator jars  with WSO2 Carbon server by copying them in to  <CARBON_HOME>/repository/components/dropins

org.wso2.carbon.identity.authenticator.saml2.sso-3.2.1.jar 
org.wso2.carbon.identity.authenticator.saml2.sso.ui-3.2.2.jar  
org.wso2.carbon.identity.authenticator.saml2.sso.stub-3.2.0.jar

Step 2.  Configure authenticators.xml file which can be found at <CARBON_HOME>/repository/conf/advanced  directory. Sample configuration would be as follows


    <Authenticator name="SAML2SSOAuthenticator">
        <Priority>10</Priority>
        <Config>
            <Parameter name="LoginPage">/carbon/admin/login.jsp</Parameter>
            <Parameter name="ServiceProviderID">carbonServer</Parameter>
            <Parameter name="IdentityProviderSSOServiceURL">https://localhost:8443/idp/profile/SAML2/Redirect/SSO</Parameter>
        </Config>
    </Authenticator>

Here please note following two parameters must be according your configurations.

ServiceProviderID -> This must be same value that you have configured as RelyingParty Id.
IdentityProviderSSOServiceURL  -->  This must be the SSO redirect url of shibboleth IDP

Step 3. Start the server and try to login to management console,  you would probably redirected to  shibboleth  IDP login page..   


Configure Shibboleth as SAML2 IDP

Shibboleth  is one of a most popular SAML2 IDP that is widely used.  I tried to configure shibboleth  as SAML2 IDP. In this post i am going to share these steps with you. I hope that would be useful for you also.  My Operating System  was ubunutu 10.04

Step1. Download  latest version (v2.3.6) of  shibboleth IDP from here 

Step2. Extract in to your file system. 

Step3. Go to root directory and run install script.  This would install shibboleth in to given location in your file system Lets call it as IDP_HOME. Also this installation would create a key store which can be found at  IDP_HOME/credentials directory  and war file which can be found at  IDP_HOME/war directory.


First let configure a user store with shibboleth.  We can use LDAP based user store for this. Here i am using the ApacheDS LDAP user store.  You can find simple steps to create an ApacheDS LDAP server from here.

Step4. Open login.config file which can be found at IDP_HOME/conf directory and configure your LDAP user store.  following is my sample configurations. 

ShibUserPassAuth {

edu.vt.middleware.ldap.jaas.LdapLoginModule required
ldapUrl="ldap://localhost:10389"
bindDn="uid=admin,ou=system"
bindCredential="secret"
baseDn="ou=users,ou=system"
ssl="false"
userFilter="uid={0}"
;

};


Step5.  Enable username/password login handler from handler.xml file which can be found at IDP_HOME/conf directory. 

    <ph:LoginHandler xsi:type="ph:UsernamePassword" 
                  jaasConfigurationLocation="file:///home/asela/Wso2/shibboleth/conf/login.config">
        <ph:AuthenticationMethod>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ph:AuthenticationMethod>
    </ph:LoginHandler>


Step6. Configure logging level from logging.xml  file can be found at IDP_HOME/conf directory.  All the logs files would be saved at  IDP_HOME/logs.  This would probably help you to trouble shooting the issues.

Now let deploy idp.war file in a web application server.  Here i am using apache tomcat for this.  Please use tomcat 6.X.X as shibboleth is not tested with tomcat 7.X.X


Step7. Copy  IDP_HOME/lib/endorsed  directory in to tomcat root directory. 

Step8.  Enable HTTPS in tomcat.  Locate the server.xml at TOMCAT_HOME/conf directory and configure HTTPS connector.  Sample configuration would be as follows. 

<Connector port="8443"
           protocol="org.apache.coyote.http11.Http11Protocol"
           SSLImplementation="edu.internet2.middleware.security.tomcat6.DelegateToApplicationJSSEImplementation"
           scheme="https"
           SSLEnabled="true"
           clientAuth="false"
           keystoreFile="/home/asela/shibboleth/credentials/idp.jks"
           keystorePass="changeit" /> 

Step9. Copy idp.war  file in to  TOMCAT_HOME/webapp directory.

Step10. Start tomcat server  by running  catalina script. 

Step11. Check status of the server by using   https://localhost:8443/idp/status