Support providing arguments to Mail::SPF::Server::new to work around hard-coded limitations like for DNS-lookups.
We are using PolicyD for implementing quotas and SPF-checks and recently had the problem that one of our(!) customers was notified about the following errors by one of its(!) customers:
Recipient address rejected: Failed SPF check; kobe.eu, Maximum DNS-interactive terms limit (10) exceeded
Logs look like the following:
Jan 2 12:10:09 mail cbpolicyd: module=CheckSPF, action=reject, host=18.104.22.168, helo=lb1-smtp-cloud8.xs4all.net, from=[...], to=[...], reason=spf_permerror Jan 2 12:10:09 mail postfix/smtpd: NOQUEUE: reject: RCPT from lb1-smtp-cloud8.xs4all.net[22.214.171.124]: 554 5.7.1 <[...]>: Recipient address rejected: Failed SPF check; kobe.eu, Maximum DNS-interactive terms limit (10) exceeded; from=<[...]> to=<[...]> proto=ESMTP helo=<lb1-smtp-cloud8.xs4all.net>
Looking at what the sender of the mail publishes for SPF, the error message is totally correct, as 10 seems to be defined as hard limit and other services checking SPF-entries warn about too many lookups as well:
SPF Included Lookups Too many included lookups (11)
Warning : The maximum amount of 10 lookups exceeded. ISPs could ignore your SPF record
Because of the exceeded limit, PolicyD results in a permanent error and according our config failed SPF-checks result in mails being rejected in the end. From what I see, I'm not able to configure those kinds of permanent errors differently, so would either reject things like currently or accept all mails and some kind of defeat the SPF-checks entirely.
The problem is that my customer simply wants to receive the mails from its customer and doesn't care much about SPF and stuff and it's difficult to tell its customer's IT or service provider about the problem in a timely manner. Additionally, what standards define is one thing, what I'm willing to accept another and in this concrete case I could easily live with allowing 11 or even 15 DNS-lookups.
But PolicyD doesn't allow me to override the hard limit even though it doesn't check SPF on its own, but uses
Mail::SPF::Server instead and that supports overriding its limits:
An integer denoting the maximum number of terms (mechanisms and modifiers) per SPF check that perform DNS look-ups, as defined in RFC 4408, 10.1, paragraph 6. If undef is specified, there is no limit on the number of such terms. Defaults to 10, which is the value defined in RFC 4408.
Looking at your SPF-plugin, it already has the infrastructure to read arbitrary content from the config of PolicyD and uses that to e.g. decide on its own if the plugin is enabled or not. So I suggest to add additional config statements which get simply forwarded to
Mail::SPF::Server::new, as currently an empty CTOR is called always, resulting in hard limits to be used which I would like to relax. That doesn't even need to be per domain or stuff like that, in the easiest case only the keys already supported by
new might be read from the config. Though, some prefix like
mail_spf_ might be of help to distinguish other configs for the plugin itself in future.
My current workaround to that problem is to have created a custom plugin like
/usr/local/lib/postfix-cluebringer, which forwards all the hard work to the official one. The only thing I'm doing is replacing the call to
Mail::SPF::Server::new with a custom implementation adding hard-coded different limits. Thanks to Perl and https://metacpan.org/pod/Sub::Override this was pretty easy to achieve in the end, but took me some time to think about that possibility.
Reason is how
CheckSPF is implemented currently, one is not able to access e.g.
$spf_server to replace it with another instance and of course I don't want to reimplement everything, even if it's only C&P. I'm using PolicyD provided by Ubuntu-repos and prefer being as compatible with those packages and their changes as possible. The default values of
Mail::SPF::Server OTOH are constants and can't be replaced easily as well.
That workaround shouldn't need to be necessary in my opinion, users should be allowed to configure more aspects about SPF-checking. Especially if it's as easy as it seems to be with what is available and used already. Thanks!