This is actually a follow-up for #1713. I've finally found some time to tinker on it. I would share my solution and ask a few questions about possible improvements.
I've enabled avamis and spamassasin in the env, so starting up both incoming and outgoing messages are checked for spam.
ENABLE_AMAVIS=1
ENABLE_SPAMASSASSIN=1
So basically every message goes through postfix. I don't quite understand why after receiving the message by dovecot it gets transferred to postfix, and not directly to the inbox. I guess it's about reusing some useful parts like queues, spamchecks etc.
The solution I've found is to route the traffic either to amavis or a dummy filter to send out the message.
What is important here is the content_filter in /etc/postfix/main.cf
content_filter = smtp-amavis:[127.0.0.1]:10024
So the traffic always goes to smtp-amavis for it to handle the check and send the message. We can override this by using a FILTER like this:
smtpd_sender_restrictions =
check_sender_access FILTER smtp-amavis:[127.0.0.1]:10026
This would also use smtp-amavis, but on another port, which we could use to our advantage and disable some checks there, like this (config/amavis.cf):
$inet_socket_port = [10024, 10026];
#interface_policy{'10026'} = 'ORIGINATING';
$policy_bank{'ORIGINATING'} = {
originating => 1, # declare that mail was submitted by our smtp client
# don't perform spam/virus/header check.
bypass_spam_checks_maps => [1],
bypass_virus_checks_maps => [1],
bypass_header_checks_maps => [1],
# allow sending any file names and types
bypass_banned_checks_maps => [1],
final_spam_destiny => D_PASS, # insure spam passes
final_banned_destiny => D_PASS, # insure banned files pass
};
But this took ~400 ms per message, and I was not entirely happy with it.
Ok, back to the topic. We need a conditional here. This can be used to switch between originating and foreign:
smtpd_sender_restrictions =
check_sender_access regexp:/etc/postfix/tag_as_originating.re
permit_mynetworks
permit_sasl_authenticated
permit_tls_clientcerts
reject_unknown_sender_domain
reject_unknown_client_hostname
check_sender_access regexp:/etc/postfix/tag_as_foreign.re
And the filters looks like this.
echo '/^/ FILTER filter:dummy ' > /etc/postfix/tag_as_originating.re
echo '/^/ FILTER smtp-amavis:[127.0.0.1]:10024' > /etc/postfix/tag_as_foreign.re
The missing part is the filter. It should be created in master.cf
filter unix - n n - 10 pipe
flags=Rq user=filter null_sender=
argv=/opt/filter.sh -f ${sender} -- ${recipient}
It basically executes the /opt/filter.sh script:
#!/bin/sh
# Simple shell-based filter. It is meant to be invoked as follows:
# /path/to/script -f sender recipients...
# Localize these. The -G option does nothing before Postfix 2.3.
INSPECT_DIR=/var/spool/filter
SENDMAIL="/usr/sbin/sendmail -G -i" # NEVER NEVER NEVER use "-t" here.
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
EX_UNAVAILABLE=69
# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15
# Start processing.
cd $INSPECT_DIR || {
echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
cat >in.$$ || {
echo Cannot save mail to file; exit $EX_TEMPFAIL; }
$SENDMAIL "$@" <in.$$
exit $?
Finally, to the questions:
- the filter seems like a strange workaround, couldn't an existing service declared in
/etc/postfix/master.cf used instead? I've tried using smtpd:10025, but it would fail from time to time with "corrupted format" message (or something like that)
- the filter sends it using
sendmail, does postfix also use it? I'm not quite sure about the relationship between these two? I assume sendmail is a part of postfix`
- in the ideal case I would love to remove the entire filter part, I wonder if the
content_filter = smtp-amavis:[127.0.0.1]:10024 can be cancelled out completely - I have to check that
- I can't understand how the
smtpd_sender_restrictions works. I guess it looks for the first true value, so after finding permit_mynetworks to be true it doesn't process the params further
- do you see any points of what may fail here?
This is actually a follow-up for #1713. I've finally found some time to tinker on it. I would share my solution and ask a few questions about possible improvements.
I've enabled avamis and spamassasin in the env, so starting up both incoming and outgoing messages are checked for spam.
So basically every message goes through postfix. I don't quite understand why after receiving the message by
dovecotit gets transferred topostfix, and not directly to the inbox. I guess it's about reusing some useful parts like queues, spamchecks etc.The solution I've found is to route the traffic either to
amavisor a dummy filter to send out the message.What is important here is the
content_filterin/etc/postfix/main.cfSo the traffic always goes to
smtp-amavisfor it to handle the check and send the message. We can override this by using aFILTERlike this:This would also use
smtp-amavis, but on another port, which we could use to our advantage and disable some checks there, like this (config/amavis.cf):But this took ~400 ms per message, and I was not entirely happy with it.
Ok, back to the topic. We need a conditional here. This can be used to switch between originating and foreign:
And the filters looks like this.
The missing part is the filter. It should be created in
master.cfIt basically executes the
/opt/filter.shscript:Finally, to the questions:
/etc/postfix/master.cfused instead? I've tried usingsmtpd:10025, but it would fail from time to time with "corrupted format" message (or something like that)sendmail, does postfix also use it? I'm not quite sure about the relationship between these two? I assume sendmail is a part of postfix`content_filter = smtp-amavis:[127.0.0.1]:10024can be cancelled out completely - I have to check thatsmtpd_sender_restrictionsworks. I guess it looks for the firsttruevalue, so after findingpermit_mynetworksto betrueit doesn't process the params further