I guess the best way to combat this would be to use spamassassin as
a milter as well?
Or do you have another idea?
I had exactly the same problem when I was configuring DKIM on my server, and
I did exactly this - switched from using SA as a post-queue filter to using
it as a milter. Works good for me.
postfix is really quite flexible here. many ways, and tradeoffs, to approach
filtering & delivery (and, to shoot yourself in your own foot!).
in one medium-duty case (~ 5K messages / day), I host a postfix instance on an
edge VPS.
years ago it was bogging down with amavis/rspam. i looked for a lighter,
better-behaved solution.
this works for me.
is it the most efficient, or guaranteed robust? certainly not, but it never
noticeably bogs down for my usage, avoids double passes, and has been running
in production since i switched to it.
and i find it easy to config & maintain.
YMMV.
for inbound, postscreen listens,
[mx.example.com]:25 inet n - n - 1 postscreen
-o smtpd_service_name=postscreen-internal
is passed to internal smtpd,
postscreen-internal pass - - n - - smtpd
...
-o smtpd_proxy_filter=[127.0.0.1]:33010
where 127.0.0.1:33010 is the listener for Fastmail Authentication milter, which
handles SPF/DKIM/DMARC/etc authentication + headers,
https://github.com/fastmail/authentication_milter
, and which I run in its 'smtp' mode. After scan + header adds, it reinjects
to postfix preq milters
[127.0.0.1]:33020 inet n - n - - smtpd
...
-o milter_protocol=6
-o milter_default_action=reject
-o
smtpd_milters=unix:/run/mregex/mregex.sock,unix:/run/clamav-milter/clamav-milter.sock,unix:/run/sa-milter/sa-milter.sock
-o smtpd_service_name=[127.0.0.1]:33030
, passing through milter checks for
milter-regex (https://www.benzedrine.ch/milter-regex.html)
clamav
(https://docs.clamav.net/manual/Usage/Configuration.html#clamav-milterconf)
spamassassin (https://crates.io/crates/spamassassin-milter)
which, on pass, inject again to
[127.0.0.1]:33030 inet n - n - - smtpd
-o content_filter=${def_dbtype}:${cfgdir}/relay_transports
and sends along to final delivery destinations (e.g., over a VPN link to an
internal box with a postfix+dovecot instance)
for outbound submissions, I sign with dkimpy milter
[int.mx.example.com]:465 inet n - n - - smtpd
...
-o smtpd_milters=unix:/run/dkimpy-milter/dkimpy-milter.sock
-o milter_macro_daemon_name=DKIM_ORIGINATING
-o cleanup_service_name=cleanup-out
where, additionally, I do outbound header cleanup/rewrites
...
cleanup unix n - n - 0 cleanup
cleanup-out unix n - n - 0 cleanup
...
-o syslog_name=cleanup-out
-o mime_header_checks=pcre:${cfgdir}/header_checks-out.pcre
-o header_checks=pcre:${cfgdir}/header_checks-out.pcre
...
of course, there's lots of add'l config that meets my specific needs; e.g., all
transits are TLS protected, DANE's in place, etc etc.
it's fairly trivial to move/replace pieces to other boxes, add redundancy, etc.