mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-09-09 14:46:40 +08:00
SPF Optimizer: Add "redirect:" support (#506)
FYI: The support is very minimal. It only supports redirect if it is the last item in an SPF record. At that point, it is equivalent to include. * In SFP, treat redirect like a special include. * Document SPF redirect: limited implementation.
This commit is contained in:
parent
4a7a5515a0
commit
2d9d93653b
3 changed files with 44 additions and 3 deletions
|
@ -178,6 +178,10 @@ could exceed 512 bytes, and will require EDNS or a TCP request.
|
||||||
3. Dnscontrol does not warn if the number of lookups exceeds 10.
|
3. Dnscontrol does not warn if the number of lookups exceeds 10.
|
||||||
We hope to implement this some day.
|
We hope to implement this some day.
|
||||||
|
|
||||||
|
4. The `redirect:` directive is only partially implemented. We only
|
||||||
|
handle the case where redirect is the last item in the SPF record.
|
||||||
|
In which case, it is equivalent to `include:`.
|
||||||
|
|
||||||
|
|
||||||
## Advanced Technique: Interactive SPF Debugger
|
## Advanced Technique: Interactive SPF Debugger
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
||||||
}
|
}
|
||||||
parts := strings.Split(text, " ")
|
parts := strings.Split(text, " ")
|
||||||
rec := &SPFRecord{}
|
rec := &SPFRecord{}
|
||||||
for _, part := range parts[1:] {
|
for pi, part := range parts[1:] {
|
||||||
if part == "" {
|
if part == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -69,9 +69,18 @@ func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
||||||
} else if strings.HasPrefix(part, "ip4:") || strings.HasPrefix(part, "ip6:") {
|
} else if strings.HasPrefix(part, "ip4:") || strings.HasPrefix(part, "ip6:") {
|
||||||
// ip address, 0 lookups
|
// ip address, 0 lookups
|
||||||
continue
|
continue
|
||||||
} else if strings.HasPrefix(part, "include:") {
|
} else if strings.HasPrefix(part, "include:") || strings.HasPrefix(part, "redirect:") {
|
||||||
|
if strings.HasPrefix(part, "redirect:") {
|
||||||
|
// pi + 2: because pi starts at 0 when it iterates starting on parts[1],
|
||||||
|
// and because len(parts) is one bigger than the highest index.
|
||||||
|
if (pi + 2) != len(parts) {
|
||||||
|
return nil, errors.Errorf("%s must be last item", part)
|
||||||
|
}
|
||||||
|
p.IncludeDomain = strings.TrimPrefix(part, "redirect:")
|
||||||
|
} else {
|
||||||
|
p.IncludeDomain = strings.TrimPrefix(part, "include:")
|
||||||
|
}
|
||||||
p.IsLookup = true
|
p.IsLookup = true
|
||||||
p.IncludeDomain = strings.TrimPrefix(part, "include:")
|
|
||||||
if dnsres != nil {
|
if dnsres != nil {
|
||||||
subRecord, err := dnsres.GetSPF(p.IncludeDomain)
|
subRecord, err := dnsres.GetSPF(p.IncludeDomain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -40,3 +40,31 @@ func TestParseWithDoubleSpaces(t *testing.T) {
|
||||||
}
|
}
|
||||||
t.Log(rec.Print())
|
t.Log(rec.Print())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseRedirectNotLast(t *testing.T) {
|
||||||
|
// Make sure redirect:foo fails if it isn't the last item.
|
||||||
|
dnsres, err := NewCache("testdata-dns1.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, err = Parse(strings.Join([]string{"v=spf1",
|
||||||
|
"redirect:servers.mcsv.net",
|
||||||
|
"~all"}, " "), dnsres)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal("should fail")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseRedirectLast(t *testing.T) {
|
||||||
|
dnsres, err := NewCache("testdata-dns1.json")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
rec, err := Parse(strings.Join([]string{"v=spf1",
|
||||||
|
"ip4:198.252.206.0/24",
|
||||||
|
"redirect:servers.mcsv.net"}, " "), dnsres)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(rec.Print())
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue