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:
- Absender hat bereits eine E-Mail erfolgreich zugestellt -> E-Mail sofort annehmen
- Absender in einer bekannten Whitelist -> E-Mail sofort annehmen
- Absender in einer bekannten Blacklist -> Greylisting
- Absender verwendet einen nicht standardkonformen Namen im SMTP-HELO, Absender kommt aus einem DialUp-Netzwerk etc… -> Greylisting
- SPF-Check (Sender Policy Framework) schlägt fehl -> Greylisting
- ansonsten -> E-Mail annehmen
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