Skip to content. | Skip to navigation

Navigation

You are here: Home / Support / Guides / Tools / Email / PolicyD / Policy Inconsistencies

Personal tools

PolicyD

A Postfix policy daemon

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