Friday, May 21, 2010

Redhat RHEL tomcat init script

Redhat RHEL tomcat init script

This is my effort to create a nice clean init script to start and stop tomcat for Redhat or RHEL servers.

Two file need to be created to get the init script working
  1. /etc/sysconfig/tomcat
  2. /etc/init.d/tomcat

First file - /etc/sysconfig/tomcat
--------------------------------------------------------------------------------------------------------------

# Environment variables needed for tomcat startup
# I have setup the following links
# /usr/lib/jvm/jdk to point to the present installation of java/jdk
# /opt/tomcat to point to /opt/apache-tomcat-version-no:

PATH=$PATH:/usr/lib/jvm/jdk/bin
JAVA_HOME="/usr/lib/jvm/jdk"
CATALINA_HOME="/opt/tomcat"
CATALINA_BASE="/opt/tomcat"

--------------------------------------------------------------------------------------------------------------

Second file - /etc/init.d/tomcat
--------------------------------------------------------------------------------------------------------------

#!/bin/bash
#
# tomcat
#
# chkconfig: 345 84 15
# description: Start up the Tomcat servlet engine.
# config: /etc/sysconfig/tomcat
# processname: tomcat
# pidfile: /var/run/tomcat.pid

# Source function library.
. /etc/init.d/functions

# Loading the configuration parameters.
if [ -f /etc/sysconfig/tomcat ]; then
. /etc/sysconfig/tomcat
fi

RETVAL=0

case "$1" in
start)
if [ -f $CATALINA_HOME/bin/startup.sh ];
then
logger -s "Starting Tomcat"
/bin/su -l tomcat -c $CATALINA_HOME/bin/startup.sh
RETVAL=$?
[ $RETVAL = 0 ] && touch /var/lock/subsys/tomcat
fi
;;
stop)
if [ -f $CATALINA_HOME/bin/shutdown.sh ];
then
logger -s "Stopping Tomcat"
/bin/su -l tomcat -c $CATALINA_HOME/bin/shutdown.sh
RETVAL=$?
[ $RETVAL = 0 ] && rm -f /var/lock/subsys/tomcat
fi
;;
restart)
$0 stop
$0 start
;;
version)
if [ -f $CATALINA_HOME/bin/version.sh ];
then
logger -s "Display Tomcat Version"
/bin/su -l tomcat -c $CATALINA_HOME/bin/version.sh
RETVAL=$?
fi
;;
*)
echo $"Usage: $0 {start|stop|restart|version}"
exit 1
;;
esac

exit $RETVAL

--------------------------------------------------------------------------------------------------------------

Installing

Once the above files have been created issue the command


chmod 755 /etc/init.d/tomcat
chkconfig --add tomcat
chkconfig --list tomcat

This will create the necessary links in the /etc/rcn.d directories

Lets now try and start and shutdown of tomcat.

service tomcat start
service tomcat stop
service tomcat stop

You can inspect the log file /var/log/messages. You should have log file entries there identifying the user who restarted tomcat
eg:

May 21 14:02:07 server1 bob : Stopping Tomcat
May 21 14:02:09 server1 bob : Starting Tomcat
May 21 14:05:34 server1 bob : Stopping Tomcat
May 21 14:06:14 server1 bob : Stopping Tomcat
May 21 14:06:42 server1 last message repeated 2 times
May 21 14:07:19 server1 bob : Starting Tomcat

Background

Ok Now finer details.
What runlevels does it start at and in which sequence
This is controlled by the below line in /etc/init.d/tomcat
# chkconfig: 345 84 15

The above line indicates tomcat should be started up in runlevels 3, 4, and 5.
That is what 345 in the above line signifies

Further more 84 and 15.
84 indicates the sequence number in which it needs to be started up.
15 indicates the sequence number in which it needs to be stopped.

The reasoning for choosing 84 for startup sequence.
The default start sequence number for Apache is 85
Knowing that I thought it would be most appropriate to give a sequence number of 84 so that tomcat would be started before Apache.

Environment Variable Used

PATH=$PATH:/usr/lib/jvm/jdk/bin
I have /usr/lib/jvm/jdk as a symlink to the java installation folder

JAVA_HOME="/usr/lib/jvm/jdk"
I have /usr/lib/jvm/jdk as a symlink to the java installation folder

CATALINA_HOME="/opt/tomcat"
CATALINA_BASE="/opt/tomcat"

Assumption is the tomcat tar file for tomcat is extracted to lets say /opt/apache-tomcat-6.0.26
I further have a symlink /opt/tomcat pointing to /opt/apache-tomcat-6.0.26
Hence why I have used /opt/tomcat for the catalina_home and _base environment variables
If you prefer using /usr/local/tomcat feel free to adjust accordingly


The symlinks allow you to upgrade java and tomcat, and not having to worry about your init scripts or your environment variables.
Once you have upgraded java and tomcat all you need to do is update your symlinks to point to the directory where you new version has been installed

--------------------------------------------------------------------------------------------------------------

Future Improvement

My wish list
  1. Incorporate a mechanism to be able to check the tomcat "status".
  2. Possibly incorporate a PID file.
Once the PID file has been incorporated, it might be easier to get the status checking added on to the init script.

--------------------------------------------------------------------------------------------------------------

Acknowledgements

The above was inspired from
http://www.raibledesigns.com/tomcat/boot-howto.html
Thank you.
I have taken the original script from the above link, extended it so it is slightly clearer, and I don't have to manually create the links in rc3.d etc.

Monday, October 19, 2009

IPhone Google Gmail sync along side Outlook Exchange Sync

I have been given an iPhone from work.
I do not want to start a discussion about what I like and don't like on an iPhone.

As it is a work phone it connects to my Exchange server at work, and keeps my mail, contacts, and my calendar in sync.

It is great, but I would like my Personal calendar from Gmail and my massive list of Contact from Outlook synched as well.

Gmail now supports the SyncML protocol and I could add it as an exchange server/connector to keep it in sync(mind my description), except for the fact that you can have only one exchange mail account configured on your iPhone.

Came across this free application on iPhone yesterday, which looked like it was going to solve my problem.
Synthesis SyncML Client for iPhone for iPhone and iPod Touch.
www.synthesis.ch


Installed it and used the following settings.

URL : https://m.google.com/syncml
SyncML Version : Automatic
Ignore SSL Error : ON
User Proxy : Off
User : (your gmail id>
Password : your gmail password
Legacy Mode : ON

For your user always include @gmail.com or @googlemail.com. If you are using google apps your full email id including your domain name should be used.

Again there is a drawback with this method that you will have to startup this application and issue a synchronisation manually. Hey it is better than nothing.

On the side note, if you infact set your exchange contacs as your default contacts folder in your iPhone, all the contacts you sync via syncML will get dumped into Exchange. This could be a great plus for people who would want to do that.

I figured it out after my first sync. I didn't quite want my personal contacts on my work exchange server. So had to change the default addressbook for my iPhone to point to the iPhone contacts and did a sync again. Now got to clean up my Exchange contacts folder at work :-(.

That is Contacts sorted.
As for calendars, I have configured my gmail calendar as a CalDav calendar.
Below are the setting.

Server : www.google.com
User Name: gmailid including domain name
Password : password
Use SSL : ON
Port : 443
Account URL : I believe it figures it out.

I spent a while trying to figure out how once can have both exchange and gmail both synchronised on my iPhone.

Hope this helps.

Saturday, October 17, 2009

Highly Available Load Balanced solution on Slicehost or Racksapce cloud servers

Setting up a pair of highly available load balanced website using Slicehost.

I embarked on setting this up as prototype or proof of concept.
My colleague/friend who runs his own business and has a website for which he was looking for some high availability and load balancing.

Below is the architecture..
I am making use of 4 virtual machines or servers.

dir0
dir1
web0
web1

The servers web0 and web1 will serve as a pool of web servers, which will be serving the website.

The 2 major components to make this happen are.
1. Load Balancing.
2. Failover

The load balancing software will be configured to run on either dir0 or dir1.
While the server dir0 is actively working as the load balancer, if disaster was to strike, we need to still carry on serving the web page. This is acheived by the failover component which will allow you to migrate the IP address to the standby server dir1 and start the load balancing software.

Some background information about working with Slicehost.
For the purpose of this exercise I am going to use the smallest slice "256 slice"
The distribution of choice was Debian 5.0 (lenny).

This article has got details regarding setting up iptables in debian lenny
http://articles.slicehost.com/2009/3/31/debian-lenny-setup-page-1



________|________
| |
######### #########
# dir-0 # # dir-1 #
######### #########


my configuration file
/etc/iptables.up.rules
Looks like this. I have enabled incoming SSH and HTTP
##############################################################################
# Generated by iptables-save v1.4.2 on Sat Oct 17 15:56:48 2009
*filter
:INPUT ACCEPT [140:10452]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [130:13960]
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -i ! lo -j REJECT --reject-with icmp-port-unreachable
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-port-unreachable
-A OUTPUT -j ACCEPT
COMMIT
# Completed on Sat Oct 17 15:56:48 2009
##############################################################################


edit the lo interface to start iptables.
add the below line to "lo" interface

pre-up iptables-restore < /etc/iptables.up.rules


Restarting networking gives an error.
######################################
Reconfiguring network interfaces...if-up.d/mountnfs[eth0]: waiting for interface eth1 before doing NFS mounts (warning).
SIOCADDRT: File exists
Failed to bring up eth1.
done.
######################################
Haven't figured out what this means, But eth1 seems to be working fine..


######################################

Ok Round 1.
Installing Linux-ha or heartbeat
The linux-ha project is a great framework to provide IP and service failover feature.
http://www.linux-ha.org/doc/

Install heartbeat on both dir0 and dir1

apt-get update
apt-get upgrade
# Just wanted to make sure that we are up to date before proceeding with the install.
apt-get install less
# funny the less package was missing..
# I guess it makes sense, it is a minimal install

apt-get install heartbeat-2

The following NEW packages will be installed:
file gawk heartbeat heartbeat-2 libdb4.5 libglib2.0-0 libglib2.0-data
libltdl3 libmagic1 libnet1 libopenhpi2 libpcre3 libperl5.10 libsensors3
libsnmp-base libsnmp15 libsqlite3-0 libsysfs2 libxml2 libxml2-utils
mime-support openhpid perl perl-modules psmisc python python-central
python-minimal python2.5 python2.5-minimal sgml-base ucf xml-core

Obtain sample configuration files which will help in setting up heartbeat
The sample configuration files are in /usr/share/doc/heartbheat.

cd /etc/ha.d/
cp /usr/share/doc/heartbeat/ha.cf.gz .
cp /usr/share/doc/heartbeat/haresources.gz .
cp /usr/share/doc/heartbeat/authkeys .
gunzip ha.cf.gz
gunzip haresources.gz


Setting up the authkeys

cd /etc/ha.d/
echo "auth 3" >> authkeys
echo "3 md5 some_random_string_which_would_be_hard_to_guess" >> authkeys
chmod 400 authkeys

You have to edit you ha.cf configuration file
To hav ethe bare minimum of the below line.

dir0 (/etc/ha.d/ha.cf)
----------------------------
logfile /var/log/ha-log
logfacility local0
keepalive 2
udpport 694
ucast eth1 10.176.100.160
auto_failback off
node dir0
node dir1
----------------------------

dir1 (/etc/ha.d/ha.cf)
----------------------------
logfile /var/log/ha-log
logfacility local0
keepalive 2
udpport 694
ucast eth1 10.176.100.79
auto_failback off
node dir0
node dir1
----------------------------

I tend to use ucast as I do not plan on increasing the number of nodes.

----------------------------------

Obtain a failover IP address from Slicehost
I was allocated 174.143.237.200

echo "dir0 174.143.237.200/24" >> /etc/ha.d/haresources

This should allow us to do a basic heartbeat setup with a failover ip.
You can start heartbeat on both machines. The above IP should be running on one of them.
Infact running on dir0 if you have started dir0 first.

You can initiate a continuous ping from your local machine to the IP address 174.143.237.200.
While the ping is going on, you can stop heartbeat on dir0 and the ip should failover to dir1. and vise-verse.

I didn't loose any ping packets, while relocating the virtual IP address to and fro between dir0 and dir1.

-----------------------------------


Ok now moving on to a director setup or a load balancer setup.
I am planning on using ldirectord for the loadbalancing.

If it just simple port 80 loadbalancer, then you can have either nginx or a balance script do the job for you.

I will see if I have time to try out both approaches.

---------------------------------------------

LDirector Load balancing.

apt-get install ldirectord-2
update-rc.d -f ldirectord remove

/etc/haresources
dir0 \
IPaddr2::174.143.237.200/24/eth0/174.143.237.255 \
ldirectord::ldirectord.cf


on the web nodes did the following
apt-get update
aptitude safe-upgrade
aptitude install apache2

ifconfig tunl0 172.26.20.110 netmask 255.255.255.255 broadcast 172.26.20.110 up
route add -host 172.26.20.110 dev tunl0

Director load balancing didn't work due to several reason..
Some of it.. was due to the flast that mac addresses were being cloned etc..

--------------------------------------------

Load Balancing - Option 2 - Balance Script

aptitude install balance
Install balance on both dir0 and dir1

http://www.inlab.de/balance.html
Balance script is very straight forward, one liner which will setup some port forwarding and load balancing for you.

Man page is available here http://linux.die.net/man/1/balance


The virtual IP 174.143.237.200 is generally migrated from dir0 to dir1 and vice-versa by heartbeat.
When the IP address is migrated over, heartbeat scripts should be able to easily stop and start the balance script on it's own. Given the fact that there is no init script and configuration file for balance, I couldn't be bothered to write one up which is lsb compliant.


Under normal circumstances I would use below command to startup balance.

balance -b 174.143.237.200 80 10.176.109.174 10.176.109.192

Given that i don't have an init script.
As a work around, I am starting balance using the below command.

balance -b 0.0.0.0 80 10.176.109.174 10.176.109.192

The above balance command will listen on any IP address at port 80 and forward the connections to the 2 ips mentioned there. I would have the above balance command running on both dir0 and dir1.

What this allows me to do is migrate the virtual IP 174.143.237.200, between dir0 and dir1 without having to meddle with the balance script.

There are additional questions of monitoring etc.. but then again this is only setup as a proof of concept.

--------------------------------------------------

Load Balancing - Option 3 - HAProxy
http://www.haproxy.org/

aptitude install haproxy
update-rc.d -f haproxy remove

On both dir0 and dir1 install haproxy and remove it from starting up automatically.

enable haproxy in /etc/default/haproxy
All you need to do is set ENABLED=1

sed -i s/ENABLED=0/ENABLED=1/ /etc/default/haproxy

the haproxy configuration files needs to be setup.
The configuration file is located in /etc/haproxy/haproxy.cfg

The key section from the configuration file /etc/haproxy/haproxy.cfg is

listen ha.sushilsuresh.co.uk 174.143.237.200:80
balance roundrobin
stats enable
server web0 174.143.238.24:80 check inter 20 rise 2 fall 2
server web1 174.143.238.66:80 check inter 20 rise 2 fall 2

Finally I had to configure heartbeat to start and stop haproxy when heartbeat starts or stops.
The only configuration file that needs to be changed is
/etc/ha.d/haresources

dir0 \
IPaddr2::174.143.237.200/24/eth0/174.143.237.255 \
haproxy

Heartbeat is capable of calling the haproxy init script in /etc/init.d/

--------------------------------------------------

Testing

while true; do curl http://ha.sushilsuresh.co.uk; done
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web0 - It works!

While things are ticking along...
Trying stopping and starting apache on web1 and web2.
You should see corresponding changes in the output of the curl command.
Stopping apache web0 resulted in the below output from curl

Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!
Web1 - It works!

Again while the above curl was running,
I tried to failover the IP from dir0 to dir1.
Either by stopping heartbeat on dir0 or rebooting dir0

Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
curl: (7) couldn't connect to host
Web0 - It works!
Web1 - It works!
Web0 - It works!
Web1 - It works!

As you can see I missed about 5 consecutive curls and things were back to normal.

-----------------------------------

Load Balancing - Option 4 - Nginx Proxy Parse

Nginx has got the ability to load balance by making use of the httpd proxy module.
http://wiki.nginx.org/NginxHttpProxyModule

apt-get install nginx
update-rc.d -f nginx remove

The main configuration can fine needs to be edited.
/etc/nginx/nginx.conf

http {
default_type application/octet-stream;


upstream backend {
server 10.176.109.174 weight=10 max_fails=3 fail_timeout=10s;
server 10.176.109.192 weight=10 max_fails=3 fail_timeout=10s;
}

server {
location / {
proxy_pass http://backend;
}
}

include /etc/nginx/conf.d/*.conf;
}


nginx failover can also be achieved using the keepalived
The below url did interest me.. but just documenting it for now.
http://www.cyberciti.biz/faq/handling-nginx-failover-with-keepalived/

for now, I have just configured,, nginx to be started by heartbead within.
/etc/ha.d/haresource

----------------------------------------------------------------


balance
One liner very easy to setup... but lack a lot of features..

HAProxy
Very feature rich.
flexible and has got a nice admin interface to view statistics

nginx
very lightweight, and can hand a lot of user connections with ease.
Has a got reasonable features, but not as feature rich as HAProxy.

Thursday, July 30, 2009

Munin

2 packages are needed

munin - (is the servers side of the software which draws the pretty graph)
munin-node - (the agent or client software which runs on each of your nodes)

On the client machines
tcp port 4949 needs to be opened up

the configuration file /etc/munin/munin-node.conf needs to have an allow line which indicates the IP address of the munin data gathering server.

allow ^192\.168\.30\.34$

On the munin server the main configuration file /etc/munin/munin.conf should have a host entry similar to below.

[vm1]
address 192.168.30.34
use_node_name yes

CentOS5 dag adding rpmforge repository

Install DAG GPG key

wget http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt # download DAG GPG key
rpm --import RPM-GPG-KEY.dag.txt # import the key
rm RPM-GPG-KEY.dag.txt # clean up after ourselves


Install yum-priorities

yum install yum-priorities


Download and install package (x86_64 - 64bit)

wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
rpm -Uhv rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm # install the rpmforge yum repo
rm rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm # clean up after ourselves


Set priorities

vim /etc/yum.repos.d/CentOS-Base.repo
[base] or [updates] or [addons] or [extras]
priority=1
[centosplus]
priority=2
vim /etc/yum.repos.d/rpmforge.repo
[rpmforge]
priority=10


yum makecache
will update the local cache as well.


The above has been ripped off from the below website.

http://www.ultranetsolutions.com/CentOS-5-install-rpmforge-yum-repo.html

Thanks very much, but not sure if you will ever take down the page.

Thursday, June 25, 2009

Linux apache convert .pfx certificate files to openssl

Copy the .pfx file to the apache webserver or a linux server which has openssl installed.

To convert the .pfx file for the domain foo.bar to a file that your Apache server will understand run the following openssl commands

1. To export the Private key file from the .pfx file
openssl pkcs12 -in foo.bar.pfx -nocerts -out foo.bar.key

2. To export the Certificate file from the .pfx file
openssl pkcs12 -in foo.bar.pfx -clcerts -nokeys -out foo.bar.crt

Thursday, June 04, 2009

website page load time

Handy curl command that can be used to figure out times...

I will have to look up on the additional time parameters used by curl and document them here.. but quite usefull

curl -w '\nLookup time:\t%{time_namelookup}\nConnect time:\t%{time_connect}\nPreXfert time:\t%{time_pretransfer}\nStartXfer time:\t%{time_starttransfer}\n\nTotal time:\t%{time_total}\n' -o /dev/null -s http://blog.sushilsuresh.co.uk

A more elegant way where you can see read and understand what each line does.

curl -w '
Lookup time:\t%{time_namelookup}
Connect time:\t%{time_connect}
PreXfer time:\t%{time_pretransfer}
StartXfer time:\t%{time_starttransfer}

Total time:\t%{time_total}

' -o /dev/null -s http://blog.sushilsuresh.co.uk


The output of the above command looks like

Lookup time: 0.002
Connect time: 0.016
PreXfert0.016
StartXfer time: 0.413

Total time: 0.831

Thursday, April 30, 2009

tcpdump

tcpdump -vvv -i eth0 port 80 and host www.google.co.uk

nmap can issue searches from a different by using the -S option

need to populate as an when.