From 69a740714fb7e049a92f7d49449b91a334479472 Mon Sep 17 00:00:00 2001 From: Simon Zolin Date: Fri, 2 Oct 2020 12:51:55 +0300 Subject: [PATCH] * DNS: set default blocking mode to Null IP for A/AAAA, empty response for others Close #1914 Squashed commit of the following: commit cb127a9a409b2f228848fb838535f3db6e9d32a9 Author: Simon Zolin Date: Fri Oct 2 12:37:11 2020 +0300 return empty response if not A/AAAA qtype commit 175a736d7d69619022db92a9250c382ad7fc9996 Author: Simon Zolin Date: Fri Oct 2 12:21:51 2020 +0300 fix commit 03aab89d2da00ede3aad6eb5a5bb2d545444a186 Author: Simon Zolin Date: Fri Oct 2 12:18:11 2020 +0300 fix tests commit 4225d511df910aae2df4651231c01a8a13bb937f Author: Simon Zolin Date: Fri Oct 2 12:02:11 2020 +0300 * DNS: set default blocking mode to Null IP for A/AAAA, NXDOMAIN for others --- client/src/__locales/en.json | 2 +- dnsforward/dnsforward_test.go | 11 +++++++---- dnsforward/handle_dns.go | 3 ++- dnsforward/msg.go | 29 +++++++++++++++++++---------- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/client/src/__locales/en.json b/client/src/__locales/en.json index 26e7df08..678dd39f 100644 --- a/client/src/__locales/en.json +++ b/client/src/__locales/en.json @@ -257,7 +257,7 @@ "rate_limit_desc": "The number of requests per second that a single client is allowed to make (setting it to 0 means unlimited)", "blocking_ipv4_desc": "IP address to be returned for a blocked A request", "blocking_ipv6_desc": "IP address to be returned for a blocked AAAA request", - "blocking_mode_default": "Default: Respond with REFUSED when blocked by Adblock-style rule; respond with the IP address specified in the rule when blocked by /etc/hosts-style rule", + "blocking_mode_default": "Default: Respond with zero IP address (0.0.0.0 for A; :: for AAAA) when blocked by Adblock-style rule; respond with the IP address specified in the rule when blocked by /etc/hosts-style rule", "blocking_mode_refused": "REFUSED: Respond with REFUSED code", "blocking_mode_nxdomain": "NXDOMAIN: Respond with NXDOMAIN code", "blocking_mode_null_ip": "Null IP: Respond with zero IP address (0.0.0.0 for A; :: for AAAA)", diff --git a/dnsforward/dnsforward_test.go b/dnsforward/dnsforward_test.go index 80336055..fbffc5c4 100644 --- a/dnsforward/dnsforward_test.go +++ b/dnsforward/dnsforward_test.go @@ -267,7 +267,7 @@ func TestBlockedRequest(t *testing.T) { addr := s.dnsProxy.Addr(proxy.ProtoUDP) // - // Default blocking - REFUSED + // Default blocking - NULL IP // req := dns.Msg{} req.Id = dns.Id() @@ -280,7 +280,8 @@ func TestBlockedRequest(t *testing.T) { if err != nil { t.Fatalf("Couldn't talk to server %s: %s", addr, err) } - assert.Equal(t, dns.RcodeRefused, reply.Rcode) + assert.Equal(t, dns.RcodeSuccess, reply.Rcode) + assert.True(t, reply.Answer[0].(*dns.A).A.Equal(net.ParseIP("0.0.0.0"))) err = s.Stop() if err != nil { @@ -442,7 +443,8 @@ func TestBlockCNAME(t *testing.T) { req := createTestMessage("badhost.") reply, err := dns.Exchange(req, addr.String()) assert.Nil(t, err, nil) - assert.Equal(t, dns.RcodeRefused, reply.Rcode) + assert.Equal(t, dns.RcodeSuccess, reply.Rcode) + assert.True(t, reply.Answer[0].(*dns.A).A.Equal(net.ParseIP("0.0.0.0"))) // 'whitelist.example.org' has a canonical name 'null.example.org' which is blocked by filters // but 'whitelist.example.org' is in a whitelist: @@ -457,7 +459,8 @@ func TestBlockCNAME(t *testing.T) { req = createTestMessage("example.org.") reply, err = dns.Exchange(req, addr.String()) assert.Nil(t, err) - assert.Equal(t, dns.RcodeRefused, reply.Rcode) + assert.Equal(t, dns.RcodeSuccess, reply.Rcode) + assert.True(t, reply.Answer[0].(*dns.A).A.Equal(net.ParseIP("0.0.0.0"))) _ = s.Stop() } diff --git a/dnsforward/handle_dns.go b/dnsforward/handle_dns.go index f864865b..d770250c 100644 --- a/dnsforward/handle_dns.go +++ b/dnsforward/handle_dns.go @@ -86,9 +86,10 @@ func processInitial(ctx *dnsContext) int { } // disable Mozilla DoH + // https://support.mozilla.org/en-US/kb/canary-domain-use-application-dnsnet if (d.Req.Question[0].Qtype == dns.TypeA || d.Req.Question[0].Qtype == dns.TypeAAAA) && d.Req.Question[0].Name == "use-application-dns.net." { - d.Res = s.makeResponseREFUSED(d.Req) + d.Res = s.genNXDomain(d.Req) return resultFinish } diff --git a/dnsforward/msg.go b/dnsforward/msg.go index fc4ecb51..80997ed6 100644 --- a/dnsforward/msg.go +++ b/dnsforward/msg.go @@ -24,7 +24,10 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu m := d.Req if m.Question[0].Qtype != dns.TypeA && m.Question[0].Qtype != dns.TypeAAAA { - return s.makeResponseREFUSED(m) + if s.conf.BlockingMode == "null_ip" { + return s.makeResponse(m) + } + return s.genNXDomain(m) } switch result.Reason { @@ -42,13 +45,7 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu if s.conf.BlockingMode == "null_ip" { // it means that we should return 0.0.0.0 or :: for any blocked request - - switch m.Question[0].Qtype { - case dns.TypeA: - return s.genARecord(m, []byte{0, 0, 0, 0}) - case dns.TypeAAAA: - return s.genAAAARecord(m, net.IPv6zero) - } + return s.makeResponseNullIP(m) } else if s.conf.BlockingMode == "custom_ip" { // means that we should return custom IP for any blocked request @@ -73,11 +70,12 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu // Default blocking mode // If there's an IP specified in the rule, return it - // If there is no IP, return REFUSED + // For host-type rules, return null IP if result.IP != nil { return s.genResponseWithIP(m, result.IP) } - return s.makeResponseREFUSED(m) + + return s.makeResponseNullIP(m) } } @@ -138,6 +136,17 @@ func (s *Server) genResponseWithIP(req *dns.Msg, ip net.IP) *dns.Msg { return resp } +// Respond with 0.0.0.0 for A, :: for AAAA, empty response for other types +func (s *Server) makeResponseNullIP(req *dns.Msg) *dns.Msg { + if req.Question[0].Qtype == dns.TypeA { + return s.genARecord(req, []byte{0, 0, 0, 0}) + } else if req.Question[0].Qtype == dns.TypeAAAA { + return s.genAAAARecord(req, net.IPv6zero) + } + + return s.makeResponse(req) +} + func (s *Server) genBlockedHost(request *dns.Msg, newAddr string, d *proxy.DNSContext) *dns.Msg { ip := net.ParseIP(newAddr)