Skip to main content

Flatten and Create SPF records in CloudFlare zones

Project description

cfflatten CloudFlare SPF Flattener

This 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.

cfflatten and sender-policy-framework

This project depends on and uses the sender-policy-flattener spflat tool to do the heavy lifting. Not wanting to reinvent the wheel it was easier to use parts from that project here.

spflat is 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.

What cfflatten adds 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 run cfflatten in cron and automatically update your SPF records periodically. (Probably once a week or month is adequate.)

If you are less trusting you can run spflat in cron to monitor changes in your senders; it will send you an email notifying you a record has changed. You can then make the updates by running cfflatten.

Installation

Install using pip, ideally in its own venv

% python3 -m venv cfspf
% source cfspf/bin/activate
% pip install cf-spf-flatten 

This will install

  • cf-spf-flatten as well as
  • sender-policy-flattener
  • python-cloudflare
  • prerequisite libraries for these

The program executable is cfflatten

Anchor SPF record

To use the automated updates you will need to first create the anchor SPF record manually.

This anchor is a TXT record with the name of your domain (here we'll use example.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 of TXT entries created and updated by cfflatten.

cfflatten will never modify the anchor entry itself, only the linked chain.

Our example.com entry will look like this (I generally include mx and and on-prem ip4 SPF 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 by cfflatten. Howevever cfflatten will update the link chain starting with spf0.example.com. spf0 then links to spf1.example.com, etc. until the last required entry - but this is all created and maintained by cfflatten.

Create the configuration file

Here is an example configuration file for example.com, for sending domains of example.com and campaign.example.com. Except for one entry (cf_zone) the JSON file format is identical to the configuration file used by spflat. 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) by cfflatten.

{
    "cf_zone" : "example.com",
    "sending domains": {
        "example.com": {
                "amazonses.com": "txt",
                ... Other senders...
                "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"
}

The cf_zone entry 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.com is such a subdomain, but it is still managed in CloudFlare within the example.com zone.

The "resolvers" list - though required for spflat - can be empty for cfflatten, in which case the default resolver will be used.

CloudFlare Credentials file

If you want to automate the updated records you will also need a .cloudflare.cfg credentials file with the appropriate api keys.

There are a couple of API key formats described in detail in the python-cloudflare documentation. 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 = 0123456789abcdef0123456789abcdef01234

Running cfflatten

% cfflatten -h
usage: cfflatten [-h] [-u] -c CONFIG

Flatten and update Cloudflare SPF records

optional arguments:
  -h, --help            show this help message and exit
  -u, --update          Update the Cloudflare zone SPF records
  -c CONFIG, --config CONFIG
                        Config filename

cfflatten 0.1 copyright 2022 gunville
  • note the config file option is required.
  • using the -u or --update option 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cfflatten-22.2.11.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

cfflatten-22.2.11-py3-none-any.whl (7.0 kB view details)

Uploaded Python 3

File details

Details for the file cfflatten-22.2.11.tar.gz.

File metadata

  • Download URL: cfflatten-22.2.11.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.6.3 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for cfflatten-22.2.11.tar.gz
Algorithm Hash digest
SHA256 80848ce894e3b259e887a6e29cb83e4f41c907040ef2eaf82ca634a216e71499
MD5 dbf2550857963178e005f68d2d01b2df
BLAKE2b-256 930ac06846de6d19ffa0b5c8893cf0c761a72b8f168dd2d9f28ba0fe66f0d379

See more details on using hashes here.

File details

Details for the file cfflatten-22.2.11-py3-none-any.whl.

File metadata

  • Download URL: cfflatten-22.2.11-py3-none-any.whl
  • Upload date:
  • Size: 7.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.6.3 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.0 CPython/3.9.6

File hashes

Hashes for cfflatten-22.2.11-py3-none-any.whl
Algorithm Hash digest
SHA256 6bdf2d5715936dafcd29051327086a2412b751d6bef2423449fb2a6f8221abe6
MD5 e211f08408eb4b175b66e52b525e7f40
BLAKE2b-256 41f9f14db77d00acc97534a4417667164f54206cde1ba4597464e2fe2aa43628

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page