Shell Script To Monitor Services Such As Web / Http, Ssh, Mail Server

#!/bin/bash
# Shell script to monitor running services such as web/http, ssh, mail etc.
# If service fails it will send an Email to ADMIN user
# -------------------------------------------------------------------------
# Copyright (c) 2006 nixCraft project <http://www.cyberciti.biz/fb/>
# This script is licensed under GNU GPL version 2.0 or above
# -------------------------------------------------------------------------
# This script is part of nixCraft shell script collection (NSSC)
# Visit http://bash.cyberciti.biz/ for more information.
# ----------------------------------------------------------------------
# See URL for more info
# http://www.cyberciti.biz/tips/processing-the-delimited-files-using-cut-and-awk.html
# ---------------------------------------------------
# Last updated: Jun - 15 - 2009.
ports="22 53 80 25"
 
# service names as per above ports
service="SSH DNS WEB MAIL"
 
#Email id to send alert
ADMINEMAIL="admin@myispname.com"
 
#Bin paths, set them according to your Linux distro
NETSTAT=/bin/netstat
MAIL=/usr/bin/mail
LOGGER=/usr/bin/logger
ID=/usr/bin/id
 
# Red hat usr uncomment
MAIL=/bin/mail
LOGGER=/bin/logger
 
#Counters, set defaults
c=1
status=""
sendmail=0
 
# set the following to 1, if you want message in /var/log/messages via a SYSLOG
logtosyslog=0
 
# Log file used to send an email
LOG="/tmp/services.log.$$"
 
# log message to screen and a log file
log(){
	echo "$@"
	echo "$@" >> $LOG
}
 
# log message and stop script
die(){
	echo "$@"
	exit 999
}
 
# Make sure only root can run it
is_root(){
	local id=$($ID -u)
	[ $id -ne 0 ]  && die "You must be root to run $0."
}
# Look out for all bins and create a log file
init_script(){
	[ ! -x $MAIL ] && die "$MAIL command not found."
	[ ! -x $NETSTAT ] && die "$NETSTAT command not found."
	[ ! -x $LOGGER ] && die "$LOGGER command not found."
	[ ! -x $ID ] && die "$ID command not found."
	is_root
	>$LOG
}
 
# check for all running services and shoot an email if service is not running
chk_services(){
	log "-------------------------------------------------------------"
	log "Running services status @ $(hostname) [ $(date) ]"
	log "-------------------------------------------------------------"
 
	# get open ports
	RPORTS=$($NETSTAT -tulpn -A inet | grep -vE '^Active|Proto' | grep 'LISTEN' | awk '{ print $4}' | cut -d: -f2 | sed '/^$/d' | sort  -u)
 
	# okay let us compare them
	for t in $ports
	do
		sname=$(echo $service | cut -d' ' -f$c)
		echo -en " $sname\t\t\t : "
		echo -en " $sname\t\t\t : " >> $LOG
		for r in $RPORTS
		do
			if [ "$r" == "$t" ]
			then
				status="YES"
				sendmail=1
				break
			fi
		done
		echo -n "$status"
		echo ""
		echo -n "$status" >>$LOG
		echo "" >>$LOG
		# Log to a syslog /var/log/messages?
		# This is useful if you have a dedicated syslog server
		[ $logtosyslog -eq 1  ] && $LOGGER "$sname service running : $status"
 
		# Update counters for next round
		c=$( expr $c + 1 )
		status="NO"
	done
	log "-------------------------------------------------------------"
	log "This is an automatically generated $(uname) service status notification by $0 script."
 
	if [ $sendmail -eq 1 ];
	then
		$MAIL -s "Service Down @ $(hostname)" $ADMINEMAIL < $LOG
	fi
}
 
### main ###
init_script
chk_services
 
### remove a log file ###
[ -f $LOG ] && /bin/rm -f $LOG

Featured Articles:

Want to read Linux tips and tricks, but don't have time to check our blog everyday? Subscribe to our email newsletter to make sure you don't miss a single tip/tricks.

{ 21 comments… read them below or add one }

1 Streametch June 15, 2009 at 8:47 am

Hey, this script not workin under CentOS 4.7, script messaged all service is down:
-bash-3.00# sh test_script.sh
Running services status:
SSH: No
WEB: No
MAIL: No
-bash-3.00#
But all services works fine, can you help me?

Reply

2 Vivek Gite June 15, 2009 at 2:19 pm

Try updated script. Let me know if you need any other help.

Reply

3 Streametch June 18, 2009 at 4:08 pm

Hey,
Thanks, now it work, but I have issue with only ssh. I run sshd service on non-standart port, and replace 22 port with my settings. After thant when I run this script I got blank value.
————————————————————-
Running services status @ server.****.com [ Thu Jun 18 19:07:24 EEST 2009 ]
————————————————————-
SSH :
WEB : YES
MAIL : YES
————————————————————-
This is an automatically generated Linux service status notification by checkstatus script.
And got fake alert :( Can you help me?

Reply

4 Vivek Gite June 18, 2009 at 4:30 pm

Replace port 22 with your actual port such as #3922 in $ports i.e. from

ports="22 80 25"

To:

ports="3922 80 25"

Reply

5 Streametch June 18, 2009 at 4:38 pm

Yeah, I do that at once, but still get nothing about ssh

Reply

6 Streametch June 19, 2009 at 9:11 am

-bash-3.00# sh /srv/chkserv
————————————————————-
Running services status @ server.*****.com [ Fri Jun 19 12:08:57 EEST 2009 ]
————————————————————-
SSH :
WEB : YES
MAIL : YES
————————————————————-
This is an automatically generated Linux service status notification by /srv/chkserv script.
-bash-3.00# grep Port /etc/ssh/sshd_config
Port 22
#GatewayPorts no
-bash-3.00# ps aux|grep ssh
root 16151 0.0 0.0 7004 2284 ? Ss 12:07 0:00 sshd: root@ttyp0
root 23653 0.0 0.0 4624 632 ttyp0 S+ 12:09 0:00 grep ssh
root 28047 0.0 0.0 4140 1044 ? Ss Jun18 0:00 /usr/sbin/sshd

Reply

7 Vivek Gite June 19, 2009 at 9:41 am

Correct way to run script is either:
chmod +x /srv/chkserv
/srv/chkserv

OR
bash /srv/chkserv
To find current sshd port enter:
netstat -tulpn

8 Streametch June 19, 2009 at 10:57 am

-bash-3.00# chmod +x /srv/chkserv
-bash-3.00# /srv/chkserv
————————————————————-
Running services status @ server.*****.com [ Fri Jun 19 13:53:11 EEST 2009 ]
————————————————————-
SSH :
WEB : YES
MAIL : YES
————————————————————-
This is an automatically generated Linux service status notification by /srv/chkserv script.
-bash-3.00# bash /srv/chkserv
————————————————————-
Running services status @ server.*****.com [ Fri Jun 19 13:53:23 EEST 2009 ]
————————————————————-
SSH :
WEB : YES
MAIL : YES
————————————————————-
This is an automatically generated Linux service status notification by /srv/chkserv script.
-bash-3.00# netstat -tulpn |grep ssh
tcp 0 0 :::22 :::* LISTEN 9262/sshd
-bash-3.00# grep port /srv/chkserv
ports=”22 80 25″

Any idea?

Reply

9 Streametch June 19, 2009 at 11:29 am

So now, I replace Ports in script to:
ports=”80 25 22″
And Services to:
service=”WEB MAIL SSH”
And re-run script:
-bash-3.00# /srv/chkserv
————————————————————-
Running services status @ server.*****.com [ Fri Jun 19 14:27:53 EEST 2009 ]
————————————————————-
WEB : YES
MAIL : YES
SSH : NO
————————————————————-
This is an automatically generated Linux service status notification by /srv/chkserv script.

I don’t know why :(

Reply

10 Vivek Gite June 19, 2009 at 12:38 pm

Ok, I will look at the script this week end and see if there is any bug that is shooting an email even if service is running.

Reply

11 Streametch July 10, 2009 at 8:18 pm

Any updates?

Reply

12 Vivek Gite July 14, 2009 at 7:34 am

I’ve tweaked it further. Can you test it again?

./svrmon.sh
Outputs:

-------------------------------------------------------------
Running services status @ www031.xxxtopxxxxx.net [ Tue Jul 14 02:30:24 CDT 2009 ]
-------------------------------------------------------------
 SSH			 : YES
 DNS			 : YES
 WEB			 : YES
 MAIL			 : YES
-------------------------------------------------------------
This is an automatically generated Linux service status notification by /tmp/svrmon.sh script.

Stop named:
# service named stop
Run it again:

-------------------------------------------------------------
Running services status @ www031.xxxtopxxxxx.net [ Tue Jul 14 02:30:24 CDT 2009 ]
-------------------------------------------------------------
 SSH			 : YES
 DNS			 : NO
 WEB			 : YES
 MAIL			 : YES
-------------------------------------------------------------
This is an automatically generated Linux service status notification by /tmp/svrmon.sh script.

Reply

13 Smile4u July 14, 2009 at 7:07 am

There is an error in the “init_script”-section:
[ ! -x $NETSTAT ] && die “$MAIL command not found.”
should be like this
[ ! -x $NETSTAT ] && die “$NETSTAT command not found.”

Reply

14 Vivek Gite July 14, 2009 at 7:37 am

Thanks for the heads-up!

Reply

15 FarhanFaisal October 1, 2009 at 3:32 am

I got the same problem and I’m on FreeBSD. I modified the netstat command part, changed to this.

RPORTS=$($NETSTAT -ant -A inet | grep ‘LISTEN’ | awk ‘{ print $5}’ | cut -d’.’ -f2 | sed ‘/^$/d’ | sort -u)

But I still got problem, because of different way those services were initiated. My DNS configured to listen on specific address. So, DNS entry in netstat will be
XXX.XXX.XXX.XXX.53
but some other service like smtp will have
*.25

I still prefer a script that can monitor the port itself, checking whether its open or not.

Reply

16 Fernando Hallberg October 2, 2009 at 9:39 pm

Hi,

This script sendmail at services is UP, and not if one of services is DOWN! :D

I remove the send mail lines and create a external check for a NO ocurrence, and if exists send mail for the administrators and restart services :D

Regards,

Fernando

Reply

17 hadi February 10, 2010 at 5:22 am

hi.. can you send to me the external script to my email hadi.utomo@gmail.com

Reply

18 Jonas Holmgren October 7, 2009 at 10:47 am

Try with

RPORTS="`nmap -sT $(ifconfig | grep 'inet addr:' | grep -v '127.0.0.1' | cut -f2 -d: | awk '{ print $1}') 2>/dev/null | awk '/^[0-9]/ {print $1}' | cut -f1 -d/`"

Regards,
Jonas

Reply

19 Jonas Holmgren October 7, 2009 at 11:03 am

Note that due to the SLQ Injection protection in this forum, the opening apostrophes were replaced with back-quotes. What you see on the screen is correct, but you can’t copy and paste it into your script.

Reply

20 Vivek Gite October 14, 2009 at 6:26 am

You can always download script file.

Reply

21 Naleen November 18, 2009 at 7:45 pm

This script worked first time for me, no probs at all.
no modification needed apart from email address, very nice !!!!

Reply

Previous post:

Next post: