rblfilter - extract IP address from E-mail and check against RBL lists
rblfilter [ --filter | --debug ]
This program extracts the remote IP address from the Received: headers in an E-mail message, and checks it against one or more RBL-style lists. Specifically, it looks for the first line of the form:
Received: from not-our-mail-server by our-mail-server
This allows you to use RBL-style spam filtering even if you receive mail at some remote host (e.g. your ISP) where you cannot get them to do RBL checking at the time the message is received.
I receive mail via the forwarding service 'pobox.com', which then forwards to my ISP, from where I collect via POP3. Typically a message looks like this by the time I receive it:
Received: from pop3.demon.co.uk by localhost with POP3 (fetchmail-5.0.5) ... Received: from punt-2.mail.demon.net by mailstore ... Received: from growl.pobox.com ([22.214.171.124]) by punt-2.mail.demon.net ... Received: from somehost (somehost [z.z.z.z]) by growl.pobox.com ...
In this case, it is the [z.z.z.z] address which I want to check against the RBL. To do this, I simply give rblfilter some patterns to match *pobox.com and *mail.demon.net as 'my' mail servers.
Notice that because I included *mail.demon.net, this also works if someone sends mail directly to my ISP account; in this case, the relevant header is
Received: from somehost (somehost [z.z.z.z]) by punt-1.mail.demon.net ...
In general, you just list all the hosts where you have an E-mail account.
This is a perl program. Therefore, by definition, it is a hack :-)
You configure the program by editing the source code - look for @mymailservers and @rblservers at the top of the program, and edit to suit.
This program has three modes:
This is the default. It accepts message headers on stdin, finds the first suitable Received: header, looks it up in the RBL lists, and exits with 0 if the message is clean or 1 if it is listed in any of the RBL lists. Nothing is output on stdout.
This mode is best if you just need to detect quickly whether a single message is RBL listed. For example, in .procmailrc the following recipe will filter matching messages into a 'junk' folder:
:0: * ! ? /usr/local/bin/rblfilter Mail/junk
This is enabled by adding --filter to the command line. This copies every line from stdin to stdout, and if appropriate adds an
X-rblfilter: <RBL domain>
header for each RBL list matched. Multiple lines will be added if the address matches multiple RBL lists. Multiple messages separated by the UNIX mailbox separator 'From ' can be processed. The exit code is always 0.
This mode is useful for processing a whole mailbox file, or for processing mail whilst leaving the decision about which messages to keep or drop to the end-user (who can filter on the X-rblfilter: headers using their own mail client)
Enabled by adding --debug to the command line. This is identical to filter mode, but adds additional messages to show rblfilter's decision making process. This is useful to work out why rblfilter is not triggering on a particular message when you think it should be.
DO NOT CONFIGURE YOUR SYSTEM TO DELETE MAIL BASED ON THIS PROGRAM! Move it to a 'junk' folder instead. Not only does this protect you against bugs in the software, it also gives you a chance to save important mail from a machine which happened to be RBL-listed. Plus it gives you a file full of spam messages useful for testing :-)
In addition, don't attempt to automatically bounce messages which match the RBL. Spam almost always has forged return addresses, so all you will do is cause unnecessary grief to the person who legitimately owns the forged address.
Remember that using RBL filtering will slow down message delivery - sometimes by several seconds per message - while the RBL data is looked up in the DNS. This also means that you must stay connected to your ISP while the messages are being delivered.
Pipe an existing mailbox file through rblfilter --debug to check that the correct IP addresses are being extracted (look for ``X-Matched: ...''). If you have some stored junk mail which was relayed via an RBL-listed machine, even better.
RBL lists usually have a test address which is 127.0.0.2 or 127.0.0.3. If you are running rblfilter on a Unix machine, you can pass a test message directly to sendmail to trip your filter:
/usr/sbin/sendmail -v <your-address> Received: from 127.0.0.2 ([127.0.0.2]) by <your-mailserver>
This is a test .
(sendmail will also add its own Received: header, but since this won't contain an IP address for a locally-submitted message, it will be skipped by rblfilter)
Alternatively, if you have a shell account on the machine which receives your mail, you can login there and inject a mail message using telnet to the SMTP port:
telnet 127.0.0.2 25 HELO some.domain MAIL FROM:<someone@somewhere> RCPT TO:<youraddress@yourdomain> DATA Subject: This is a test message
Testing 1 2 3 . QUIT
This is ALPHA software. It has been developed under Red Hat Linux 6.0 i386 with perl-5.00503-2 and procmail-3.13.1-2. It may not work for you.
The format of Received: headers is variable, and unfortunately not yet standardised; the pattern which rblfilter looks for may not match the mailer used by your ISP.
Probably should do more error checking.
Probably should be written in a real programming language, with a real configuration file.
Brian Candler <B.Candler@pobox.com>. The latest version of this file should be available at http://pobox.com/~b.candler/software/rblfilter/