dns: add HELO/PTR consistency check
Compare the HELO/EHLO hostname announced by the sending server (first Received hop) against the sender IP's PTR records, surfacing the same signal as x-ptr/policy.ptr in Authentication-Results. Adds helo_hostname and helo_ptr_match to DNSResults, applies a 15-point PTR sub-score penalty on mismatch, and displays the result in a new HELO/PTR Consistency card.
This commit is contained in:
parent
27dcb1b0c3
commit
e168446b44
10 changed files with 460 additions and 0 deletions
|
|
@ -23,6 +23,7 @@ package analyzer
|
|||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
"git.happydns.org/happyDeliver/internal/model"
|
||||
)
|
||||
|
|
@ -62,6 +63,21 @@ func (d *DNSAnalyzer) checkPTRAndForward(ip string) ([]string, []string) {
|
|||
return ptrNames, forwardIPs
|
||||
}
|
||||
|
||||
// checkHeloPtrMatch reports whether the announced HELO hostname matches one of
|
||||
// the sender's PTR records (case-insensitive, trailing dot ignored).
|
||||
func checkHeloPtrMatch(helo string, ptrRecords []string) bool {
|
||||
helo = strings.TrimSuffix(strings.ToLower(strings.TrimSpace(helo)), ".")
|
||||
if helo == "" {
|
||||
return false
|
||||
}
|
||||
for _, ptr := range ptrRecords {
|
||||
if strings.TrimSuffix(strings.ToLower(ptr), ".") == helo {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Proper reverse DNS (PTR) and forward-confirmed reverse DNS (FCrDNS) is important for deliverability
|
||||
func (d *DNSAnalyzer) calculatePTRScore(results *model.DNSResults, senderIP string) (score int) {
|
||||
if results.PtrRecords != nil && len(*results.PtrRecords) > 0 {
|
||||
|
|
@ -73,6 +89,11 @@ func (d *DNSAnalyzer) calculatePTRScore(results *model.DNSResults, senderIP stri
|
|||
score -= 15
|
||||
}
|
||||
|
||||
// Penalty when the announced HELO name doesn't match the PTR hostname
|
||||
if results.HeloPtrMatch != nil && !*results.HeloPtrMatch {
|
||||
score -= 15
|
||||
}
|
||||
|
||||
// Additional 50 points for forward-confirmed reverse DNS (FCrDNS)
|
||||
// This means the PTR hostname resolves back to IPs that include the original sender IP
|
||||
if results.PtrForwardRecords != nil && len(*results.PtrForwardRecords) > 0 && senderIP != "" {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue