[RELEASE] SpamBlocker released

The firewall runs at the kernel level and is already running and already looking at all the packets.

Anyway, that's my opinion and the opinion of a bunch of people I've called and asked today.

Jeff
 
While I respect the opinion...don't see why you found the need to solicit the opinion of "a bunch of people". LOL.

Is there any realistic reason NOT to do it other then it goes against the opinion of a "bunch of people"? Will it cause security problems, servers to crash, upgrade problems?

Don't get me wrong, I respect your opinion, just curious as to why it's an issue to begin with. There are always more the one way to address an issue and not all will be the 'best', but doesn't mean they are wrong or don't work. And I think oxy made some compelling statements as to his reasoning.
 
sullise said:
While I respect the opinion...don't see why you found the need to solicit the opinion of "a bunch of people". LOL.
Because I could always be wrong :) .

I don't see a reason for not checking to see if others agree with me. And I'm certainly willing to say so when I've been wrong.
Is there any realistic reason NOT to do it other then it goes against the opinion of a "bunch of people"? Will it cause security problems, servers to crash, upgrade problems?
It will not cause security problems. It will definitely use more machine resources during, for example, a dictionary attack.

Why? Because each email coming in will have to go through the entire multi-packet-exchange smtp handshake (ehlo, mail-from, rcpt-to) before exim (running as a user process) will check it against files on disk to see if it should be accepted or not.

If you use iptables (the userspace interface to the kernel's netfilter, the packet is blocked the moment it's matched against a list residing in memory.
Don't get me wrong, I respect your opinion, just curious as to why it's an issue to begin with.
Being that I wrote the exim blocklist code we're debating, I'm concerned about people having higher expectations for it than they should have.
There are always more the one way to address an issue and not all will be the 'best', but doesn't mean they are wrong or don't work. And I think oxy made some compelling statements as to his reasoning.
The constantly changing deny chain"? A read on the differences between how ipchains and iptables work is probbly in order, though it's probably too technical by several orders of magnitude for a discussion here. And even if we were using chains rather than hashed tables in memory we'd still have all the advantages of the efficient kernel code rather than the slow interpreted lookup (note the code isn't interpreted, but each exim thread must read and interpret the entire exim.conf file, and then in the case of ACLs, read each of the referenced files completely) of exim.

Here's an appropriate quote from a post to exim-users made Jan 17, 2006 by Dr Philip Hazel, the author of exim:
Remember that every Exim process
reads and processes the config file when it starts up, and this happens a lot. I used to get worried at the amount of processing this might require, but nobody else seems to care. :)
I'm not saying that exim isn't great. I'm not saying that exim isn't elegant. I'm not saying that exim isn't easy to use.

I'm only saying under certain circumstances (and a dictionary attack from one IP# is certainly one of them) exim is slower than using filter tables already built into the kernel.

Jeff
 
Jeff,

All good points. I'm still struggling with this though. Yes, I realize now as you have so eloquently pointed out (and BTW, thank you for the research) that it is more efficient to let the firewall do the filtering. But is it practical?

I use APF. It's not great (Shorewall was great but it is now abandoned) but it does the job. It has a block list I can add to. But I really don't want to keep reloading the firewall to have it pickup the changes. I'd much rather just insert the IP address into the ACCEPT chain as a DROP. The problem is that exim does not have permission to do this.

So from a practical standpoint, how can I fire iptables from the mail user? If I could do that, the rest is easy.

The way I see it is, given the ACL changes I proposed easier, instead of firing dictscan.pl you fire dictscan.sh. dictsh does 2 things:

1: Adds the IP address to the chain.
2: Adds an AT job to remove the IP address automatically in 24/48 hours.

This solves the problem of reloading the firewall every time I have a new IP to add. (in my case, that's not too bad but it would mean I'd reload once every 3-4 minutes) If I ever do need to clear things out and start over, all I have to do is restart since I'm not storing these blocks on a perm basis anywhere.

Also importnat, it has an automatic cleanup. Right now, I have to go through exim_deny every few days and delete a bunch of IP addresses.

So does anyone know how to allow mail to run iptables on Linux?

=C=
 
PF

Does anyone have a working version of such a script that implements the PF firewall to block the IP's of identified spammers (like the dictionary scanner) ?

Unfortunately I do not know perl.

Any advice would be greatly appreciated

-Mike
 
My only issue is loading 20,000 IPs to iptables (using APF glob_deny) everytime the firewall needs to restart - or a change is made. This CAN take a significant amount of time - and it'd probably be reloading every few minutes.

For me, and thats all I'm really concerned about, this works fine.

Thanks to the dictscan original poster.
 
Hi All,

Until I can figure out a way to overcome the security issues I've expressed above, I'm using the system as is. (Once I can overcome those issues I will most likely move to a system where the firewall blocks.)

In the mean time, I need something to manage the exim_deny list to keep it from growing out of control. Ok, on my system 100 new IPs a day is a heavy day but still I don't want to have to remember to clean it. So I wrote this quick little script. This needs to be run by a user who has permission to read and write the /etc/exim_deny list. I run it in the root cron on a nightly basis.

I share it here for your use should you need it. Use at your own risk, etc. etc.etc.

=C=
p.s. for those having trouble pasting this into a script, you can download it from:

http://www.calevans.com/exim_deny_filter.txt



PHP:
#!/usr/local/bin/php
<?PHP
/**
 *
 * exim_deny_filter
 *
 * Reads in the exim_deny list of IP addresses and discards 
 * any that are over X seconds old. This works totally in memory 
 * so it may not be a good solution for large lists. It is meant 
 * to be called periodically from a cron job. The user running the 
 * job has to have permission to read and write the /etc/exim_deny 
 * file.
 * 
 * The project page for this code is:
 * [url]http://www.calevans.com/view.php/page/edf[/url]
 * 
 * @author Cal Evans <[email protected]>
 * @copyright 2006 Cal Evans
 * @license GPL 2.0
 * @package exim_deny_filter
 * @access public
 * @version 1.0
 *
 */
$o= &new Exim_Deny_Filter();
$o->main();
$o=null;
exit();
 
class Exim_Deny_Filter {
	var $file;
	var $seconds_to_keep;

	function Exim_Deny_Filter() {
		$this->file         = "/etc/exim_deny";
		$this->seconds_to_keep = 86400;
	} // function Exim_Filter()


	function main() {
		$lines = file($this->file);
		if (count($lines)<1) return;
		$ips = array();
		$break = mktime()-$this->seconds_to_keep;
		$file_handle = fopen($this->file,'w');
		for($lcvA=0;$lcvA<count($lines);$lcvA++) {
			if (substr($lines[$lcvA],0,1)=="#") {
				$time = strtotime(substr($lines[$lcvA],1));
				if ($time<$break) continue;
				$thisIP = trim(strtr($lines[$lcvA+1],"\n\r\t\0","    "));
				if (in_array($thisIP, $ips)) continue;
				fwrite($file_handle,"# ".date('m/d/Y h:i:s',$time)."\n".$thisIP."\n\n");
				$ips[] = $thisIP;
				$lcvA++;
			} // if (substr($lines[$lcvA],0,1)=="#")
		} // for($lcvA=0;$lcvA<count($lines);$lcvA++)

		fClose($file_handle);
	
	} // function main()
} // class Exim_Deny_Filter
?>
 
Last edited:
after update DA to v1.26.2
i can't send & received any mail :confused:

2006-01-22 11:31:32 H=(wwwrt) [**.**.**.**] F=<[email protected]> temporarily rejected RCPT <[email protected]>: failed to expand ACL string "${lookup{$sender_host_address}lsearch{/etc/virtual/pophosts_user}{${perl{find_user}{$value}}}}": Undefined subroutine &main::find_user called.
2006-01-22 11:31:33 H=(wwwrt) [**.**.**.**] incomplete transaction (QUIT) from <[email protected]>
 
Last edited:
Why not put exim_deny in /etc/virtual like the other lists and the other scripts in /var/edf

We can do it ourselves, but it's always good to have a logical default, no?
 
Cool, thx.
There is also a case that this deny filter misses. The one where a sender (IP) tries to send to one or more adresses using different Froms.
How hard would it be to also store those IPs?
I don't know if it's very common on your setups, but I do see it quite a lot.
 
Hi,

That' an interesting scenario and one I'm not qualified to cover. I didn't actually write the solution, I just inserted it into SpamBlocker. You may want to ask Jeff about this and if it can be covered.

=C=
 
Please don't ask me to take the time study the thread and try to figure out exactly what it is you want.

Please instead write a simple spec for what you want and if it can be easily added to SpamBlocker, and if it makes sense, I'll add it.

Jeff
 
Back
Top