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.