########################################################## # Defense in Depth - Anti-SPAM for sendmail environments # # by David Bank --> http://dave.trianglenug.org # ########################################################## # Code Example #1 - Perl - MIMEDefang - filter_relay() # ########################################################## # GLOBAL VARIABLES - declared outside any function ############################### # Hash of internal hosts # - Key: IP addresses we consider internal # - Value: Flag as to if host if Virus-scan exempt (0=No, 1=Yes) ############################### %OurHosts=( "127.0.0.1", 0, "10.0.0.1", 0, "192.168.1.1", 1 ); # List of RBL servers to check @RBL_list=qw{ sbl.spamhaus.org dnsbl.njabl.org bl.spamcop.net cbl.abuseat.org }; # Timeout (in seconds) for RBL check $RBL_timeout=8; # Maximum number of positive RBL responses before we don't care any more $RBL_max=3; [...] sub filter_relay { # Read parameters passed to function my($ip, $name)=@_; # Pointer to hash returned from RBL check function my($rblhash); # Local variables for analysis my($rblserver, $rblresult, $rblscore); my($tempfail_flag)=0; # Search the list of our hosts using the $hostip argument if ( exists($OurHosts{$ip}) ) { # The connecting host is our own host, don't bother checking further return('CONTINUE', 'ok'); } else { # This host is not our host - check RBLs $rblhash=relay_is_blacklisted_multi($ip, $RBL_timeout, $RBL_max, @RBL_list); } # Evaluate RBL results foreach $rblserver (keys(%$rblhash)) { $rblresult=$rblhash->{$rblserver}; # If the value returned by a specific RBL server is an array, then # the RBL had a listing for this IP if (ref($rblresult) eq "ARRAY") { $rblscore=$rblscore + 1; } else { if ($rblresult eq "SERVFAIL") { # A lookup failed - set a flag to TEMPFAIL the mail if # enough other RBLs have the IP listed $tempfail_flag=1; } # End of IF } # End if IF } # End of FOR loop # If the RBL score is RBL_max or higher, we REJECT the connection if ($rblscore >= $RBL_max) { return('REJECT', "$name appears on multiple IP blacklists; see SPAM database lookup at http://www.dnsstuff.com"); } # If we are here, then the IP was not on a sufficient number of RBLs to be # rejected. However, we can TEMPFAIL the connection if the IP was listed # on "RBL_max - 1" RBLs and there was at least one RBL lookup failure if ( ($rblscore + $tempfail_flag) == $RBL_max ) { return('TEMPFAIL', "Please try again later"); } # If we have reached this point, the connection is either not blacklisted, or # does not appear on enough blacklists - allow it to proceed return('CONTINUE', 'ok'); } # End of sub filter_relay