Thursday, November 12, 2009

Apache HTTP Server Installation and Configuration on Red Hat Linux

In the early days of my career I had the impression that apache http server is a part of apache tomcat server. But those are completely two different products. 
I’m very much familiar with tomcat, but never had any chance to install and configure apache http server from scratch. In my current project, we wanted to secure our application by switching to https from http. The application is running on Jboss. So, there are two choices: - either configure Jboss for https or use apache http server to do that job. If the apache http server is configured to https, it will redirect the requests to Jboss. So, we opted for the second option:- to use http server.It was not an easy task for me, but finally I managed to accomplish it with lot of googling and
trial and error methods. In this blog entry, I‘ll share my experience.

Apache HTTP Server Installation
First we need to install apache http server. If you are installing on windows, it is very easy. Just few clicks and you are done. But, unfortunately the actual pain will start once you change the httpd.conf file for SSL configuration. The apache http service will not start with some stupid message and you are stuck. So, my advice is to download the apache http binaries for Linux or Solaris boxes. I did on Red Hat Linux box, so I’ll note down the steps:-
  • Download latest version of binaries (I used httpd-2.0.63.tar.gz) from apache http website.
  • Copy it in /tmp directory.
  • Extract it using the command  tar -xvzf httpd-2.0.63.tar.gz
  • A directory httpd-2.0.63 will be created.
  • Go to the directory /tmp/httpd-2.0.63
  • Execute the below commands step by step:-
            1) make clean
            2) ./configure --enable-rewrite --enable-ssl --with-ssl
            3) make
            4) make install

Note that you need root access to execute the above commands. The above process will create an Apache server in /usr/local/apache2 directory.
So, apache is ready with SSL and rewrite modules.


Private Key and Certificate Generation
Now, we need the keys and certificates for the SSL.JDK ships with a utility called keytool which is used to create and manage encryption keys and certificates. We need to do the following:-
  • Use the keytool utility to create a RSA key pair (public key and private key). Here are the sample command :-
           [root@box sctool]# cd /tmp/jks/
           [root@box jks]# /usr/java/jdk1.6.0_16/bin/keytool -genkeypair -alias myapp.alias -dname         
           "CN=myboxname.com, OU=Department, O=XYZ Bank, L=Singapore, ST=Singapore, C=SG" -keystore 
            mykeystore.jks
            Enter keystore password:
            Re-enter new password:
            Enter key password for
            (RETURN if same as keystore password):
            [root@box jks]# ls
            mykeystore.jks

            [root@box jks]# /usr/java/jdk1.6.0_16/bin/keytool -list -keystore mykeystore.jks
            Enter keystore password:
            Keystore type: JKS
            Keystore provider: SUN
            Your keystore contains 1 entry
            myapp.alias, Nov 3, 2009, PrivateKeyEntry,
            Certificate fingerprint (MD5): AD:85:96:0F:33:BB:35:BF:5B:0D:C9:92:21:1F:A2:61

            Please note the name myboxname.com . It must exactly match with the host name of the  box on which the  application will be running. In, my case, myboxname.com is the             hostname of the box on which JBoss server   is running. The application URL will                         be something like https://myboxname.com/myappname. So, give extra  attention                         while creating key pairs.
  • We need to generate a csr file from the public key.
            [root@box jks]# /usr/java/jdk1.6.0_16/bin/keytool -certreq -alias myapp.alias -file myapp.csr -keystore             mykeystore.jks
            Enter keystore password:
            [root@box jks]# ls
            myapp.csr mykeystore.jks
            [root@box jks]#
            The myapp.csr looks similar to below
            [root@box jks]# more myapp.csr

            -----BEGIN NEW CERTIFICATE REQUEST-----             MIICejCCAjgCAQAwdTELMAkGA1UEBhMCU0cxEjAQBgNVBAgTCVNpbmdhcG9yZTESMBAGA1UEBxMJ U2luZ2Fwb3JlMREwDwYDVQQKEwhYWVogQmFuazETMBEGA1UECxMKRGVwYXJ0bWVudDEWMBQGA1UEAxMNb
XlhcHBuYW1lLmNvbTCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn
9hG3UjzvRADDHj+AtlEmaUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gE
exAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIV
AJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlXTAs9B4Jn
UVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi
8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQCtlvqZD0z9Jvjn
ShxfqpnXooCmP0ncVEog/yGYJ3irytzI0EERTKxeYq6tUCwUWlr1xq1worOp94m/ETJFJYPkAUkA
qaLorCStyhsD+tS+jmFa2nr1ywAErcZJ7qTDoYPWLXRB8jpo3fwzfSx66roSwPwarrWP1ZLP93+H
w9LZq6AAMAsGByqGSM44BAMFAAMvADAsAhQ50JZ11KPJ0S0ZN4BAF08btQfGYAIUNVFJCuiomeR3
99xnK/vS9tZ5/uE=
            -----END NEW CERTIFICATE REQUEST-----
            [root@box jks]#

      Submit the myapp.csr file to the certificate issuer. If it is an internet application, you need to get certificate  from venders like VeriSign or any other venders. If it is intranet application, there might that some security department in your organization who can issue a certificate for you. Or else you can create your own using openssl.
  • The private key is also needed in RSA format, not in PKCS#8 format.
We need to extract the private key from mykeystore.jks file against the alias myapp.alias.Please have a look into the below link on how to extract the private key http://conshell.net/wiki/index.php/Keytool_to_OpenSSL_Conversion_tips There is a free tool to extract the private key. http://yellowcat1.free.fr/index_ktl.html. Use java Web start to  launch the application



  Screen shots to extract the private key




We need the private key in RSA format, because apache does not understand PKCS#8 PEM format. So, finally, we get three files out of the above exercise:-
            1. root.cer
            2. myapp.cer
            3. myapp.key 





Configuring /usr/local/apache2


1. Create www directory under /usr/local/apache2
2. Create myapp directory under /usr/local/apache2/www.
3. Create ssl.crt directory under /usr/local/apache2.
4. Copy the 3 files in /usr/local/apache2/ssl.crt directory. 

                        (1)root.cer 
                        (2)myapp.cer
                        (3)myapp.key
5. Copy mod_jk.so to /usr/local/apache2/modules.
6. Copy workers.properties to /usr/local/apache2/conf. The content is
                 worker.list=jboss_ajp13
                 worker.jboss_ajp13.port=8009
                 worker.jboss_ajp13.host= myboxname.com
                 worker.jboss_ajp13.type=ajp13

7. Append the below entries /usr/local/apache2/conf httpd.conf file
                 NameVirtualHost *:80
                 NameVirtualHost *:443

                 <VirtualHost *:443>
 
                    ServerName myboxname.com
                     SSLEngine on
                     SSLOptions +StdEnvVars +ExportCertData +StrictRequire
                     SSLCertificateFile /usr/local/apache2/ssl.crt/ myapp.cer
                     SSLCertificateKeyFile /usr/local/apache2/ssl.crt/myapp.key
                     SSLCertificateChainFile /usr/local/apache2/ssl.crt/root.cer
                     DocumentRoot /usr/local/apache2/www/myapp
                     ErrorLog /usr/local/apache2/logs/myapp-error_log
                     CustomLog /usr/local/apache2/logs/myapp-access_log common
                     <IfModule mod_jk.c>
                             JkMount /* jboss_ajp13
                     </IfModule>
                 </VirtualHost>

                 <VirtualHost *:80 >
                     RewriteEngine On
                     RewriteCond %{HTTPS} off
                     RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}myappname
                     DocumentRoot  /usr/local/apache2/www/myapp
                     ServerName  myboxname.com
                     ErrorLog /usr/local/apache2/logs/xyz-error_log
                     CustomLog /usr/local/apache2/logs/xyz-access_log common
                 </VirtualHost>

8.Restart apache2
       /usr/local/apache2/bin/apachectl restart




Conclusion 
So, now we are ready to go. Apache http server is running on port 80 and Jboss is running on 8080. So, all requests to apache will be forwarded to jboss application server.
https://myboxname.com/myappname


No comments: