[Dovecot] Running spamc during LMTP delivery
martin f krafft
madduck at madduck.net
Thu Aug 9 15:23:51 EEST 2012
also sprach Daniel Piddock <dgp-dove at corefiling.co.uk> [2012.08.08.1201 +0200]:
> Have you taken a look at Pigeonhole and Sieve? There's
> experimental support for running spam filters and external
> commands. You'll need at least 0.3.0 which requires Dovecot 2.1.
Dear list,
here is an update. Indeed, the pigeonhole filters suggested by
Daniel were the ticket. It took me a while to figure it all out
though. Therefore, for posterity, at least for those running Debian
systems:
First, I compiled the extprograms plugin, running into a segfault,
which Stephan helped me solve. Essentially, the extprograms are not
in Debian, but everything else is (install dovecot-dev!), so
I checked out revision 058de395713a [1], ran
./configure --with-dovecot=/usr/lib/dovecot
--with-pigeonhole=/usr/include/dovecot/sieve
--with-prefix=/usr/local/stow/pigeonhole-extprograms
make
make install
cd /usr/local/stow/
stow pigeonhole-extprograms
1. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=684271#10
Since dovecot only allows a single plugin dir to be specified, I had
to hack around this by creating a symlink:
ln -s /usr/local/lib/dovecot/sieve /usr/lib/dovecot/modules
Now, after enabling the following in /etc/dovecot/conf.d/90-sieve:
sieve_extensions = +vnd.dovecot.filter
sieve_plugins = sieve_extprograms
you should see 'vnd.dovecot.filter' in the dovecot -n output:
dovecot -n | grep vnd.dovecot
managesieve_sieve_capability = fileinto reject envelope
encoded-character vacation subaddress comparator-i;ascii-numeric
relational regex imap4flags copy include variables body enotify
environment mailbox date ihave vnd.dovecot.filter
^^^^^^^^^^^^^^^^^^
I used sieve_global_extensions instead, because I wanted to enable
spamc globally for all users using the dovecot LDA, which includes
all virtual users on this machine. I also set (in 90-sieve.conf)
sieve_before = /etc/dovecot/sieve.before.d
and then put the following sieve script into /etc/dovecot/sieve.before.d/spamassassin.sieve:
require [ "vnd.dovecot.filter" ];
filter "spamc" [ "--no-safe-fallback" ];
and then ran
sievec spamassassin.sieve && chmod 444 spamassassin.svbin
To tell the LDA where to find the spamc filter, I added (to
90-sieve.conf):
sieve_filter_bin_dir = /etc/dovecot/sieve-filter
and symlinked spamc there
ln -s /usr/bin/spamc /etc/dovecot/sieve-filter/spamc
So far so good, this now works for real system users, but it would
not work for virtual users. The reason for that is that while vmm
uses UIDs/GIDs above 70000 to tighten permissions per-virtual-user,
spamc and spamd were unable to deal with the lack of libnss
integration.
Stephan suggested simply to let libnss know about the virtual mail
accounts, and I did. After installing libnss-pgsql2 and extending
/etc/nsswitch.conf to read
passwd: compat pgsql
group: compat pgsql
I wrote the attached configuration file (/etc/nss-pgsql.conf), which
I will submit to the vmm project. The advantage is that now, while
the users cannot log in, their UIDs/GIDs on the filesystems are
properly mapped, and root *can* /bin/su to them (using -s to
override the shell).
After a restart of spamd and dovecot, spamc is now run for every
user as part of the LDA process before the user's sieve script runs.
Thanks to Stephan for his help. Comments welcome. I hope I did not
forget anything.
PS: I know there are good reasons against running a spamfilter
post-queue. There are also several reasons for that. The most
important for me is that spam is subjective, especially in
combination with training, and I never want to reject spam for
fear of false positives, and since I do not want to overload the
queues of mail servers (like debian.org) that forward to my
account.
--
martin | http://madduck.net/ | http://two.sentenc.es/
"the unexamined life is not worth living"
-- platon
spamtraps: madduck.bogus at madduck.net
-------------- next part --------------
connectionstring = hostaddr=127.0.0.1 dbname=vmm user=nss password=5ecr41 connect_timeout=1
getgroupmembersbygid = SELECT local_part||'@'||domainname AS name FROM users JOIN domain_name USING (gid) WHERE gid = $1 AND is_primary = 't'
getpwnam = SELECT local_part||'@'||domainname AS name, '*' AS passwd, 'vmm virtual mail account' AS gecos, domaindir ||'/'||uid AS homedir, '/bin/true' AS shell, uid, gid FROM users JOIN domain_data USING (gid) JOIN domain_name USING (gid) WHERE local_part = split_part($1, '@', 1) AND domainname = split_part($1, '@', 2) AND is_primary = 't'
getpwuid = SELECT local_part||'@'||domainname AS name, '*' AS passwd, 'vmm virtual mail account' AS gecos, domaindir ||'/'||uid AS homedir, '/bin/true' AS shell, uid, gid FROM users JOIN domain_data USING (gid) JOIN domain_name USING (gid) WHERE uid = $1 AND is_primary = 't'
allusers = SELECT local_part||'@'||domainname AS name, '*' AS passwd, 'vmm virtual mail account' AS gecos, domaindir ||'/'||uid AS homedir, '/bin/true' AS shell, uid, gid FROM users JOIN domain_data USING (gid) JOIN domain_name USING (gid) WHERE is_primary = 't'
getgrnam = SELECT domainname, '*' AS passwd, gid, NULL AS members FROM domain_name WHERE domainname = $1
getgrgid = SELECT domainname, '*' AS passwd, gid, NULL AS members FROM domain_name WHERE gid = $1
groups_dyn = SELECT domainname, '*' AS passwd, gid, NULL AS members FROM domain_name WHERE is_primary = 't'
allgroups = SELECT domainname, '*' AS passwd, gid, NULL AS members FROM domain_name WHERE is_primary = 't'
-------------- next part --------------
A non-text attachment was scrubbed...
Name: digital_signature_gpg.asc
Type: application/pgp-signature
Size: 1124 bytes
Desc: Digital signature (see http://martin-krafft.net/gpg/sig-policy/999bbcc4/current)
URL: <http://dovecot.org/pipermail/dovecot/attachments/20120809/a0dfc9d4/attachment-0004.bin>
More information about the dovecot
mailing list