milter quota

Ενα milter για να γλιτώσουμε (κι άλλο) backscatter.

Υποθέτουμε οτι στο mail σύστημά μας έχουμε Frontend και Backend mail servers.

Ενας τυπικός frontend mail server κάνει μία σειρά από ελέγχους, πχ. Reverse DNS Lookups, dnsbl lookups, whitelist/blacklist checks, Level-1 attachment cut-off, Anti-Virus scan κλπ.

Το mail που περνάει επιτυχώς όλα τα παραπάνω, πρέπει να πάει στους backend servers και αφού γραφτεί στο mailbox, να περιμένει τον χρήστη να το διαβάσει. Στην περίπτωση όμως που ο χρήστης υπερβαίνει το quota του, τότε το backend δε θα καταφέρει να γράψει το mail στο mailbox, και θα αναγκαστεί να στείλει ένα NDR bounce message, το οποίο είναι backscatter..

Χρειαζόμαστε ένα μικρό (web)service στο backend, που θα μας λέει αν ένα mailbox είναι στο όριο ή όχι (overquota).

Για παράδειγμα αυτό το cgi script:

#!/usr/bin/perl
# This is /cgi-bin/quota.cgi

use CGI qw(:standard);

$username = param("u");
exit if ($username eq "");

$quota=200*1024*1024; # assume 200MB quota
$home="/var/mail"; # assume mbox format

$size = ( -s "$home/$username" );

print "Content-Type: text/plain\n\n");

if ($size>quota) {
    print "OVERQUOTA $username $size $quota\n";
} else {
    print "OK $username $size $quota\n";
}

Στο frontend εγκαθιστούμε τα perl modules LWP και Sendmail::Milter.

Παίρνουμε το sample.pl από το Sendmail::Milter και το διαμορφώνουμε κατάλληλα:

use LWP::Simple;

sub envrcpt_callback
{
        my $ctx = shift;
        my @args = @_;

        $email=@args[0]; # format is <user @dom.ain>
        $email =~ s/< (.*)>/$1/; # strip <>
        ($username, $domain) = split (/@/, $email);

        $be_response = get("http://$backend/cgi-bin/quota.cgi?u=$username");

        if ($be_response =~ /OVERQUOTA/) {
                #print "$email overquota\n";
                #RCODE 452 Requested action not taken: insufficient system storage (RFC 2821)
                #XCODE 4.2.2 Mailbox full (RFC 3463)
                $ctx->setreply('452', '4.2.2', "Quota exceeded for $email, try again later");
                return SMFIS_TEMPFAIL;
        }
        else {
                #print "$email not overquota\n";
                return SMFIS_CONTINUE;
        }
}

Το mail προς κάποιο overquota mailbox γίνεται tempfail και όχι reject, ώστε αν ο χρήστης αδειάσει το mailbox του να πάρει τα mails αργότερα..

Update: There is now a proof-of-concept cgi script for Maildir.

Advertisement