#!/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 # https://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,inet6 | 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
Get the latest tutorials on SysAdmin, Linux/Unix, Open Source, and DevOps topics:
- RSS feed or Weekly email newsletter
- Share on Twitter • Facebook • 33 comments... add one ↓
Category | List of Unix and Linux commands |
---|---|
File Management | cat |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Network Utilities | dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • jobs • killall • kill • pidof • pstree • pwdx • time |
Searching | grep • whereis • which |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
Will this work to check for any webservices exposed by a server.
Hi,
Can we check through shell script if certain web service are up or not ?
Regards,
Amar Sharma
Had problem with httpd not using a set ip and with the command in script above does not find services that don’t have them attached to an ip. So I have fixed this with the following command.
On .el5 this is not working . Only SMTP status printed properly.
RPORTS=$($NETSTAT -tulpn | grep -vE ‘^Active|Proto’ | grep ‘LISTEN’ | awk ‘{ print $4}’ | sed ‘s/[0-9a-z\.\:]*\:\([0-9]\+\)$/\1/’ | sort -u)
Hi,
You have a couple of bugs.
1. The script sends whenever at least one process is UP, you want the opposite.
2 You need to set status to ‘NO’ at the beginning of the loop rather than the end, otherwise if the first service is down it will have a status of empty string.
3. I would recommend using variables more descriptive than a single character, it will make it easier to read.
Here are the changes you need to make (note that I renamed the c variable to ‘count’):
# okay let us compare them
for t in $ports
do
status=”NO”
sname=$(echo $service | cut -d’ ‘ -f$count)
echo -en ” $sname\t\t\t : ”
echo -en ” $sname\t\t\t : ” >> $LOG
for r in $RPORTS
do
if [ “$r” == “$t” ]
then
status=”YES”
break
fi
done
if [ “$status” == “NO” ]
then
sendmail=1
fi
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
count=$( expr $count + 1 )
done
Whoops forgot to use the code blocks
# okay let us compare them
for t in $ports
do
status="NO"
sname=$(echo $service | cut -d' ' -f$count)
echo -en " $sname\t\t\t : "
echo -en " $sname\t\t\t : " >> $LOG
for r in $RPORTS
do
if [ "$r" == "$t" ]
then
status="YES"
break
fi
done
if [ "$status" == "NO" ]
then
sendmail=1
fi
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
count=$( expr $count + 1 )
done
Hi Smeven,
Thanks a lot…its worked Fine…:)
We want ot chane #get open ports section to
RPORTS=$($NETSTAT -tulapn -A inet,inet6 | grep -vE ‘^Active|Proto’ | grep ‘LISTEN’ | awk ‘{ print $4}’ | cut -d: -f2,4 | cut -d: -f2 | sed ‘/^$/d’ | sort -u) .Then only it will works on Ipv6..
Regards,
Shaiju
My experience is that if a port of a running service dosn’t show up in the netstat line, it’s because it’s not using the protocol inet, but inet6 istead.
try netstat -tulpn -A inet,inet6 , but the some modifications to the cut part of this line has to be done also.
cut -d: -f2 would fail because of the format of inet6 is different , try cut -d: -f2,4 | cut -d: -f2 instead.
It’s emailing me even when all services are up:
$ sudo ./monitor.sh
————————————————————-
Running services status @ sabresboard [ Fri Apr 9 18:50:43 EDT 2010 ]
————————————————————-
SSH : YES
WEB : YES
MAIL : YES
————————————————————-
This is an automatically generated Linux service status notification by ./monitor.sh script
Still sends me an email.
Hi thanks for the script..
How to monitor a new port using the scrip.i want to monitor 8080,and i changed port in the ports=”22 53 80 8080″
when running the script it is showing that
SSH : YES
DNS : YES
WEB : YES
tomcat : NO
please help me
Regards
Shaiju
This script worked first time for me, no probs at all.
no modification needed apart from email address, very nice !!!!
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.
You can always download script file.
Try with
Regards,
Jonas
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
hi.. can you send to me the external script to my email hadi.utomo@gmail.com
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.
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.”
Thanks for the heads-up!
Any updates?
I’ve tweaked it further. Can you test it again?
./svrmon.sh
Outputs:
Stop named:
# service named stop
Run it again:
-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?
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 :(
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.
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?
Replace port 22 with your actual port such as #3922 in $ports i.e. from
To:
Yeah, I do that at once, but still get nothing about ssh
-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
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
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?
Try updated script. Let me know if you need any other help.
Where is updated scripts