Reduce wiki spam

From Wiki

Jump to: navigation, search

I've chosen to do this at the Apache level. While this isn't the most efficient way it has advantages in a name-based virtual hosting environment. I have other web sites hosted on this server and I do not want to risk those becoming unavailable due to someone's accidental inclusion in a blacklist.

I've created a quick script which fetches a list of known forum spammers and converts it into an Apache ACL. It could easily be adapted to create a pf, iptables or almost any other ruleset:

#!/bin/sh

# List of twats you wish to block.  This one allows only ONE 
# download per day, so test with a self-hosted copy.
LIST="http://www.stopforumspam.com/downloads/listed_ip_90.zip"
# List of addresses to exclude from the deny list (not implemented)
EXCEPTIONS="http://example.com/exceptions.txt"
# Temporary files
OLDACL="/tmp/old-wikispamfister"
NEWACL="/tmp/new-wikispamfister"
# Where to put the final ACL for Apache to use:
ACL="/etc/apache2/wikispamfister"

# This script must run as root to do anything useful
if [ "$(id -u)" != '0' ]
then
 echo "This script has to be run as root."
 exit 1
fi

# Delete any old copies of the ACL
if [ -f ${OLDACL} ]
then
 rm ${OLDACL}
fi

if [ -f ${NEWACL} ]
then
 rm ${NEWACL}
fi

# Fetch the twatlist
if ! wget -qO /tmp/twatlist.zip $LIST
then
 echo "wget was unable to fetch the twatlist."
 echo "This script will now die horribly without tidying up after itself."
 exit 1
fi

# ...and unzip it
if ! unzip -p /tmp/twatlist.zip > /tmp/twatlist.txt 
then
 echo "unzip didn't like the twatlist."
 echo "This script will now die horribly without tidying up after itself."
 exit 1
fi

# Munge the file into something Apache will recognise
# SURELY grep and sed can't go wrong?  Please?
grep -v '0\.0\.0\.0' /tmp/twatlist.txt | sed 's/^/Deny from /' > $NEWACL

# Move the current ACL out of the way and slide in the new one
mv ${ACL} ${OLDACL}
cp ${NEWACL} ${ACL}

# Does Apache like it?
if ! /usr/sbin/apache2ctl configtest
 then
  echo "That ACL smells of POOP!!!!"
  echo "reverting..."
  cp ${OLDACL} ${ACL}
  echo "I've put the old ACL back.  You should check what went wrong."
 echo "This script will now die horribly without tidying up after itself."
  exit 1
 else
  echo "Reloading Apache..."
  service apache2 reload
fi

exit 0

Place that script somewhere convenient and chmod +x it. Then call it once per day from your crontab.

Here's an example httpd.conf snippet for Apache:

<Location />
	Order Deny,Allow
	# This must point to the deny list produced by the script, not the script itself:
 	Include /etc/apache2/wikispamfister
</Location>
Personal tools