bley – gewichtetes Greylisting + Cache

This blog post has been published on 2010-11-14 and may be out of date.

Auf der openrheinruhr.de habe ich gestern einen sehr interessanten Vortrag über Greylisting von Evgeni Golov gehört.


Ich selber hatte bis vor einigen Stunden noch eine Kombination aus Black- & Greylisting + SpamAssassin + ClamAV. Das Problem welches einige kennen ist, dass E-Mails dadurch ggf. verloren gehen oder zumindest verzögert werden, wenn ein “guter” Absender auf einer Blacklist kommt.

Das gewichtetet Greylisting erweitert das normale Greylisting um eine selektive Komponente, somit wenden nur auffällige Sender (welche in einer DNSBL (Blackliste) ist, nicht RFC-konformes EHLO übergibt etc…) werden gegreylisted. Das heißt, dass dem Absender mitgeteilt wird, dass momentan die E-Mail nicht zugestellt werden kann und er es gleich noch einmal versuchen soll, alle anderen werden durchgelassen. Spamer kommen jedoch (noch) nicht noch-einmal, um die selbe E-Mail ein zweites Mal zuzustellen.

Normalerweise werden bei “normalem” Greylisting unbekannten Absender direkt temporär abgewiesen und dessen Reaktion abgewartet. Bei dem “gewichtetem” (intelligentem) Greylisting wird der erste Zustellversuch zunächst analysiert. Anhand dieser Analyse wird entschieden, ob die E-Mail sofort angenommen werden soll oder ob Greylisting zum Einsatz kommt und die E-Mail somit mit einem temporären Fehler abgelehnt wird.


die Analyse:
  1. Absender hat bereits eine E-Mail erfolgreich zugestellt -> E-Mail sofort annehmen
  2. Absender in einer bekannten Whitelist -> E-Mail sofort annehmen
  3. Absender in einer bekannten Blacklist -> Greylisting
  4. Absender verwendet einen nicht standardkonformen Namen im SMTP-HELO, Absender kommt aus einem DialUp-Netzwerk etc… -> Greylisting
  5. SPF-Check (Sender Policy Framework) schlägt fehl -> Greylisting
  6. ansonsten -> E-Mail annehmen
Golov2009a.pdf (docs.google.com) -> S.42


Bley verwendet die Policy-Daemon-Schnittstelle des SMTP-Servers Postfix und ist somit leicht in existierende Umgebungen integrierbar bzw. “policyd-weight” zu ersetzen.
Als Vergleich wurde “bley” & “policyd-weight” auf einem Server mit ca 20.000 E-Mails/Tag getestet, dabei filterte policyd-weight 97,5% der E-Mails als Spam, bley 97%, der Vorteil von bley ist jedoch, dass E-Mails ggf. nicht Verzögert und nicht verloren gehen.
Für den praktischen Einsatz wird die Kombination von bley mit einer inhaltsbasierten Spam-Erkennung (z.B. SpamAssassin) vorgeschlagen. Dadurch, dass bley bereits die meisten Spam-Mails mit minimalem Rechenaufwand auf Protokollebene abweisen kann, müssen rechenaufwändige inhaltsbasierte Verfahren (z.B. SpamAssassin) nur noch auf eine sehr viel geringere Zahl von E-Mails angewendet werden.


Es folgt noch ein kurzes How-To: ;-)


Software nachinstallieren:

aptitude install python-setuptools python-twisted-core python-twisted-names python-spf python-psycopg2 postgresql python-pgsql

bley herunterladen und entpacken:

cd /usr/src
mkdir bley && cd bley
wget http://bley.mx/download/bley-0.1.4.tar.gz
tar xzvf bley-0.1.4.tar.gz
cd bley-0.1.4/

Datenbank anlegen:

su postgres
createuser bley
Enter password for new role: ********
Enter it again: ********
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n

createdb --owner=bley bley

exit

bley installieren:

python setup.py build
python setup.py install

cp -vp build/scripts-2.6/bley /usr/bin/

Konfiguration anpassen (Datenbank -> Passwort):

vim /etc/bley/bley.conf

Autostart für bley anlegen:

vim /etc/init.d/bley
#! /bin/sh
### BEGIN INIT INFO
# Provides:          bley
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: bley initscript
# Description:       intelligent greylisting daemon for Postfix.
### END INIT INFO

# Author: Evgeni Golov <evgeni@debian.org>

# Do NOT "set -e"

# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="intelligent greylisting daemon for Postfix"
NAME=bley
DAEMON=/usr/bin/$NAME
DAEMON_ARGS=""
DAEMON_USER=$NAME
PIDFILE=/var/run/$NAME/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

# Add pidfile to DAEMON_ARGS
DAEMON_ARGS="-p $PIDFILE $DAEMON_ARGS"

#
# Function that starts the daemon/service
#
do_start()
{
	# Return
	#   0 if daemon has been started
	#   1 if daemon was already running
	#   2 if daemon could not be started

	# prepare /var/run/bley which can be gone if /var/run is cleaned on reboot
	if [ ! -d /var/run/bley ]; then
		mkdir /var/run/bley
		chown bley:bley /var/run/bley
	fi

	# start bley
	start-stop-daemon --start --quiet --pidfile $PIDFILE --startas $DAEMON --test > /dev/null \
		|| return 1
	start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $DAEMON_USER --startas $DAEMON -- \
		$DAEMON_ARGS \
		|| return 2
	# Add code here, if necessary, that waits for the process to be ready
	# to handle requests from services started subsequently which depend
	# on this one.  As a last resort, sleep for some time.
}

#
# Function that stops the daemon/service
#
do_stop()
{
	# Return
	#   0 if daemon has been stopped
	#   1 if daemon was already stopped
	#   2 if daemon could not be stopped
	#   other if a failure occurred
	start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
	RETVAL="$?"
	[ "$RETVAL" = 2 ] && return 2
	# Wait for children to finish too if this is a daemon that forks
	# and if the daemon is only ever run from this initscript.
	# If the above conditions are not satisfied then add some other code
	# that waits for the process to drop all resources that could be
	# needed by services started subsequently.  A last resort is to
	# sleep for some time.
	start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
	[ "$?" = 2 ] && return 2
	# Many daemons don't delete their pidfiles when they exit.
	rm -f $PIDFILE
	return "$RETVAL"
}

case "$1" in
  start)
	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
	do_start
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  stop)
	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
	do_stop
	case "$?" in
		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
	esac
	;;
  status)
       status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
       ;;
  restart|force-reload)
	log_daemon_msg "Restarting $DESC" "$NAME"
	do_stop
	case "$?" in
	  0|1)
		do_start
		case "$?" in
			0) log_end_msg 0 ;;
			1) log_end_msg 1 ;; # Old process is still running
			*) log_end_msg 1 ;; # Failed to start
		esac
		;;
	  *)
	  	# Failed to stop
		log_end_msg 1
		;;
	esac
	;;
  *)
	echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
	exit 3
	;;
esac

:
chmod +x bley

update-rc.d bley defaults

User anlegen & Rechte setzen:

adduser --system --quiet --disabled-password --no-create-home --home "/var/run/bley" --gecos "intelligent greylisting daemon for Postfix" --group bley
chown root:bley /etc/bley
chmod 750 /etc/bley
chown bley:bley /etc/bley/bley.conf
chmod 600 /etc/bley/bley.conf
vim /etc/bley/bley.conf

log_file = /var/log/bley/bley.log

cd /var/log
mkdir bley
chown bley:bley bley/
mkdir /var/run/bley
chown bley:bley /var/run/bley
/etc/init.d/bley start

Postfix anpassen:

vim /etc/postfix/main.cf
smtpd_recipient_restrictions =
        permit_mynetworks,
        permit_sasl_authenticated,
        #reject_invalid_hostname,
        #reject_unknown_recipient_domain,
        #reject_unauth_pipelining,
        reject_unauth_destination,
        #reject_non_fqdn_hostname,
        #reject_non_fqdn_sender,
        #reject_non_fqdn_recipient,
        #reject_unknown_sender_domain,
        #reject_unknown_recipient_domain,
        #reject_unauth_pipelining,
        #reject_unauth_destination,
        #check_client_access hash:/etc/postfix/rbl_override,
        check_policy_service inet:127.0.0.1:1337,
        ##check_policy_service inet:127.0.0.1:12525,
        #reject_rbl_client multi.uribl.com,
        #reject_rbl_client dsn.rfc-ignorant.org,
        ##reject_rbl_client dul.dnsbl.sorbs.net,
        #reject_rbl_client list.dsbl.org,
        #reject_rbl_client sbl-xbl.spamhaus.org,
        #reject_rbl_client bl.spamcop.net,
        ##reject_rbl_client dnsbl.sorbs.net,
        #reject_rbl_client cbl.abuseat.org,
        ##reject_rbl_client ix.dnsbl.manitu.net,
        #reject_rbl_client combined.rbl.msrbl.net,
        #reject_rbl_client rabl.nuclearelephant.com,
        permit

Published by

voku

Lars Moelleken | Ich bin root, ich darf das!

%d bloggers like this: