Package: cfflatten
cfflatten CloudFlare SPF FlattenerThis project implements Sender Policy Framework (SPF) record flattening for CloudFlare managed DNS zones.  This includes creating and updating these records.If you are looking for an SPF flattening tool you already know what SPF flattening is. If you don't, you probably don't need one yet. It's goal is to minimize the DNS lookups (to under 10) for a mailer to gather all approved senders.cfflattenandsender-policy-frameworkThis project depends on and uses thesender-policy-flattenerspflattool to do the heavy lifting. Not wanting to reinvent the wheel it was easier to use parts from that project here.spflatis a great tool to track and monitor SPF record changes. To that end we also use the same configuration file format, expecting you will probably use both.Whatcfflattenadds is the ability to generate the SPF records without the email, and to (optionally) automatically update these records in CloudFlare managed DNS zones. (As the question may come up, I plan on adding Route-53 support as well.)If you are a trusting person, you can runcfflattenincronand automatically update your SPF records periodically. (Probably once a week or month is adequate.)If you are less trusting you can runspflatincronto monitor changes in your senders; it will send you an email notifying you a record has changed.  You can then make the updates by runningcfflatten.InstallationInstall usingpip, ideally in its ownvenv%python3-mvenvcfspf
%sourcecfspf/bin/activate
%pipinstallcf-spf-flattenThis will installcf-spf-flattenas well assender-policy-flattenerpython-cloudflareprerequisite libraries for theseThe program executable iscfflattenAnchor SPF recordTo use the automated updates you will need to first create the anchor SPF record manually.This anchor is aTXTrecord with the name of your domain (here we'll useexample.com). This is what you normally would do for any SPF record.At the end of the anchor entry add an"include:spf0.example.com -all"to link to the chain ofTXTentries created and updated bycfflatten.cfflattenwill never modify the anchor entry itself, only the linked chain.Ourexample.comentry will look like this (I generally includemxand and on-premip4SPF entries in the anchor.):"v=spf1 mx ip4:130.223.20.181 ... ip4:100.10.20.11 include:spf0.example.com -all"As mentioned, the anchor record remains the same and is not updated bycfflatten.  Howevevercfflattenwill update the link chain starting withspf0.example.com.spf0then links tospf1.example.com, etc. until the last required entry - but this is all created and maintained bycfflatten.Create the configuration fileHere is an example configuration file forexample.com, for sending domains ofexample.comandcampaign.example.com.
Except for one entry (cf_zone) the JSON file format is identical to the configuration file used byspflat. Hence I'll refer you to that [documentatation] for details on the fields.Actually only"cf_zone","sending domains"and"resolvers"are used by"cfflatten".The"email"and"output"stanzas are ignored (neither required or used) bycfflatten.{"cf_zone":"example.com","sending domains":{"example.com":{"amazonses.com":"txt",...Othersenders..."spf.protection.outlook.com":"txt"},"campaign.example.com"{"amazonses.com":"txt"}},"resolvers":["1.1.1.1","1.0.0.1"],"email":{"to":"dnsadmins@example.com","from":"SPF-checker@example.com","subject":"[Change Detected] SPF Records for {zone} have changed.","server":"mail.example.com"},"output":"example_com-status.json"}Thecf_zoneentry is the name of the actual CloudFlare registered zone. It is included because you may be using subdomains to send mail. In this example,campaign.example.comis such a subdomain, but it is still managed in CloudFlare within theexample.comzone.The"resolvers"list - though required forspflat- can be empty forcfflatten, in which case the default resolver will be used.CloudFlare Credentials fileIf you want to automate the updated records you will also need a.cloudflare.cfgcredentials file with the appropriate api keys.There are a couple of API key formats described in detail in thepython-cloudflaredocumentation. Check there for details on format, location, environmental variables, etc.  We'll use a simple example here of one format:[CloudFlare]
email = dnsadmins@example.com
token = 0123456789abcdef0123456789abcdef01234Runningcfflatten%cfflatten-h
usage:cfflatten[-h][-u]-cCONFIG

FlattenandupdateCloudflareSPFrecords

optionalarguments:-h,--helpshowthishelpmessageandexit-u,--updateUpdatetheCloudflarezoneSPFrecords-cCONFIG,--configCONFIGConfigfilename

cfflatten0.1copyright2022gunvillenote the config file option isrequired.using the-uor--updateoption will actually attempt to update the SPF records.  You will want to run this first without update mode to get an idea of what changes will be made.