From c32f3e3745dfd32758c76509e200e05a9a37301a Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Fri, 11 Jun 2021 13:59:01 +0300 Subject: [PATCH] all: imp fqdn support in ptr dnsrewrite --- dnsengine_test.go | 18 +++++++++--------- dnsrewrite_test.go | 16 +++++++++++++++- rules/dnsrewrite.go | 17 ++++++++++++++--- 3 files changed, 38 insertions(+), 13 deletions(-) diff --git a/dnsengine_test.go b/dnsengine_test.go index 02d7c7e..52f6ade 100644 --- a/dnsengine_test.go +++ b/dnsengine_test.go @@ -313,11 +313,11 @@ func TestClient(t *testing.T) { assertMatchRuleText(t, rulesText[0], res, ok) // not match client IPv4 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host0", ClientIP: "127.0.0.2"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host0", ClientIP: "127.0.0.2"}) assert.False(t, ok) // restricted client IPv4 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host1", ClientIP: "127.0.0.1"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host1", ClientIP: "127.0.0.1"}) assert.False(t, ok) // non-restricted client IPv4 @@ -329,11 +329,11 @@ func TestClient(t *testing.T) { assertMatchRuleText(t, rulesText[2], res, ok) // not match client IPv6 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host2", ClientIP: "2001::c0:ffef"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host2", ClientIP: "2001::c0:ffef"}) assert.False(t, ok) // restricted client IPv6 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host3", ClientIP: "2001::c0:ffee"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host3", ClientIP: "2001::c0:ffee"}) assert.False(t, ok) // non-restricted client IPv6 @@ -345,11 +345,11 @@ func TestClient(t *testing.T) { assertMatchRuleText(t, rulesText[4], res, ok) // not match network IPv4 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host4", ClientIP: "127.0.1.1"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host4", ClientIP: "127.0.1.1"}) assert.False(t, ok) // restricted network IPv4 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host5", ClientIP: "127.0.0.254"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host5", ClientIP: "127.0.0.254"}) assert.False(t, ok) // non-restricted network IPv4 @@ -361,11 +361,11 @@ func TestClient(t *testing.T) { assertMatchRuleText(t, rulesText[6], res, ok) // not match network IPv6 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host6", ClientIP: "2001::c0:feee"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host6", ClientIP: "2001::c0:feee"}) assert.False(t, ok) // restricted network IPv6 - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host7", ClientIP: "2001::c0:ff07"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host7", ClientIP: "2001::c0:ff07"}) assert.False(t, ok) // non-restricted network IPv6 @@ -377,7 +377,7 @@ func TestClient(t *testing.T) { assertMatchRuleText(t, rulesText[8], res, ok) // not match client name - res, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host8", ClientName: "Franks laptop"}) + _, ok = dnsEngine.MatchRequest(DNSRequest{Hostname: "host8", ClientName: "Franks laptop"}) assert.False(t, ok) } diff --git a/dnsrewrite_test.go b/dnsrewrite_test.go index 622cf2d..353a92d 100644 --- a/dnsrewrite_test.go +++ b/dnsrewrite_test.go @@ -212,6 +212,7 @@ func TestDNSEngine_MatchRequest_dnsRewrite(t *testing.T) { |new-mx^$dnsrewrite=NOERROR;MX;32 new-mx-host |new-txt^$dnsrewrite=NOERROR;TXT;new-txtcontent |1.2.3.4.in-addr.arpa^$dnsrewrite=NOERROR;PTR;new-ptr +|1.2.3.5.in-addr.arpa^$dnsrewrite=NOERROR;PTR;new-ptr-with-dot. |https-record^$dnsrewrite=NOERROR;HTTPS;32 https-record-host alpn=h3 |svcb-record^$dnsrewrite=NOERROR;SVCB;32 svcb-record-host alpn=h3 @@ -437,7 +438,20 @@ func TestDNSEngine_MatchRequest_dnsRewrite(t *testing.T) { nr := dnsr[0] assert.Equal(t, dns.RcodeSuccess, nr.DNSRewrite.RCode) assert.Equal(t, dns.TypePTR, nr.DNSRewrite.RRType) - assert.Equal(t, "new-ptr", nr.DNSRewrite.Value) + assert.Equal(t, "new-ptr.", nr.DNSRewrite.Value) + }) + + t.Run("1.2.3.5.in-addr.arpa", func(t *testing.T) { + res, ok := dnsEngine.Match(path.Base(t.Name())) + assert.False(t, ok) + + dnsr := res.DNSRewritesAll() + require.Len(t, dnsr, 1) + + nr := dnsr[0] + assert.Equal(t, dns.RcodeSuccess, nr.DNSRewrite.RCode) + assert.Equal(t, dns.TypePTR, nr.DNSRewrite.RRType) + assert.Equal(t, "new-ptr-with-dot.", nr.DNSRewrite.Value) }) t.Run("https-record", func(t *testing.T) { diff --git a/rules/dnsrewrite.go b/rules/dnsrewrite.go index be573b2..300db58 100644 --- a/rules/dnsrewrite.go +++ b/rules/dnsrewrite.go @@ -24,8 +24,10 @@ type RRType = uint16 // // If the RRType is dns.TypeMX, the underlying value is a non-nil *DNSMX. // -// If the RRType is either dns.TypePTR or dns.TypeTXT, the underlying type of -// Value is string. +// If the RRType is either dns.TypePTR the underlying type of Value is string, +// and it is a valid FQDN. +// +// If the RRType is either dns.TypeTXT, the underlying type of Value is string. // // If the RRType is either dns.TypeHTTPS or dns.TypeSVCB, the underlying value // is a non-nil *DNSSVCB. @@ -212,6 +214,15 @@ func cnameDNSRewriteRRHandler(_ RCode, _ RRType, valStr string) (dnsr *DNSRewrit // ptrDNSRewriteRRHandler is a DNS rewrite handler that parses PTR rewrites. func ptrDNSRewriteRRHandler(rcode RCode, rr RRType, valStr string) (dnsr *DNSRewrite, err error) { + // Accept both vanilla domain names and FQDNs. + var fqdn string + if l := len(valStr); l > 0 && valStr[l-1] == '.' { + fqdn = valStr + valStr = valStr[:l-1] + } else { + fqdn = dns.Fqdn(valStr) + } + err = validateHost(valStr) if err != nil { return nil, fmt.Errorf("invalid ptr host: %w", err) @@ -220,7 +231,7 @@ func ptrDNSRewriteRRHandler(rcode RCode, rr RRType, valStr string) (dnsr *DNSRew return &DNSRewrite{ RCode: rcode, RRType: rr, - Value: valStr, + Value: fqdn, }, nil }