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: $ifaddrn" 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$linen$@" ; } } close (INFILE) || die "Can't close $conffile: $!"; } sub docmd ($$) { my ($dbh, $cmd) = @_; print "Doing $cmdn" 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::errstrn" 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 $linen" 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.