Tag Archives: script

Bash script to alert when memory gets low

We have a web server that’s running out of memory about once every couple of weeks. The problem is that when it happens the swap file is totally full, the system is unresponsive and it usually needs a hard reboot. So it’s a bit difficult to debug. To avoid digging through log files I don’t understand I elected to put a script in /etc/cron.hourly which checks the total amount of free memory (including swap and physical). If there is less than 256mb free (this server has 512mb of ram and a 1gb swap so at this point the situation is serious), it dumps the process list to /tmp/processes.txt and sends me an email with it attached.

Note that mutt must be installed (‘apt-get install mutt’ on Debian/Ubuntu, or ‘yum install mutt’ on RedHat/CentOS).

#!/bin/bash

free=`free -mt | grep Total | awk '{print $4}'`

if [ $free -lt 256 ]; then
        ps -eo %mem,pid,user,args >/tmp/processes.txt
        echo 'Warning, free memory is '$free'mb' | mutt -a /tmp/processes.txt -s "Server alert" email@me.com
fi

Then of course make it executable and symlink to cron.hourly:

chmod +x /etc/scripts/memalert.sh
ln -s -t /etc/cron.hourly/memalert.sh /etc/scripts/memalert.sh

Automatically update DansGuardian Filter Groups List from LDAP

Update 20th March 2011: Heath has made some modifications to the original script and made it more efficient, see the comments below.

Here’s a script I wrote today, which updates the filtergroupslist file of Dansguardian. If you’re using LDAP authentication and want to give different levels of protection to certain groups of users, you need to update the list somehow, as Dansguardian doesn’t support LDAP groups. See this page for more info on filter groups.

The school I wrote this for is a Novell eDirectory site, and it will require a bit of modification to work on other sites. In particular you will need to alter the parameters of the ldapsearch command (filter string, server name, user credentials). Other LDAP servers may not support the ufn attribute, which this is based on. If your directory is well maintained and up to date you would probably be better of using the uid attribute, but this particular school hasn’t populated it for all users yet (only users created with ConsoleOne and iManager populate the uid attribute by default). If you do use uid, be sure to remove the cut command.

ldapsearch outputs data in ldif format, which is difficult to use in scripts. The tool to use to convert this is awk, which unfortunately is a language I haven’t learnt yet. So I found a premade awk script which converts ldif2csv (from here), removed out all the attributes and replaced them with just ufn (you may want to use uid instead).

If you use this script and modify or improve it, I’d appreciate you contributing the modifications back, as they may be useful to others (myself included)!

updateFilter.sh

#!/bin/bash
#
# Dansguardian filter group update script
# Alex Forbes, Edtech Ltd
# Updated 9th September 2009
#

## Variables
# Dansguardian filtergroupslist file
DESTFILE=/root/filtergroupslist-test
LOGFILE=/var/log/dansfgupdate.log

# LDAP settings
LDAPFILTER="(&(objectClass=Person)(|(groupMembership=cn=ALL-TEACHERS,ou=TCHR,o=HWK)(groupMembership=cn=ALL-ADMIN,ou=ADM,o=HWK)(groupMembership=cn=OESAdmins,o=HWK)))"

# Which filtergroup do you want the users to be a member of
FILTERGROUP=filter2

# Path to the awk script (converts the ldif file to parseable text). I modified one from
# http://www.yolinux.com/TUTORIALS/LinuxTutorialLDAP-ScriptsAndTools.html
AWKSCRIPT=/opt/ldif2csv.awk
TMP=/tmp

# Dansguardian filter group list file
# Temp path, creates folder for the temp files. There are probably better ways of doing it.

# Make temp directories
WIP=$TMP/dgFilterUpdate
mkdir -p $WIP

# Header message
echo "## This file is automatically updated, any changes will be overwritten" > $WIP/4final
echo "## See /opt/edir2dansg.sh" >> $WIP/4final
echo "" >>$WIP/4final

# Perform LDAP search. Outputs ldif file.
ldapsearch -uxvA -H ldaps://fs2.howick.school.nz -b "o=HWK" -S '' -s "sub" -D cn=ldapauth,o=hwk -w password "$LDAPFILTER" ufn > $WIP/1ldif

# Picks out the ufn attribute using a modified awk script I found:
awk -F ': ' -f $AWKSCRIPT  $WIP/2txt

# Picks the first field of the ufn attribute to generate a clean list of users
cut -d, -f1 $WIP/2txt > $WIP/3userlist

# Add the values required to meet the dansguardian filter format
for u in `cat $WIP/3userlist`; do
	echo "$u=$FILTERGROUP" >> $WIP/4final
done

# Finally, copy the file to overwrite the dansguardian list.
# I've done a simple check to make sure the file isn't too small in case of error, but it could be handled better.
SIZE=`stat -c %s $WIP/4final`
if [ $SIZE -gt 2500 ]; then
	cp $WIP/4final $DESTFILE
	echo $(date +"%Y/%m/%d %H:%M"): Updated filter groups list "("size $SIZE bytes")" >> $LOGFILE
else echo $(date +"%Y/%m/%d %H:%M"): Output file is too small, list not updated >> $LOGFILE
fi

# Gentle reload of dansguardian
dansguardian -g

And the modified awk script, ldif2csv.awk:

BEGIN {
        ufn = ""
      }
/^ufn: /              {ufn=$2}
/^dn/ {
        if(ufn != "") printf("%sn",ufn)
        ufn     = ""
      }
# Capture last dn
END {
        if(ufn != "") printf("%sn",ufn)
}

Update 9-9-09: Fixed a few dumb mistakes.

Simple File Backup to Email Script

Here’s a file backup script I installed for a client. The original outline came from a post on the ubuntu forums (I forget where exactly), but it’s simple enough. It creates an archive in /tmp, zips it up, emails it then deletes the archive. If your target is a linux computer then it makes more sense to gzip it by adding a “z” to the tar options (i.e. tar -czf) and removing the zip line.

#!/bin/bash
#
# Simple file backup script, creates archive in /tmp and emails it.
#
# Software required:
#  zip
#  tar
#  mutt

# Variables
MAILADDR=email@example.com
SOURCE="/home/user1 /home/user2"
SERVERNAME=server.example.com
MAIL=`which mutt`
ZIP=`which zip`
DATE=`date +%Y_%m_%d`
FILE=myfiles-$DATE.tar
DESTINATION=/tmp/$FILE
ZIPFILE=$DESTINATION.zip

# Actions
tar -cf $DESTINATION $SOURCE 2> /dev/null
$ZIP $ZIPFILE $DESTINATION
$MAIL -a $ZIPFILE -s "Backup for $DATE" -s "$SERVERNAME backup $DATE" $MAILADDR < /dev/null
rm $ZIPFILE $DESTINATION

For mutt to work you need an MTA (mail transport agent) such as postfix. If it’s not installed and you don’t need it for anything else, configure it as a satellite system (the Ubuntu/Debian packages prompt you on install and satellite system is an option). This prevents spammers from using it as a relay, and ensures the mail goes to your real mail server.