Tutorial
Now the limit is your imagination, we have some nice ACLs that we can combine and make them work very nice. This tutorial will show some recipes, for more details look at AclList, there you can find a lot of information about the ACLs.
Basic example
acl foo sender foo@domain.com acl bad_domain sender @spammer.com action deny_spam REJECT Your domain is evil! action nice_users OK access foo nice_users access bad_domain deny_spam
There is no big secret, when the sender is foo@domain.com, we accept the message, in case the domain of the sender is spammer.com, we reject it.
Protecting accounts
It is a common task to mail admins, to protect some accounts, like account bar@domain.com should not receive messages from users outside domain.com.
acl bar recipient bar@domain.com acl domain sender @domain.com action deny_intruder REJECT This email does not receive outside of domain.com access bar !domain deny_intruder
This can be done with Postfix without problems, take a look at http://www.postfix.org/RESTRICTION_CLASS_README.html, the advantage of using apolicy is that you don't need do deal with the main.cf configuration file, creating restriction classes and more files, that is the point.
Message size limit by e-mail
We can create a nice control for message size limit:
acl foo recipient foo@domain.com acl bar recipient bar@domain.com acl 10mb size 10240000 acl 20mb size 20480000 action deny_max_10mb REJECT This user can not receive more than 10mb action deny_max_20mb REJECT This user can not receive more than 20mb access foo 10mb deny_max_10mb access bar 20mb deny_max_20mb
Now if a message is sent to foo@domain.com and is bigger than 10 Mb, Postfix will reject, but if the message is for bar@domain.com, the message can have up to 20 Mb. Note that for this ACL work, you need at least Postfix 2.2 and the policy service be called from smtpd_end_of_data_restrictions, apolicy will test if the protocol state is END-OF-MESSAGE and in case it isn't, ACLs of type size will never match.
Multi-valued ACLs
When an ACCESS line is verified, all ACLs should return true, then the action specified will be returned to Postfix. An AND is done with all results. But it is possible that one ACL matches different types.
acl bar recipient bar@domain.com acl bar sender bar@domain.com action allow_bar OK access bar allow_bar
This construction will test the recipient and sender inside the same ACL, but only one can match. It is done an OR, the first line that matches will return true. So, in this case, if actually the recipient is bar@domain.com, then the next part of the ACL will not be tested and the ACL bar will match. This feature can be used to create an ACL that matches various e-mails.
Redirecting messages
acl list recipient sales@domain.com acl list recipient contact@domain.com acl list recipient webmaster@domain.com action destination_foo REDIRECT foo@domain.com access list destination_foo
If the recipient is sales@domain.com or contact@domain.com or webmaster@domain.com, it will be redirected to foo@domain.com.
Storing lists in files
Lets say you need to specify a huge number of senders, that would make the configuration too big, so lets separate the content.
acl list senders /etc/apolicy/senders.txt
Inside the file senders.txt there must be a value per line.
Verifying SPF
To verify SPF, you have to create a spf ACL, and make it available with the access statements.
acl restrict_spf spf action deny_bad_spf REJECT Sender spoofing detected access restrict_spf deny_bad_spf
The spf is special, because it doesn't need a value, instead, the ACL have parameters for configuration. Lets suppose you want a more restrictive configuration, where domains configured with softfail must be denied. It's possible to change the default behavior.
acl restrict_spf spf softfail=reject action deny_bad_spf REJECT Sender spoofing detected access restrict_spf deny_bad_spf
Now if a SPF check returns an softfail, instead of letting the message pass, the default behavior specified by the RFC, we can reject the message.
If you have a server with high traffic, it's wise to use greylisting before checking SPF, because there is a huge amount of DNS servers that do not respond or are not configured properly. Querying DNS could be a big bottleneck.
You may have high traffic from domains that are known to do not publish SPF records, like Yahoo. So, you can skip the SPF verification in this case.
acl yahoo sender @yahoo.com acl restrict_spf spf softfail=reject action deny_bad_spf REJECT Sender spoofing detected access !yahoo restrict_spf deny_bad_spf
Notice that !yahoo appears before restrict_spf, so if the sender is from Yahoo, this ACL will return true, but we have ! there, so the value returned by the ACL is inverted, becoming a false. As soon an ACL returns false, the next ACLs will not be processed.
Controlling by day and time
Other nice ACLs that apolicy has is the day and time. With them, you can restrict or redirect the transport of a message based on the day of the week and the current time.
You have a support@domain.com address, and two people take care of this address in different shifts. With pure Postfix, support@domain.com can only be an alias to the e-mails of the workers, so one worker receives e-mails from the shift of the other, duplicating everything. Lets solve this.
acl support recipient support@domain.com acl shift_one time 06:00-11:59 acl shift_two time 12:00-18:00 action to_worker_one REDIRECT worker1@domain.com action to_worker_two REDIRECT worker2@domain.com access support shift_one to_worker_one access support shift_two to_worker_two
Sweet! Now they will only receive e-mails that arrive on their shift.
Lets say your company has some policy that requests a department to do not receive e-mails on weekends.
acl requests recipient requests@domain.com acl weekends day as action no_requests REJECT Sorry, no request can be accepted on weekends. access requests weekends no_requests
Very nice. With the ACL day we specified that on Saturday and Sunday the requests@domain.com won't accept e-mails. The value as for the ACL weekends is a for Saturday and s for Sunday.
Greylisting
Greylisting in apolicy is not a default behavior like in other Policy Daemons, it must be combined with ACLs, Actions and Access statements.
acl grey_all greylisting time=5,lifetime=15,backend=memory action to_greyslist DEFER_IF_PERMIT Greylisting, try in 5 minutes... access grey_all to_greyslist
Just like the spf, the greylisting ACL does not have a value, instead is uses comma separated list of variables that configures the behavior os the ACL.
The basic values are:
time: the period for not accepting a message, in minutes
lifetime: how long should a validated tripled be used, in minutes
backend: the storage type, possible values: disk and memory
For more details look at AclList, there you can find a lot of information about the ACLs.