noclocks / dns

DNS Records Managed via dnscontrol
https://docs.noclocks.dev/dns/
The Unlicense
3 stars 1 forks source link

[Feature]: Add/Update/Fix Sender Policy Framework (`SPF`) `TXT` DNS Record #66

Open jimbrig opened 3 months ago

jimbrig commented 3 months ago

Need to make our SPF record compliant and correct.

Root SPF TXT DNS Record

[!NOTE] The SPF RFC says that SPF settings should not require more than 10 DNS lookups. If we manually flatten (i.e. "inline") an include, we have to remember to check back to see if the settings have changed. Humans are not good at that kind of thing.

[!WARNING] Can only have one single SPF DNS TXT record per domain/sub-domain.

The SPF record can be build via dnscontrol's native SPF_BUILDER:

Example Usage:

D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
  ...
  ...
  ...
  SPF_BUILDER({
    label: "@",
    overflow: "_spf%d",  // Delete this line if you don't want big strings split.
    overhead1: "20",  // There are 20 bytes of other TXT records on this domain.  Compensate for this.
    raw: "_rawspf",  // Delete this line if the default is sufficient.
    parts: [
      "v=spf1",
      // fill in your SPF items here
      "~all"
    ],
    flatten: [
      // fill in any domains to inline.
    ]
  }),
  ...
  ...
END);

For our use-case, we send email from google, resend (amazonses), and stripe (currently):

var SPIF_RECORD = SPF_BUILDER({
  label: "@",
  parts: [
    "v=spf1",
    "include:_spf.google.com", // GSuite
    "include:amazonses.com", // Amazon SES (Resend)
    "include:stripe.com", // Stripe
    "~all"
  ],
  flatten: [
    "amazonses.com",
    "stripe.com"
  ]
});

or simply,

, TXT("@", "v=spf1 include:_spf.google.com ~all")

[!NOTE] DNSControl can optimize the SPF settings on a domain by flattening (inlining) includes and removing duplicates. DNSControl also makes it easier to document your SPF configuration.

[!WARNING] Flattening SPF includes is risky. Only flatten an SPF setting if it is absolutely needed to bring the number of "lookups" to be less than 10. In fact, it is debatable whether or not ISPs enforce the "10 lookup rule".

For No Clocks, we initially used three "includes" domains in our SPF record:

"v=spf1 include:_spf.google.com amazonses.com stripe.com ~all"

however, this resulted in more than the maximum allowed 10 individual IPs across those three domains.

Therefore, we should only implement the primary _spf.google.com include:

"v=spf1 include:_spf.google.com ~all"
// TXT Records - SPF
, TXT("@", "v=spf1 include:_spf.google.com ~all")
, TXT("send", "v=spf1 include:amazonses.com ~all")