hi all, I'm a french perl coder and debian admin, I've been lurking this list for few months, time to make known to Jedis ;)
thanx for the great tool qpsmtpd is, it saves my job position during the last massive spam attack on our servers, now Exim4 is merely poking at the underlying level, here is a mod for Marc Sebastian Pelzer's check_rcptto_exists : - instead of seeking user in the file-based Exim4 aliases routing tables, it asks MySQL Virtual Exim [http://silverwraith.com/vexim/] database if user exists on the system, - if you put any domain in the file /etc/qpsmtpd/rcptto_domains_nocheck, this domain passes through this plugin, allowing to have a catchall for it, don't know if it is the right place to post code, this is a draft, successfully tested in production, feel free to spread it and to report any feedback ! cheers, === check_rcptto_exists+vexim+catchall === # check_rcptto_exists Version 1.0 by Marc Sebastian Pelzer # # ============================================================================ # modified: 2007-12-03 by Etienne LEMEE aka Et!L3W <coding AT etilem DOT net> # in order to connect to vexim database # and to allow per domain catchall # ============================================================================ # # This plugin check wether a recipient of an incoming email exists in our local vexim # database. # # Access parameters to the database are hard-coded into this plug-in and you may need to # modify it a bit in order to fit your set-up. # # Should not be a big problem if you know Perl :) # # You should create a config-file called "config/relayclients" which should contain a (maybe # dynamically created) list of IP's or hostnames which are white-listed from this plug-in. # # You should also create a config-file called "config/rcptto_domains_nocheck" which should # contain a list of domains which are white-listed from this plug-in, allowing per domain # catchall # # It is recommended to put your relay-client's IP's inside this file, otherwise all outgoing # connections will be rejected because the recipient of the outgoing mail is not locally # known. # # Fell free to change that behaviour as you like and to use this plug-in as an example for # your own alias check. # use strict qw(vars); use Mysql; use Qpsmtpd::DSN; sub hook_rcpt { my ($self, $transaction, $recipient) = @_; my ($line, $user, $tmp); my $userExists = 0; my $remote_ip = $self->qp->connection->remote_ip; my $remote_host = $self->qp->connection->remote_host; # relayclients can send email to whoever thay want # my @relayclients = $self->qp->config("relayclients"); foreach $tmp (@relayclients) { if ($remote_host =~ m!$tmp! || $remote_ip =~ m!$tmp!) { $self->log( LOGNOTICE, "Ok - remote peer is a allowed RELAY client ($remote_host / $remote_ip)"); return DECLINED; } } return (DECLINED) unless $recipient->host && $recipient->user; my $host = lc $recipient->host; my $lpar = lc $recipient->user; # Et!L3W - domains found in /etc/qpsmtpd/rcptto_domains_nocheck passes through this plugin my @nocheckdomains = $self->qp->config("rcptto_domains_nocheck"); foreach my $tmp (@nocheckdomains) { if ($host =~ m!$tmp!) { $self->log( LOGNOTICE, "Ok - $host domain is allowed to have a catchall"); return DECLINED; } } # Et!L3W - connection to Mysql my ($db_host, $db_user, $db_pass, $db_base) = qw(localhost vexim CHANGEME vexim); my $dbh = Mysql->connect($db_host, $db_base, $db_user, $db_pass); $dbh->selectdb($db_base); my $sth; # Et!L3W - query for real domain, in case of domain alias (needs subselect feature from MySQL) $sth = $dbh->query(sprintf( "select domain from domains where domain_id in " . "(select domain_id from domainalias where alias='%s')", $host)); my $real = $sth->fetchrow; $host = $real ? $real : $host; my $from = $lpar . '@' . $host; # Et!L3W - query for username $sth = $dbh->query(sprintf( "select count(*) from users where username='%s'", $from)); $userExists = $sth->fetchrow; if ($userExists < 1) { # Et!L3W - I pick the default SMTPD timeout for qpsmtpd found in /etc/qpsmtpd/timeoutsmtpd # instead of hardcoding it to set the slow-down delay, or fall back to 60 seconds my $sleep = $self->qp->config("timeoutsmtpd") || 60; # Et!L3W - adding the delay advice (second logging message part) $self->log(LOGNOTICE, "Recipient '$from' does not exists here. " . "Slowing down spammer for $sleep seconds..."); sleep $sleep; # slow down spammer return Qpsmtpd::DSN->no_such_user("mail to $from not accepted here"); } # Et!L3W - adding the userExists count advice $self->log(LOGNOTICE, "OK, recipient '$from' exists [count=$userExists]. " . "Allowing to pass through ..."); return (DECLINED); } === rcptto_domains_nocheck === # domains, one per line, found in this file are not checked by check_rcptto_exists # e.g.: # domain.tld # anotherdomain.tld === timeoutsmtpd === # qpsmtpd timeout in seconds 30 -- Etienne /\_/\ (=°o°=) http://etilem.net