= 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.