Debian Qmail QFILTERs

The Debian Qmail package appears to have something like the qmail-qfilter feature patched into it. Setting it up wasn’t explained clearly, and I kept forgetting how it was done, so this article is a reference.

Filtration can be performed by replacing specifying a qmail-queue replacement, via the QMAILQUEUE environment variable, specified in /etc/qmail/tcp.smtp:

127.:allow,RELAYCLIENT=""
:allow,QMAILQUEUE="/var/lib/qmail/bin/qfilter-chain-of-filters"

I wrote a short shell script that calls my filters:

#! /bin/sh
exec /usr/local/bin/qmail-qfilter \
-- /var/lib/qmail/bin/qfilter-baddomains

There’s no need to call qmail-queue as a filter.

Here’s the code for one of the filters:

#!/usr/bin/perl

use Sys::Syslog;

openlog('qfilter-baddomains', 'pid', LOG_MAIL);

@evilsenders = (
'.+\@qq.com'
);

while(<STDIN>) {
print;
last if /^\n$/o;
last if /^\r\n$/o;
for my $sender (@evilsenders) {
if ( $_ =~ /^From:.+<$sender>$/ ) {
syslog('info', "Rejecting domain $sender");
exit(31);
}
}
}

while(<STDIN>) {
print;
}

The program is divided into two loops. The upper one is for the header, and the lower is for the body. In the upper loop, I search for a blank line that ends the header; upon finding it, control passes to the lower loop.

Exiting with status 31 tells qmail-qfilter to exit with a status message.

Exiting with 99 silently drops the email.