From 07ffcbec3dfb58f0df22b9c842231135653fa4a3 Mon Sep 17 00:00:00 2001 From: Alexander Turcic Date: Sat, 4 May 2019 22:51:14 +0200 Subject: [PATCH 1/2] * dnsforward, config: add unspecified IP blocking option * dnsforward: prioritize host files over null filter * dnsforward, config: adjust setting variable to blocking_mode * dnsforward: use net.IPv4zero for null IP --- config.go | 1 + dnsforward/dnsforward.go | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/config.go b/config.go index dcee1d39..24ee8605 100644 --- a/config.go +++ b/config.go @@ -115,6 +115,7 @@ var config = configuration{ FilteringConfig: dnsforward.FilteringConfig{ ProtectionEnabled: true, // whether or not use any of dnsfilter features FilteringEnabled: true, // whether or not use filter lists + BlockingMode: "nxdomain", // mode how to answer filtered requests BlockedResponseTTL: 10, // in seconds QueryLogEnabled: true, Ratelimit: 20, diff --git a/dnsforward/dnsforward.go b/dnsforward/dnsforward.go index 224f4b28..bd6cf75a 100644 --- a/dnsforward/dnsforward.go +++ b/dnsforward/dnsforward.go @@ -61,6 +61,7 @@ func NewServer(baseDir string) *Server { type FilteringConfig struct { ProtectionEnabled bool `yaml:"protection_enabled"` // whether or not use any of dnsfilter features FilteringEnabled bool `yaml:"filtering_enabled"` // whether or not use filter lists + BlockingMode string `yaml:"blocking_mode"` // mode how to answer filtered requests BlockedResponseTTL uint32 `yaml:"blocked_response_ttl"` // if 0, then default is used (3600) QueryLogEnabled bool `yaml:"querylog_enabled"` // if true, query log is enabled Ratelimit int `yaml:"ratelimit"` // max number of requests per second from a given IP (0 to disable) @@ -401,6 +402,10 @@ func (s *Server) genDNSFilterMessage(d *proxy.DNSContext, result *dnsfilter.Resu return s.genARecord(m, result.IP) } + if s.BlockingMode == "null_ip" { + return s.genARecord(m, net.IPv4zero) + } + return s.genNXDomain(m) } } From cd2dd00da300c24a88a51082ee9622a332a5b72b Mon Sep 17 00:00:00 2001 From: Alexander Turcic Date: Tue, 14 May 2019 14:53:31 +0200 Subject: [PATCH 2/2] * dnsforward_test: add test for null filter --- dnsforward/dnsforward_test.go | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/dnsforward/dnsforward_test.go b/dnsforward/dnsforward_test.go index b568d4e0..0c1325c7 100644 --- a/dnsforward/dnsforward_test.go +++ b/dnsforward/dnsforward_test.go @@ -293,6 +293,55 @@ func TestBlockedRequest(t *testing.T) { } } +func TestNullBlockedRequest(t *testing.T) { + s := createTestServer(t) + s.FilteringConfig.BlockingMode = "null_ip" + defer removeDataDir(t) + err := s.Start(nil) + if err != nil { + t.Fatalf("Failed to start server: %s", err) + } + addr := s.dnsProxy.Addr(proxy.ProtoUDP) + + // + // Null filter blocking + // + req := dns.Msg{} + req.Id = dns.Id() + req.RecursionDesired = true + req.Question = []dns.Question{ + {Name: "null.example.org.", Qtype: dns.TypeA, Qclass: dns.ClassINET}, + } + + reply, err := dns.Exchange(&req, addr.String()) + if err != nil { + t.Fatalf("Couldn't talk to server %s: %s", addr, err) + } + if len(reply.Answer) != 1 { + t.Fatalf("DNS server %s returned reply with wrong number of answers - %d", addr, len(reply.Answer)) + } + if a, ok := reply.Answer[0].(*dns.A); ok { + if !net.IPv4zero.Equal(a.A) { + t.Fatalf("DNS server %s returned wrong answer instead of 0.0.0.0: %v", addr, a.A) + } + } else { + t.Fatalf("DNS server %s returned wrong answer type instead of A: %v", addr, reply.Answer[0]) + } + + // check query log and stats + log := s.GetQueryLog() + assert.Equal(t, 1, len(log), "Log size") + stats := s.GetStatsTop() + assert.Equal(t, 1, len(stats.Domains), "Top domains length") + assert.Equal(t, 1, len(stats.Blocked), "Top blocked length") + assert.Equal(t, 1, len(stats.Clients), "Top clients length") + + err = s.Stop() + if err != nil { + t.Fatalf("DNS server failed to stop: %s", err) + } +} + func TestBlockedByHosts(t *testing.T) { s := createTestServer(t) defer removeDataDir(t) @@ -413,6 +462,7 @@ func createTestServer(t *testing.T) *Server { rules := []string{ "||nxdomain.example.org^", + "||null.example.org^", "127.0.0.1 host.example.org", } filter := dnsfilter.Filter{ID: 1, Rules: rules}