Sunday, October 14, 2012

Understanding Load balancing


Imagine you have a retail web application running on a single application server
instance and that you average 10,000 customers a month. Your company decides to
run a TV advertisement and predicts that you may start getting 100,000 customers a
month. You’re tasked with making sure that the application can support this number
of users. In addition, your application needs to be highly available. To accomplish
these goals, you have to deploy multiple application server instances and balance
requests across them.
Load balancing is a way of balancing incoming load, or concurrent requests, across
multiple application server instances, making your applications scalable and highly
available. Scalability is a term used to describe the ability to make your application
handle more user load by adding hardware and/or creating redundant instances of
your application without having to change code. Load balancing can help scale your
application because you can add more servers for the load balancer to balance the
load across, increasing the amount of traffic your application can handle. High availability
is the ability to continue processing requests in the face of server failure.

The load balancer acts as a single point of entry into an application environment
as well as a traffic director for requests.




TYPES OF LOAD BALANCERS
Load balancing can be done in two primary ways: with a hardware load balancer or
with a software load balancer. Hardware load balancers are typically more expensive
but are also more reliable


Load balancers typically make a single IP address for a cluster visible to clients. The
load balancer maintains a map of internal (or virtual) IP addresses for each machine
in the cluster. When the load balancer receives a request, it rewrites the header to
point to a particular machine in the cluster. If a machine in the cluster is removed or fails, the
hardware load balancer has the ability to recognize the failure and avoid
routing requests to it.



Understanding JBOSS Clustering


Clustering is the act of running the same application on multiple application server
instances simultaneously with each application server being aware of the others in the
cluster. An application server that’s part of a cluster is known as a node. But just having
nodes aware of other nodes in a cluster isn’t interesting. The nodes in the cluster must
be able to communicate with each other to do something useful, such as replicating
state or providing failover capabilities. Before we dive into the specifics of the clustering
features that JBoss offers, let’s examine some of the fundamental concepts behind
clustering. And, because you can’t seem to talk about clustering without talking about
load balancing, let’s start with that.

Introduction to jboss clustering and load balancing


A single JBoss server can handle several hundred concurrent requests; but, if your
application has to scale to support multiple thousands of concurrent requests or
multiple millions of requests a day, then a single application server probably won’t
do the trick. JBoss enables you to simultaneously run your application on multiple
application servers. Requests going to your application can then be balanced across
these servers, and your application can also withstand individual server failures.
This deployment architecture allows you to achieve maximum scalability with minimal
downtime. Clients need not know that their different requests may be handled
by different servers.
Java EE doesn’t specify any standards for how clustering services should work.
Every application server implements clustering differently and provides a different
set of clustering capabilities and services. Red Hat has set out to make cluster setup a simple task. As you’ll learn in this chapter, clusters are easy to create in JBoss and
require minimal configuration. Adding nodes requires no administrative management
because nodes detect each other automatically over network protocols. JBoss
also provides a sophisticated distributed cache that allows stateful components to replicate
their states across multiple nodes in a cluster, enabling you to easily develop
fault-tolerant applications, with very little code.


Client cert authentication mechanism in JBOSS


This authentication mechanism is almost same as mutual authentication. But there are some differences between those two authentication mechanisms. In client cert authentication, we don’t have to enter usernames and passwords. Web browser keeps server certificates and verifies with certificate that the server sends at the beginning of a conversation.
Let’s see how to implement client cert authentication.
We have to edit some configuration files to achieve client cert authentication.
First we have to change the web.xml in the application. Add following authentication method within login-config tag. Other tags are remaining same as the mutual authentication.


<login-config>
        <auth-method>CLIENT-CERT</auth-method>
        <realm-name>JBoss JMX Console</realm-name>
    </login-config>


Go to following directory and open the server.xml file.

C:\jboss\jboss-eap-5.1\jboss-as\server\default\deploy\jbossweb.sar

Then find following tag and edit it as follows.

<Realm className="org.jboss.web.tomcat.security.JBossWebRealm"
            certificatePrincipal="org.jboss.security.auth.certs.SubjectCNMapping"
            allRolesMode="authOnly"/>       

Then create a security domain in login-config.xml as follows.


<application-policy name="simple-security-domain">
<authentication>
        <login-module code="org.jboss.security.auth.spi.BaseCertLoginModule"
                      flag="required">
            <module-option name="password-stacking">useFirstPass</module-option>
            <module-option name="securityDomain">java:/jaas/simple-security-domain</module-option>
        </login-module>
        <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule"
                      flag="required">
            <module-option name="password-stacking">useFirstPass</module-option>
            <module-option name="usersProperties">props/cert-user.properties</module-option>
            <module-option name="rolesProperties">props/cert-role.properties</module-option>
        </login-module>
    </authentication>
</application-policy>


We need to create two new properties files inside the props directory called cert-user.properties as cert-role.proerties. but the names can be any names whatever you like. In this case, cert-user.properties file should be empty.  Then open the cert-role.properties file and following things to that file.

Username=admin
Username2=guest

This username has some special things. This username should be same as the client certificate’s common name and the alias of client certificate that saved in server.trustore.
Then go to jboss-web.xml file in the application add security domain as discussed in early login module topics.
After that we have to add mbean into jboss server. This mbean is a service. So we have to add new xml file into following directory. File name of that xml should be somename-service.xml. In my case, the file name is jboss-service.xml.

C:\jboss\jboss-eap-5.1\jboss-as\server\default\deploy

Then add following code into the jboss-service.xml file.


<mbean code="org.jboss.security.plugins.JaasSecurityDomain"
       name="jboss.ch8:service=SecurityDomain">
    <constructor>
        <arg type="java.lang.String" value="simple-security-domain"/>
    </constructor>
    <attribute name="KeyStoreURL">${jboss.server.home.dir}/conf/server.truststore</attribute>
    <attribute name="KeyStorePass">password</attribute>
</mbean>


This password is the password for server.trustore.
We have described about client.pfx files in mutual authentication section. As described in that section, we have to import client.pfx file into the browser.
Now we are done with the client-cert login.

Mutual authentication in JBOSS


Run the commands below in the command prompt within default\conf directory. Copy keytool.exe, all the files in openssl/bin folder. 

Create a self signed client certificate
1).Create private key:

 openssl genrsa -des3 -out client.key 1024

2).Create a csr:

openssl req -new -key client.key -out client.csr –config openssl.cnf

3).Create the client certificate:

openssl x509 -req -days 365 -in client.csr -signkey client.key -out client.crt

            4). Convert client.key to client.pem 

openssl rsa -in client.key -out client.pem 

          5). Convert the certificate to .pfx

openssl pkcs12 -inkey client.pem -in client.crt -export -out    client.pfx

Go to internet explorer and import client.pfx. You will have to provide the password which you introduced when creating the pfx.  You can see it under personal certificates. Then you can save the client.crt inside server.keystore in default/conf. 


Security certificates and authentication in JBOSS


Before moving onto the client-cert authentication let’s have a basic idea about public key certificates.
In the previous authentication methods we could only encrypt authentication details at the best case.
That is insecure because an eavesdropper can read our content easily if they have the tools. So the content should also be encrypted as well. Server first sends its public key to the browser and browser encrypts the content with that key and the server decrypts. Problem with this protocol is that we don’t have the data source integrity.  Certification authorities are there to certify the identity of web servers.  Browser can verify that certificate with the available certificates.

The above mentioned authentication mechanism is called server only authentication because only the identity of the server is specified. Note that this authentication is done at the protocol level.

 First you have to find keytool.exe located at “C:\Java\jdk1.6.0_32\bin” and copy it to “C:\jboss-eap-5.1\jboss-as\server\default\conf”.

Change your command line working directory to the above and execute

     keytool -genkey -alias serverCert -keyalg RSA -validity 1500 –keystore server.keystore

This command creates a server certificate which is valid for 1500 days and stores it in server.keystore.
When you execute this you will be asked to fill some details and add a password to the key store.
 Locate server.xml at “C:\jboss-eap-5.1\jboss-as\server\default\deploy\jbossweb.sar” and include 

<Connector port="8443"
scheme="https"
secure="true"
clientAuth="false"
keystoreFile="${jboss.server.home.dir}/conf/server.keystore"
keystorePass="serverpass"
sslProtocol = "TLS" />

Under an existing connector element.  For the keystoreFile attribute you must provide the name of the key store you created before, to store server certificates and keystorepass should be key store’s password.
 Add a transport guarantee in the web.xml’s security constraint element.

<user-data-constraint>
  <description>Require SSL</description>
  <transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>

This guarantees that even we connect to an insecure port we are redirected to a secure port as specified in server.xml. You can either specify an auth-method in the web.xml or not. Now you can open the URL in your browser and see the http request is redirected to a port which handles https.
In addition to the server you can also authenticate the client. We have two type of mechanisms.. Those mechanisms will discussing in future articles.




Digest Authentication in JBOSS


This authentication mechanism is almost same as the basic authentication. But the different is, in basic authentication, we store password as plaintext. In digest, we store password after encrypted using encryption algorithm such as MD5. Let’s see how to create digest authentication login module.
First we have to change web.xml file. We have to add following code instead of basic authentication code.


<login-config>                                                                                                                                          
  <auth-method>DIGEST</auth-method>                                                                                                                    
  <realm-name> My Secure Content Authentication </realm-name>                                                                                                          
</login-config>


Then we should create new application policy for digest authentication. So we have to edit           login-config.xml file. So add following application-policy to the login-config.xml file.


<application-policy name="MyApp">
 <authentication>
 <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
 <module-option name="usersProperties">props/digest-users.properties</module-option>
 <module-option name="rolesProperties">props/digest-roles.properties</module-option>
 <module-option name="hashAlgorithm">MD5</module-option>
 <module-option name="hashEncoding">rfc2617</module-option>
 <module-option name="hashUserPassword">false</module-option>
 <module-option name="hashStorePassword">true</module-option>
 <module-option name="passwordIsA1Hash">true</module-option>
 <module-option name="storeDigestCallback">
 org.jboss.security.auth.spi.RFC2617Digest
            </module-option>
 </login-module>
 </authentication>
</application-policy>


According to the application policy name, edit the security domain in jboss-web.xml. In my case, security domain in MyApp.
Then we should encrypt the password. Because we need to store encrypted password. Then type following command. Then you will get encrypted password.

java –cp C:\jboss\jboss-eap-5.1\jboss-as\common\lib\jbosssx-server.jar / org.jboss.security.auth.spi.RFC2617Digest username "Realm name" password

Username= we have to give username
Password=Real password
Realm name= the realm name that we specify in web.xml.

Finally you have to store the hashed password as opposed to the plaintext password, in the users.properties file specified in the application policy. roles.properties file   remains same as that of basic authentication implemented with UserRolesLoginModule.