[Mimedefang] Including archetypal filters to include in release?

Philip Prindeville philipp_subx at redfish-solutions.com
Tue Jan 10 19:47:25 EST 2006


David F. Skoll wrote:

>Or, the original poster may be invoking mimedefang without the "-r"
>option, in which case filter_relay is never called.
>
>Regards,
>
>David.
>  
>

I wasn't paying attention, apparently, that the default config in 
/etc/sysconfig/
didn't include sender and relay checking.  Or perhaps the name of the 
variable
confused me (MX_...), since in the more frequent case that I was trying to
solve, it had to do with a UA and not an interim MXer...

Anyway, once that was straightened out, a lot of bugs in the logic 
started to
show up (that and a lot of email got bounced or deferred).

I've attached what I've got now in place.  Next I'll try to integrate 
Net::CIDR.

BTW:  In the case where there is no rDNS for an incoming connection...
what would be the approximate false positive rate be if we were to refuse
those connections (unless of course they were authenticated or local)?

-Philip

-------------- next part --------------
my %badnetworks = (
    '58.71.0.0/17',	'REJECT',
    '62.117.127.0/25',	'REJECT',
    '66.165.224.0/20',	'REJECT',
    '69.72.128.0/17',	'REJECT',
    '69.240.0.0/12',	'REJECT',
    '82.208.169.0/24',	'REJECT',
    '84.13.0.0/17',	'REJECT',
    '198.59.0.0/15',	'REJECT',
    '212.44.242.0/16',	'REJECT',
    '212.145.160.0/21',	'REJECT',
    '212.145.192.0/20',	'REJECT',
    '216.191.0.0/16',	'REJECT',
    '217.165.0.0/21',	'REJECT',
    '217.165.32.0/22',	'REJECT',
    '218.78.0.0/15',	'REJECT',
    '218.80.0.0/14',	'REJECT',
    '220.224.0.0/14',	'REJECT',
    '222.136.0.0/11',	'REJECT',
    # local mail
    '127.0.0.1/32',	'CONTINUE',
    '192.168.1.0/24',	'CONTINUE',
    # wildcard action
    '0.0.0.0/0',	'CONTINUE',
);

# return an int, rather than a packed string
sub Inet_ntoa($) {
    my $num = shift;
    inet_ntoa(pack('N', $num));
}

sub Inet_aton($) {
    my $str = shift;
    unpack('N', inet_aton($str));
}

sub cmpbymask() {
    my ($addra, $lena) = split('/', $a);
    my ($addrb, $lenb) = split('/', $b);

    $lena <=> $lenb;
}

sub filter_relay($$) {
    my ($hostip, $hostname) = @_;

    md_syslog('debug', "$QueueID: relay: $hostip, $hostname");

    my $ip = Inet_aton($hostip);

    # search the hash in order of most specific netmask to least...
    # interim fix until we use Net::CIDR::Lite
    foreach my $lhs (reverse(sort cmpbymask keys(%badnetworks))) {
        my $action = $badnetworks{$lhs};

        my ($net, $len) = split('/', $lhs);

        # md_syslog('debug', "$QueueID: net=$net, len=$len");

        $net = Inet_aton($net);

        my $mask = (0xffffffff << (32 - $len)) & 0xffffffff;

        # check for a match... if so, we return immediately
        if (($ip & $mask) == $net) {
            my $msg = ($action eq 'CONTINUE') ? 'OK'
                       : "This network is blacklisted";

            md_syslog('debug', "$QueueID: match: $hostip " . Inet_ntoa($net) . "/$len");
            md_syslog('info', "$QueueID: relay: $action: $msg");
            return ($action, $msg);
        }
    }

    # we shouldn't hit this, but if we do... default action is to accept
    md_syslog('debug', "$QueueID: no match; defaulting");
    return ('CONTINUE', "OK");
}

sub filter_sender($$$$) {
    my ($sender, $hostip, $hostname, $helo) = @_;

    md_syslog('info', "$QueueID: sender: $hostip, $hostname said \"helo $helo\"");

    # dotted quads need to be bracketed
    if ($helo =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/) {
        md_syslog('info', "$QueueID: no brackets: $helo");
        return ('REJECT', "Incorrect format for address-literal");
    }

    # ok, got the format right... now is the address correct?
    # this might be wrong if our clients are behind a NATting gateway;
    # if that's the case, we need to preface this with accepting everyone
    # whose $hostip matches a certain address or address range
    if ($helo =~ /^\[(\d{1,3})\.(\d{1,3}).(\d{1,3})\.(\d{1,3})\]$/) {
        if ($helo ne "[$hostip]") {
            md_syslog('info', "$QueueID: wrong ip: $hostip claims to be $helo");
            return ('REJECT',
                    "Header forgery attempt, [$hostip] claims to be $helo");
        }
    }

    # put this in explicitly, in case the test below is disabled.
    if ($helo eq 'localhost') {
        md_syslog('info', "$QueueID: localhost: $hostip ($hostname)");
        return ('REJECT', "Nothing local about you");
    }

    # doesn't contain any dots
    if (index($helo, '.') == -1) {
        md_syslog('info', "$QueueID: not fqdn: $helo");
        return ('REJECT', "Expected fully-qualified domain name");
    }

    return ('CONTINUE', "OK");
}



More information about the MIMEDefang mailing list