1
0
mirror of https://github.com/StackExchange/dnscontrol.git synced 2024-05-11 05:55:12 +00:00

SPF Optimizer: Enable the use of TXTMulti records to support longer SPF records (#794)

* Add multiple string support to SPF optimizer

Notes:

* This implements [RFC 4408][rfc] for the SPF optimizer. Allowing for
more SPF records to fit within the 10 lookups by using multiple strings.
* By default the max size of the TXT remains at 255. Meaning users will
still only get a single 255 length string unless they modify `txtMaxSize`
and opt into this feature.
* The general recommendation when using multiple strings for TXT records
is to keep the size within a single UDP packet. It seems like the
maximum size for this depends on a bunch of factors that are sometimes
outside of your control. A similar tool has a [formula for estimating the
maximum allowed size][formula]. However I felt giving a user
configurable size would fit with the current configuration style that
dnscontrol has. Similar to how dnscontrol recommends only flattening a
record if absolutely needed, I can see this length being increased by
only enough to get you within 10 lookups.

[rfc]: https://tools.ietf.org/html/rfc4408#section-3.1.3
[formula]: https://github.com/oasys/mkspf/blob/master/Overhead.md

* Add a nice comment for the Chunks function
This commit is contained in:
Michael Russell
2020-07-31 19:28:13 +02:00
committed by GitHub
parent 237c573c2a
commit f21c8fc400
6 changed files with 245 additions and 119 deletions

View File

@@ -58,17 +58,27 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
overhead1 = i
}
// Default txtMaxSize will not result in multiple TXT strings
txtMaxSize := 255
if oh, ok := txt.Metadata["txtMaxSize"]; ok {
i, err := strconv.Atoi(oh)
if err != nil {
errs = append(errs, Warning{fmt.Errorf("split txtMaxSize %q is not an int", oh)})
}
txtMaxSize = i
}
if !strings.Contains(split, "%d") {
errs = append(errs, Warning{fmt.Errorf("Split format `%s` in `%s` is not proper format (should have %%d in it)", split, txt.GetLabelFQDN())})
continue
}
recs := rec.TXTSplit(split+"."+domain.Name, overhead1)
recs := rec.TXTSplit(split+"."+domain.Name, overhead1, txtMaxSize)
for k, v := range recs {
if k == "@" {
txt.SetTargetTXT(v)
txt.SetTargetTXTs(v)
} else {
cp, _ := txt.Copy()
cp.SetTargetTXT(v)
cp.SetTargetTXTs(v)
cp.SetLabelFromFQDN(k, domain.Name)
domain.Records = append(domain.Records, cp)
}