/Main_Page

::You must have ninja focus to complete your mission::NinjaFocus::

SpamAssassin Updater

Views:


This script will check for new spamassassin rule sets, download them, test them, compile them and reload spamd plus keep backups of the previous verious. It make me feel a little bit better about spamassassin pulling in new rule sets automatically. Doing that is a good thing but sometimes bad rules are pushed out.

#!/bin/bash

# This script will automatically update spamassassin rules and compile them
# Backups are kept for at least 28 days

###########
# Settings

SA=/usr/bin/spamassassin
SA_UPDATE=/usr/bin/sa-update
SA_COMPILE=/usr/bin/sa-compile
SA_VAR=/var/lib/spamassassin
SPAMD_PID=/var/run/spamd.pid
BACKUP_OWNER="sa-update"


COMPILED_DIR="${SA_VAR}/compiled"
BACKUP_DIR="${SA_VAR}/backups"

############
# Functions

# date adjusts to the given number of days in the past and 
# formatted using the provided formatting string
# usage: pastDate <minus no. days> <format>
pastDate()
{
    if [ ! $1 ]
    then
        exit 1
    fi
    if [ ! $2 ]
    then 
        exit 1
    fi
    if [ `uname` = "Darwin" ]
    then
        echo $(date -v -"$1"d +"$2")
    fi
    if [ `uname` = "Linux" ]
    then
        echo $(date --date="$1 day ago" +"$2")
    fi
}

##############
# For logging

echo "$(date +"%F %X") spamassassin updater"

#########################################################
# SpamAssassin Version and corresponding rules directory

# spamassassin uses a different directory name to store rules, based on
# it's version number. The version number is converted to a "filesytem 
# friendly" name like 3.002005 or 3.003000 for 3.2.5 and 3.3.0.
SA_VERSION=$("${SA}" -V | grep SpamAssassin | sed -e 's/SpamAssassin version //')
SA_MAJOR=$(echo "${SA_VERSION}" | cut -d. -f 1)
SA_MINOR=$(echo "${SA_VERSION}" | cut -d. -f 2)
SA_PATCH=$(echo "${SA_VERSION}" | cut -d. -f 3)
RULE_DIR="${SA_VAR}/$(printf "%d.%0#3d%0#3d" "${SA_MAJOR}" "${SA_MINOR}" "${SA_PATCH}")"

###############
# Basic checks 

if [ ! -f "$SPAMD_PID" ]
then
    echo "spamd pid file $SPAMD_PID does not exist"
    exit 1
fi

if [ ! "$RULE_DIR" ]
then
    echo "could not determine directory for spamassassin rules" 
    exit 1
fi
if [ ! -d "$RULE_DIR" ]
then
    mkdir "$RULE_DIR"
fi
if [ ! -d "$RULE_DIR" ]
then
    echo "cannot create rule directory $RULE_DIR"
    exit 1
fi

if [ "$(egrep "^${BACKUP_OWNER}:" /etc/passwd | wc -l)" -ne 1 ]
then
    echo "backup owner \"${BACKUP_OWNER}\" does not exist"
    exit 1
fi

if [ ! -d "$BACKUP_DIR" ]
then
    mkdir "$BACKUP_DIR"
fi
if [ ! -d "$BACKUP_DIR" ]
then
    echo "cannot create backup rules directory $BACKUP_DIR"
    exit 1
fi
if [ ! -w "$BACKUP_DIR" ]
then
    echo "backup rules directory $BACKUP_DIR is not writable"
    exit 1
fi

############
# Spamd pid 

SPAMD_PID=$(cat "$SPAMD_PID")
if [ ! "$(ps -p "$SPAMD_PID" --no-headers)" ]
then
    echo "spamd is not running"
    exit 1
fi

###############
# Backup dates

TODAY=$(date +%F)
FOUR_WEEKS_AGO=$(pastDate 28 %F)

###################################
# Check for availabilty of updates

"$SA_UPDATE" --gpg --checkonly
SA_UPDATE_EXIT_CODE=$?
if [ $SA_UPDATE_EXIT_CODE -eq 1 ]
then 
    echo "No updates available"
    exit 0
elif [ $SA_UPDATE_EXIT_CODE -gt 1 ]
then
    echo "sa-update returned error $SA_UPDATE_EXIT_CODE"
    exit $SA_UPDATE_EXIT_CODE
fi

########################
# Backup existing rules 

mkdir "$BACKUP_DIR/$TODAY"
cp -rp "$RULE_DIR" "$BACKUP_DIR/$TODAY/" 
cp -rp "$COMPILED_DIR" "$BACKUP_DIR/$TODAY/" 
chown -R $BACKUP_OWNER "$BACKUP_DIR/$TODAY"

###############
# Update rules

"$SA_UPDATE" $GPGKEYS
SA_UPDATE_EXIT_CODE=$?
if [ $SA_UPDATE_EXIT_CODE -eq 1 ]
then
    echo "No updates available"
    exit 0
elif [ $SA_UPDATE_EXIT_CODE -gt 1 ]
then
    echo "sa-update returned error $SA_UPDATE_EXIT_CODE"
    exit $SA_UPDATE_EXIT_CODE
fi

################
# Compile rules

"$SA_COMPILE"
SA_COMPILE_EXIT_CODE=$?
if [ $SA_COMPILE_EXIT_CODE -ne 0 ]
then
    echo "sa-compile failed with error $SA_COMPILE_EXIT_CODE"
    exit $SA_COMPILE_EXIT_CODE
fi

##########################################
# Reload spamassassin spamd configuration

kill -s SIGHUP "$SPAMD_PID"

##########################
# Remove old rule backups

cd "$BACKUP_DIR"
for DIR in *
do
    # be paranoid and check that the directory name looks plausible
    if [ $(echo "$DIR" | egrep "^[[:digit:]]{4}-[[:digit:]]{2}-[[:digit:]]{2}$") ]
    then
	# strip the hyphens from the date: YYYY-MM-DD becomes YYYYMMDD, now we can do numerical comparisons
        if [ "${DIR//-/}" -lt "${FOUR_WEEKS_AGO//-/}" ]
        then
            sudo -u $BACKUP_OWNER rm -rf "${BACKUP_DIR}/${DIR}"
        fi
    fi
done


Main Menu

Personal tools

Toolbox