Even as an ISP you don't always have it easy, that's why we have put together a list of things you should consider as an ISP.
If you host many domains that also send e-mail using your services, let your users find out what they want in their SPF policies. Some of them also use other providers, not just your services. Some do not want to have nonsensical PASS or FAIL policies, some want PASS or NEUTRAL, and many are not interested in SPF as long as they do not have problems with fake e-mails from some@user.example. Something you could do for your customers: You have one or more outgoing mail servers that use EHLO mailer2.your.domain.example or similar names Then you can publish the guidelines for these HELO names. example: mailer2.your.domain.example. IN TXT "v=spf1 a -all"
This means that every mailer that claims to be mailer2.your.domain.example but has an address other than A (mailer2.your.domain.example) in the EHLO will receive a FAIL. The recipients, then check for SPF, hopefully reject the FAIL. It gets more interesting, because your users with different domains can't be sure which outgoing server you are using. However, your customers need to know or appreciate this if they want to publish policies for their domains and/or send e-mail using your services. Forcing users to guess is a bad idea.
To make this as easy as possible for your customers, your customers can list all outgoing servers by name (SPF "a" mechanism), by number (SPF ip4 or ip6 mechanism) or, if necessary, use the mx mechanism indirectly to list all names. Note, however, that MX is actually about your inbound servers. This trick is therefore only useful if your inbound happens to be identical to your outbound for your mail servers.
You can also be inaccurate here to a certain extent, e.g. if you have a / 24 with 256 IPs (of course not with all outbound SMTP servers): dummy.your.domain.example. IN TXT "v=spf1 ip4:11.22.33.44/24 ?all" This allows all 11.22.33.nn IPs in CIDR / 24 characters. Or say: dummy.your.domain.example. IN TXT "v=spf1 a:mailer2.your.domain.example/24 ?all"
You will get the same effect as long as the address of Mailer2 belongs to /24. You would then only tell your users that they can include this policy in their policies. Your user with the domain user.example can then say: user.example IN TXT "v=spf1 a include:dummy.your.domain.example -all" This then means that e-mails from any@user.example must come from either the IP addresses of user.example or from one of the 256 IP addresses included in your dummy policy, otherwise it will fail. Similarly, the user.example owner might allow more IPs for other routes, or select ?all for a NEUTRAL result.
But what if your users may have no idea what it's all about, and you want to provide a web form or something similar where the smarter users can set their SPF policies, which will actually be published by you if your services include mail (SMTP) + domain ( DNS).
In this case, the offer simply includes the following by default for all domains you host: dummy.your.domain.example: user.example. IN TXT "v=spf1 include:dummy.your.domain.example ?all" This means that e-mails from any@user.example will receive a SPF-PASS if they are sent through your servers, otherwise they are considered NEUTRAL. So you can offer to change the protection to "otherwise not passed" if a user requests it. You may want to add an "a" to the default value for user.example if this is not covered by dummy.your.domain.example. While you are at it, please also publish identical policies with the new SPF-RR type, as using TXT is more of a problem until all name servers and SPF implementations can handle the new DNS-RR type.
Please note that ?all and -all in a contained record have the same "no match" effect. The inclusion policy therefore requires a separate -all for FAIL protection. However, if the dummy record is also the target of redirections, the difference is important: your.domain.example. IN TXT "v=spf1 a redirect=dummy.your.domain.example".