#!/bin/perl # # name : /secure/monitor_processes.pl # # History : # <4> Apr.26'99 (S.Boran) # Adapt for RedHat6.1 and OpenBSD2.6 # <3> V1.3 Apr.20'99 (S.Boran) # Bug fix: did not detect missing inetd # <2> V1.2 Oct.15'93 (S.Boran) # Fix: process running more that 99 mins not seen # <1> V1.1 Oct.14'93 (S.Boran) # FCS: tested on 4.1.3 & 5.2 SunOS # # FUNCTION: Check to see if a list of processes are running. # If not, send a message to syslog (if syslog is not # running, send a mail). # [syslogd is monitored even if not listed] # The list is given on the command line, but also # has defaults set below. # Runs on solaris 1 &2. # $user = 'root you@yourdomain.com'; # --- security precautions --- $ENV{'PATH'} = '/usr/bin'; $ENV{'SHELL'} = '/bin/sh' if $ENV{'SHELL'} ne ''; $ENV{'IFS'} = '' if $ENV{'IFS'} ne ''; umask(077); # -rw------- # ----------------- variable setup --------------- $debug = ''; # '1' for debug, '' for no debug info $debug2 = ''; # very detailed debugging $host = `uname -n`; $subject = "Processes dead on $host"; chop($host); $syslog_priority = 'warning|daemon' ; @proc_list = @ARGV; if (@proc_list == 0) { # are there any args ? set defaults @proc_list = ('inetd','sshd'); } push(@proc_list, 'syslogd'); # ALWAYS check for syslog - we use it! print "Searching for: @proc_list\n" if $debug; foreach $process (@proc_list) { $event_count{$process} = 0; } ## OS specific settings chop($os_ver=`uname -r`); chop($os=`uname -s`); print "OS=$os, version $os_ver detected.\n" if $debug; if ($os =~ /BSD/) { $mail='/usr/bin/mailx'; $ps_options = '/bin/ps -ax'; $pattern = '(.+ +\d+:\d\d.\d\d )(.*)'; } elsif ($os =~ /Linux/) { $mail='/bin/mail'; $ps_options = '/bin/ps -ax'; } else { ## assume Sun if ($os_ver =~ /4\.1\.\d/) { $mail='/usr/ucb/mail'; $ps_options = '/bin/usr/ps -ax'; $pattern = '(.+ +\d+:\d\d )(.*)'; } elsif ($os_ver =~ /5\.\d/) { # assume Solaris 2 (SVR4) $mail='/usr/bin/mailx'; $ps_options = '/usr/bin/ps -ef'; $pattern = '(.+ +\d+:\d\d )(.*)'; print "OS= Solaris 2.x\n" if $debug; } else { print "OS=$os, version $os_ver is not supported!\n"; exit -1; } } # ---------- call "ps" & analyse output ------------- open(PS, "$ps_options |") || die "can't run ps: __FILE__ $!\n"; $/="\n"; # record seperator while ($_ = ) { print "Pattern=$pattern, line=$_" if $debug2; # <3> don't want to analyse my own process!! next if (/monitor_processes.pl/); # $pattern is defined above. # $1 = anything spaces manydigits : digit digit onespace <2> # $2 = rest of line if (/$pattern/) { print "Process: '$2'\n" if $debug2; foreach $process (@proc_list) { if ($2 =~ /$process/) { $event_count{$process}++; # count occurrences } } } } close(PS); # now inform about any process not running. # If syslog is running use 'logger' else # send email to root $tmp_var=""; foreach $process (@proc_list) { if ($event_count{$process} == 0) { $tmp_var = $tmp_var . "WARNING: Process '$process' is NOT running!\n"; print "WARNING: Process '$process' is NOT running!\n" if $debug; } } if ($event_count{'syslogd'} != 0){ # syslog OK! # syslog is last in @proc_list # &syslog() doesn't work on solaris 2.. foreach $process (@proc_list) { if ($event_count{$process} == 0) { if ($debug) { print "WARNING: Process '$process' is NOT running!\n"; } else { system("/usr/ucb/logger -p daemon.err ". "Process: '$process' NOT running!\n"); ## send an email too: system "echo '$tmp_var' | $mail -s '$subject' $user"; } } elsif ($debug) { print "Process '$process' occurred $event_count{$process} times\n"; } } } else { # syslog is dead! if (! $debug) { system "echo '$tmp_var' | $mail -s $subject $user"; } } exit 0; #EOF