PolicyD
Policy Inconsistencies
PolicyD isn't without its inconsistencies. As you diversify your categorisation from the orthogonal incoming and outgoing to any arrangement that isn't orthogonal then multiple policies can apply. Consider an incoming message from a trusted sender which will match your incoming trusted senders policy and the generic fallback policy (source any, destination any). How does PolicyD handle multiple matching policies?
Each policy has a priority and all modules honour the priority, iterating over all matching priorities from low to high.
If there is more than one matching policy with the same priority, however, then those policies are looped over in a random order. At least this can be mitigated by giving everything a unique priority -- easy enough if the database creation is scripted.
However, how each module uses the matching policies to apply rules to the email differ.
Consider the quotas module. Its goal is to tally up the number of emails sent (or size of the messages) in a rolling time window and if you're over the limit then the policy daemon's verdict is DEFER -- ie. the sender is asked to send the email again in a little while. OK, so which of the policy limits applies? The trusted sender quota (generous) or the fallback quota (harsh)? Both apply! Obviously the fallback quota will hit its harsh limit long before the trusted sender quota and the email will be deferred. Oh dear.
The quotas module, however, has a LastQuota flag which means that if this policy applies to the email then do not process any further policies. OK.
So that would lead you to believe that the correct expression of your policies is to have the more specific policies with the lowest priority (ie. first) leading to the least specific policy (the fallback one) last.
Hmm, CheckHelo, CheckSPF and Greylisting all work differently, though. For these, the resultant ruleset is effectively the last matching policy. In practice, for each matching policy the "result" is updated with the current policy's rules to be overridden by the next matching policy's rules (if set).
So that means the policies are effectively applied in the opposite order to quotas.
You can mitigate this by all-but doubling the number of policies (with increasing priority). A nominal policy sets of:
PID Name Pri Source Dest 1 Outgoing 10 %my_lans,%my_doms any 2 Trusted 20 %trusted %my_doms 3 Fallback 30 any any
might become:
PID Name Pri Source Dest 1 Outgoing 10 %my_lans,%my_doms any 2 Trusted 20 %trusted %my_doms 3 Fallback 30 any any 4 Trusted2 40 %trusted %my_doms 5 Outgoing2 50 %my_lans,%my_doms any
where the top half is duplicated in reverse in the second half.
You can have quotas associated with the top half of the policies and the CheckHelo, CheckSPF and Greylisting associated with the bottom half.
Ugly but do-able without rewriting PolicyD itself.
The AccessControl module operates in a way you might argue that all modules ought to operate in that the first matching policy is used.
Document Actions