RelayDelay (Greylisting)

Sendmail Zusatzmodule Installieren

Perl

Vor dem Install schauen, dass dies alles installiert ist.  Sonst einfach über Port instalieren:

WICHTIG!

Damit das alles läuft, muss perl threaded installiert sein. (damit p5-Sendmail-Milter installiert werden kann) In der Grundinstallation von FreeBSD wird perl nicht mit thread Support installiert. Schauen, wie Perl installiert wurde:

cd /usr/ports/mail/p5-Sendmail-Milter
make

kommt jetzt ein error, dass Perl den threaded support benötigt, muss Perl neu kompiliert & installiert werden.

Note: nach Upgrade zu perl 5.16 kam dieser Fehler ebenfalls, obwohl Perl threaded instaliert war:

# perl -V:usethreads
usethreads='define';

Das Problem liegt irgendwo im Makefile. ${PERLTHREADS} war gleich „define “ (mit Space am Ende) statt „define“. Somit hab ich einfach folgendes geändert, danach lief die Installation durch:

.if ${PERLTHREADS} != "define"
.if ${PERLTHREADS} != "define "

Ist perl nicht mit Threads installiert, wie folgt weitermachen:

cd /usr/ports/lang/perl5.8/
make deinstall
make WITH_THREADS=yes install clean

In dem Fall müssten dach dem Perl Install auch alle von Perl abhängigen Pakete aktualisiert werden:

portupgrade -fr lang/perl5.8

 

MySQL

Das ist nur formhalber, weil wir das eh installiert haben. Einfach prüfen, ob alle Module vorhanden sind: Now for the database server; MySQL is perfect for this sort of work. Install the databases/mysql40-server along with databases/p5-DBD-mysql40. The previous port should imply the installation of databases/p5-DBI-137 so that knocks off another step.

mach

pkg_version -v

und schau, dass folgendes installiert ist:

mysql40-server (bzw. current)
p5-DBD-mysql40
p5-DBI-137

Sollte etwas fehlen, installieren…

/usr/ports/databases/p5-DBD-mysql55
make install clean

DBD und DBI wird so gleich beides gleichzeitig installiert…

===>   Compressing manual pages for p5-DBD-mysql55-4.020
===>   Registering installation for p5-DBD-mysql55-4.020
===>  Cleaning for p5-DBI-1.618
===>  Cleaning for p5-DBD-mysql55-4.020

p5 Plugins

Install the perl based portable server plugin, net/p5-Net-Daemon port. Most of these port installations should have been straight forward. The next step will be more involved.

Now install the mail/p5-Sendmail-Milter port. As of this writing the Makefile contains a line beginning with BROKEN, just remove it or comment it out. It is only marked this way because FreeBSD neither has nor installs a threaded perl package by default. Once that line is removed it should build and install perfectly fine.

cd /usr/ports/net/p5-Net-Daemon
make install clean
cd /usr/ports/mail/p5-Sendmail-Milter
make install clean

RelayDelay

mkdir /usr/local/software/relaydelay
cd /usr/local/software/relaydelay

aktuellste version Downloaden sowie Patch runterladen.

fetch http://projects.puremagic.com/greylisting/releases/relaydelay-0.04.tgz
fetch http://lists.puremagic.com/pipermail/greylist-users/attachments/20030904/b8dafed9/relaydelay-0.04.bin

Hier gibt es sonst noch einen neueren Patch (0.05) den hab ich aber bisher noch nicht ausprobiert…

http://www.maynidea.com/sendmail/relaydelaypl.html

Upack

gunzip -c relaydelay-0.04.tgz | tar xvf -

Rechte richtig setzen

chown -R root:wheel relaydelay-0.04

Mysql Daten erstellen

mysql -uroot -p < relaydelay-0.04/mysql.sql

File Patchen

 patch -d /usr/local/software/relaydelay/relaydelay-0.04 < relaydelay-0.04.bin 

Nun noch folgende Korrektur machen, damit diese Fehlermeldung nicht mehr erscheint Use of uninitialized value $ifaddr in concatenation (.) or string at /usr/local/sbin/relaydelay.pl line 611.

vi /usr/local/software/relaydelay/db_maintenance.pl
 my $ifaddr      = $ctx->getsymval("{if_addr}");

# added by teslina
# Sendmail seems to sometimes not pass the {if_addr} if the relay_ip is localhost, so fix that
$ifaddr = $relay_ip if (!defined $ifaddr and $relay_ip eq "127.0.0.1");
# eof teslina

print "  Relay: $tmp - If_Addr: $ifaddr\n" if ($verbose);


Edit the relaydelay.conf and the db_maintenance.pl file to append the correct username and password for the MySQL database. If the database was built and installed like the above then no users or passwords exist. This should be altered before putting this into production, that is covered in the database documentation and is beyond the scope of this document.

vi relaydelay-0.04/relaydelay.conf
$database_user = 'relaydelay';
$database_pass = '';
vi relaydelay-0.04/db_maintenance.pl 

Jetzt erstelle user relaydelay in der MySQL user table:

INSERT INTO `mysql`.`user` (
`Host` ,
`User` ,
`Password` ,
`Select_priv` ,
`Insert_priv` ,
`Update_priv` ,
`Delete_priv` ,
`Create_priv` ,
`Drop_priv` ,
`Reload_priv` ,
`Shutdown_priv` ,
`Process_priv` ,
`File_priv` ,
`Grant_priv` ,
`References_priv` ,
`Index_priv` ,
`Alter_priv` ,
`Show_db_priv` ,
`Super_priv` ,
`Create_tmp_table_priv` ,
`Lock_tables_priv` ,
`Execute_priv` ,
`Repl_slave_priv` ,
`Repl_client_priv` ,
`Create_view_priv` ,
`Show_view_priv` ,
`Create_routine_priv` ,
`Alter_routine_priv` ,
`Create_user_priv` ,
`ssl_type` ,
`max_questions` ,
`max_updates` ,
`max_connections` ,
`max_user_connections`
)
VALUES (
'localhost', 'relaydelay', PASSWORD( '' ) , 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '0', '0', '0', '0'
);

INSERT INTO `mysql`.`db` (
`Host` ,
`Db` ,
`User` ,
`Select_priv` ,
`Insert_priv` ,
`Update_priv` ,
`Delete_priv` ,
`Create_priv` ,
`Drop_priv` ,
`Grant_priv` ,
`References_priv` ,
`Index_priv` ,
`Alter_priv` ,
`Create_tmp_table_priv` ,
`Lock_tables_priv` ,
`Create_view_priv` ,
`Show_view_priv` ,
`Create_routine_priv` ,
`Alter_routine_priv` ,
`Execute_priv`
)
VALUES (
'localhost', 'relaydelay', 'relaydelay', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y', 'Y'
);

FLUSH PRIVILEGES ;

Jetzt ins directory wechseln:

cd relaydelay-0.04

Copy or move the configuration files to their respective directories

cp db_maintenance.pl /usr/local/sbin
cp relaydelay.pl /usr/local/sbin
cp relaydelay.conf /etc/mail/
cp relaydelay.sh /usr/local/etc/rc.d/

Testen

/usr/local/etc/rc.d/relaydelay.sh start

Wenn alles gut ging, sieht das logfile jetzt so aus:

tail -f /var/log/relaydelay.log 
DBI Connecting to DBI:mysql:database=relaydelay:host=localhost:port=3306
Spawned relaydelay daemon process 81592.
Starting Sendmail::Milter 0.18 engine.
Successful exit from the Sendmail::Milter engine.
Loaded Config File: /etc/mail/relaydelay.conf
Using connection 'local:/var/run/relaydelay.sock' for filter relaydelay
Attempting to unlink local UNIX socket '/var/run/relaydelay.sock' ... successful.
DBI Connecting to DBI:mysql:database=relaydelay:host=localhost:port=3306
Spawned relaydelay daemon process 82301.
Starting Sendmail::Milter 0.18 engine.

Wenn dieser Output nicht kommt, stimmt was nicht. Dann am besten das /var/log/messages logfile checken.

Konfigurieren

Sendmail

Jetzt den Filter in Sendmail includen

cd /etc/mail/my_prefs/
vi corky.mc 

Diese Zeile einfügen:

dnl ### mimedefang vorübergehend deaktivieren! hoher load!!
dnl ### wenn ich es über MAIL_FILTER statt über INPUT_MAIL_FILTER mache, geht zwar relaydely,
dnl ### aber danach werden die mails beim second attempt nicht an mimedefang weitergegeben.
dnl ### define(`MILTER',1)
dnl ### MAIL_FILTER(`relaydelay', `S=local:/var/run/relaydelay.sock, F=T, T=S:1m;R:2m;E:3m')dnl
dnl ### MAIL_FILTER(`mimedefang', `S=local:/var/spool/MIMEDefang/mimedefang.sock, F=T, T=C:15m;S:4m;R:4m;E:10m')dnl
dnl ### define(`confINPUT_MAIL_FILTERS', `relaydelay',`mimedefang')dnl

define(`MILTER',1)
INPUT_MAIL_FILTER(`relaydelay', `S=local:/var/run/relaydelay.sock, F=T, T=S:1m;R:2m;E:3m')dnl
INPUT_MAIL_FILTER(`mimedefang', `S=local:/var/spool/MIMEDefang/mimedefang.sock, F=T, T=C:15m;S:4m;R:4m;E:10m')dnl
  • define(`MILTER‘,1) Muss nur eingefügt werden, wenn die Zeile nicht schon vorhanden ist.
  • bei confINPUT_MAIL_FILTERS ist die Reihenfolge sehr wichtig. relaydelay muss vor mimedefang aufgerufen werden.
  • sollte relaydelay aus irgendeinem grund nicht available sein, bedeutet die F=T teile, dass sendmail jede connection „tempfailen“ soll, wenn sendmail nicht mit dem filter kommunizieren kann. Wenn Sendmail einfach ignorieren soll, ob der milter erreichbar ist oder nicht, kann man die Zeile „F=T, “ einfach vom MAIL_FILTER entfernen. Dann wird Sendmail die Mails so verarbeiten, als wäre einfach kein Milter installiert während er nicht erreichbar ist.
The current flags (F=) are:
R Reject connection if filter unavailable
T Temporary fail connection if filter unavailable
If a filter is unavailable or unresponsive and no flags have been
specified, the MTA will continue normal handling of the current
connection. The MTA will try to contact the filter again on each new
connection.

Die Line kann also so:

 INPUT_MAIL_FILTER(`relaydelay', `S=local:/var/run/relaydelay.sock, F=T, T=S:1m;R:2m;E:3m')dnl

oder so:

INPUT_MAIL_FILTER(`relaydelay', `S=local:/var/run/relaydelay.sock, T=S:1m;R:2m;E:3m')dnl

aussehen

 

Danach sendmail neu builden

cd /etc/mail/
make
rcsendmail stop
rcsendmail start

Nun sollten auch schon bald die ersten Log Einträge erscheinen:

tail -f /var/log/relaydelay.log 
=== 2007-11-21 16:31:19 ===
Stored Sender: <xxx@xxx.com>
Passed Recipient: <info@testserver.ch>
  Relay: ppp91-122-149-183.pppoe.avangard-dsl.ru [91.122.149.183] - If_Addr: 81.94.97.82
  RelayIP: 91.122.149.183 - RelayName: ppp91-122-149-183.pppoe.avangard-dsl.ru - RelayIdent:  - PossiblyForged: 0
  From: xxx@xxx.com - To: testuser
  InMailer: esmtp - OutMailer: cyrusv2 - QueueID: lALFVAAv091928
  New mail row successfully inserted.  Issuing a tempfail.  rowid: 412
  IN ABORT CALLBACK - PrivData: 0<xxx@xxx.com>

White / Blacklists

Jetzt wieder ins install verzeichnis:

cd /usr/local/software/relaydelay/relaydelay-0.04

und folgendes perl-file erstellen:

vi add-list.pl

Inhalt pasten (Quelle: http://lists.puremagic.com/pipermail/greylist-users/2003-November/000327.html):

#!/usr/bin/perl -w
use DBI;
#user strict verwenden wir nicht, da sonst fehler auftauchen (im config sind die
# variablen eben nicht mit "my $log_file = " etc. deklariert, sondern ohne my.
# somit gibts fehler:
# Error evaluating this line from /etc/mail/relaydelay.conf:
# $run_as_daemon = 1;
#
# Global symbol "$run_as_daemon" requires explicit package name at (eval 30) line 1,  line 26.
#
#use strict;

# Version: 0.01
# 
# Programmer: Tim Freeman 

my $conffile = "/etc/mail/relaydelay.conf";
my $verbose;
my $milter_filter_name;
my $milter_socket_connection;
my $maximum_milter_threads;
my $relaydelay_pid_file;
my $delay_mail_secs;
my $auto_record_life_secs;
my $update_record_life;
my $update_record_life_secs;
my $check_wildcard_relay_ip;
my $check_wildcard_rcpt_to;
my $tempfail_messages_after_data_phase;
my $do_relay_lookup_by_subnet;
my $enable_relay_name_updates;
my $check_envelope_address_format;
my $pass_mail_when_db_unavail;
my $reverse_mail_tracking;
my $reverse_mail_life_secs;
my $database_type;
my $database_name;
my $database_host;
my $database_port;
my $database_user;
my $database_pass;

sub usage () {
    die << "EOM";
Usage: $0 [[-whitelist|-blacklist] yyyy-mm-dd hh:mm:ss|-delete] < list

Add the IP addresses listed in one of the .txt files that comes with
relaydelay to the database.

Reads $conffile for database passwords.

With -whitelist, the given IP\'s are whitelisted until the given date.
With -blacklist, the given IP\'s are blacklisted until the given date.

With -delete, the given IP\'s are deleted from the database.  Do this
first if you want to change the dates on the whitelists or the
blacklists, or you accidentally blacklisted your whitelist.

For example:

   $0 -whitelist 9999-12-31 23:59:59 < whitelist_ip.txt

EOM
}

# Unfortunately, this strategy for reading the configuration file
# requires that each perl statement in the config file is on one line.
sub readconf () {
    open (INFILE, "<$conffile") || die "Can't read $conffile: $!";
    for (;;) {
	my $line = ;
	last unless defined $line;
	eval $line;
	if ($@ ne '') {
	    die "Error evaluating this line from $conffile:\n$line\n$@" ;
	}
    }
    close (INFILE) || die "Can't close $conffile: $!";
}

sub docmd ($$) {
    my ($dbh, $cmd) = @_;
    print "Doing $cmd\n" if $verbose;
    $dbh->do($cmd);
}

sub main () {
    my $foundarg = 0;
    if (0 == @ARGV || $ARGV[0] =~ m!help!i) {
	usage ();
    }
    readconf (); 
    my $dsn = "DBI:$database_type:database=$database_name:".
	"host=$database_host:port=$database_port";
    my $dbh = DBI->connect($dsn, $database_user, $database_pass, 
			   { PrintError => 0, RaiseError => 1 });
    die "$DBI::errstr\n" unless($dbh);
    for (;;) {
	my $line = ;
	last unless defined $line;
	chomp $line;
	if ($line !~ m!^\s*(\d+(\.\d+)*)?\s*(\#.*)?$!) {
	    die "Syntax error at $line";
	}
	my $ip = $1;
	if (! $ip) {
	    print "Skipping blank line $line\n" if $verbose;
	    next;
	}
	print "Found ip $ip.\n" if $verbose;
	my $didsomething = 0;
	if ($ARGV[0] eq "-delete") {
	    $didsomething = 1;
	    docmd ($dbh, "delete from relaytofrom where relay_ip = '$ip'");
	} else {
	    usage () unless 3 == @ARGV;
	    my $date = "$ARGV[1] $ARGV[2]";
	    if ($ARGV[0] eq "-blacklist") {
		$didsomething = 1;
		docmd ($dbh,
		       "insert into relaytofrom ".
		       "(block_expires, record_expires, create_time, relay_ip) ".
		       "values ('$date', '$date', now(), '$ip')");
	    } elsif ($ARGV[0] eq "-whitelist") {
		$didsomething = 1;
		docmd ($dbh,
		       "insert into relaytofrom ".
		       "(relay_ip, record_expires, create_time) ".
		       "values ('$ip', '$date', now())");
	    }
	}
	if (!$didsomething) {
	    usage ();
	}
    }
    $dbh->disconnect();
}

main ();

noch executable machen:

chmod 775 add-list.pl 

Jetzt das whitelist_ip.txt editieren und die IPs hinzufügen, die vom Filter ignoriert werden sollen.

vi whitelist_ip.txt

Eigene Server hinzufügen und wer sonst noch ausgeschlossen werden soll

217.150.250.113 # violet

dann gibts noch das blacklist_ip.txt – dort eingetragene server werden immer SOFORT abgewiesen. da gibt es keinen zweiten zustellungsversuch mehr.

nach Update, die Files importieren:

./add-list.pl -whitelist 9999-12-31 23:59:59 < whitelist_ip.txt
./add-list.pl -blacklist 9999-12-31 23:59:59 < blacklist_ip.txt

Es kann sein, dass es zu folgender fehlermeldung kommt:

./add-list.pl -whitelist 9999-12-31 23:59:59 < whitelist_ip.txt
Error evaluating this line from /etc/mail/relaydelay.conf:
$log_file = '/var/log/relaydelay.log';

Global symbol "$log_file" requires explicit package name at (eval 31) line 1,  line 27.

In dem fall muss man das /etc/mail/relaydelay.conf wie folgt anpassen (einfach ein my vor die variabeln):

my $run_as_daemon = 1;
my $log_file = '/var/log/relaydelay.log';

Dieser Script importiert nun die IP adressen in die Mysql Datenbank.

Startup Script

Damit RelayDelay beim Booten gestartet wird, ins rc.conf eintragen:

vi /etc/rc.conf

Add Lines:

#-----------------------------------------------#
#       GreyListing                             #
#-----------------------------------------------#
relaydelay_enable="YES"

Dann müssen wir den Startscript selber auch noch anpassen, damit er nach dem manuellen starten auch im Hintergrund läuft:

vi /usr/local/etc/rc.d/relaydelay.sh
/usr/local/sbin/relaydelay.pl $CONFIG &

relaydelay.conf

vi /etc/mail/relaydelay.conf 

Folgendes ändern:

# $pass_mail_when_db_unavail = 0;
$pass_mail_when_db_unavail = 1;
# $delay_mail_secs = 58 * 60;  # 58 Minutes
$delay_mail_secs = -1;  # Beim 2. Versuch sofort zustellen

Das ist ein sehr langes timout. Wenn ich das auf -1 setze, dann wird das mail nur 1mal abgewiesen. Beim zweiten Versuch sofort zugestellt. So gibt es auf unserer Seite das kleinste Timeout. Ich würde es zuerst mal auf -1 setzen, dann eine Weile beobachten und je nachdem optimieren.

Flattr this!

  • *

    Du kannst diese HTML tags verwenden: <a> <abbr> <acronym> <b> <blockquote> <cite> <code> <del> <em> <i> <q> <s> <strike> <strong>

  • Kommentar-Feed für diesen Beitrag
nach oben