diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 5a8608e0..9949ffe6 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -189,6 +189,9 @@ query_name: [ query_type: | default = "ANY" ] [ query_class: | default = "IN" ] +# Set the recursion desired (RD) flag in the request. +[ recursion: | default = true ] + # List of valid response codes. valid_rcodes: [ - ... | default = "NOERROR" ] diff --git a/config/config.go b/config/config.go index e36b47c9..b71d97ed 100644 --- a/config/config.go +++ b/config/config.go @@ -82,6 +82,7 @@ var ( // DefaultDNSProbe set default value for DNSProbe DefaultDNSProbe = DNSProbe{ IPProtocolFallback: true, + Recursion: true, } ) @@ -264,8 +265,9 @@ type DNSProbe struct { TransportProtocol string `yaml:"transport_protocol,omitempty"` QueryClass string `yaml:"query_class,omitempty"` // Defaults to IN. QueryName string `yaml:"query_name,omitempty"` - QueryType string `yaml:"query_type,omitempty"` // Defaults to ANY. - ValidRcodes []string `yaml:"valid_rcodes,omitempty"` // Defaults to NOERROR. + QueryType string `yaml:"query_type,omitempty"` // Defaults to ANY. + Recursion bool `yaml:"recursion_desired,omitempty"` // Defaults to true. + ValidRcodes []string `yaml:"valid_rcodes,omitempty"` // Defaults to NOERROR. ValidateAnswer DNSRRValidator `yaml:"validate_answer_rrs,omitempty"` ValidateAuthority DNSRRValidator `yaml:"validate_authority_rrs,omitempty"` ValidateAdditional DNSRRValidator `yaml:"validate_additional_rrs,omitempty"` diff --git a/prober/dns.go b/prober/dns.go index d3463e2e..8e8a1b59 100644 --- a/prober/dns.go +++ b/prober/dns.go @@ -250,7 +250,7 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry msg := new(dns.Msg) msg.Id = dns.Id() - msg.RecursionDesired = true + msg.RecursionDesired = module.DNS.Recursion msg.Question = make([]dns.Question, 1) msg.Question[0] = dns.Question{dns.Fqdn(module.DNS.QueryName), qt, qc} diff --git a/prober/dns_test.go b/prober/dns_test.go index 1d313d66..73385ae1 100644 --- a/prober/dns_test.go +++ b/prober/dns_test.go @@ -69,16 +69,20 @@ func startDNSServer(protocol string, handler func(dns.ResponseWriter, *dns.Msg)) func recursiveDNSHandler(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) - answers := []string{ - "example.com. 3600 IN A 127.0.0.1", - "example.com. 3600 IN A 127.0.0.2", - } - for _, rr := range answers { - a, err := dns.NewRR(rr) - if err != nil { - panic(err) + if !r.RecursionDesired { + m.Rcode = dns.RcodeRefused + } else { + answers := []string{ + "example.com. 3600 IN A 127.0.0.1", + "example.com. 3600 IN A 127.0.0.2", + } + for _, rr := range answers { + a, err := dns.NewRR(rr) + if err != nil { + panic(err) + } + m.Answer = append(m.Answer, a) } - m.Answer = append(m.Answer, a) } if err := w.WriteMsg(m); err != nil { panic(err) @@ -99,6 +103,7 @@ func TestRecursiveDNSResponse(t *testing.T) { IPProtocol: "ip4", IPProtocolFallback: true, QueryName: "example.com", + Recursion: true, }, true, }, { @@ -106,6 +111,7 @@ func TestRecursiveDNSResponse(t *testing.T) { IPProtocol: "ip4", IPProtocolFallback: true, QueryName: "example.com", + Recursion: true, ValidRcodes: []string{"SERVFAIL", "NXDOMAIN"}, }, false, }, @@ -114,6 +120,7 @@ func TestRecursiveDNSResponse(t *testing.T) { IPProtocol: "ip4", IPProtocolFallback: true, QueryName: "example.com", + Recursion: true, ValidateAnswer: config.DNSRRValidator{ FailIfMatchesRegexp: []string{".*7200.*"}, FailIfNotMatchesRegexp: []string{".*3600.*"}, @@ -125,6 +132,7 @@ func TestRecursiveDNSResponse(t *testing.T) { IPProtocol: "ip4", IPProtocolFallback: true, QueryName: "example.com", + Recursion: true, ValidateAuthority: config.DNSRRValidator{ FailIfMatchesRegexp: []string{".*7200.*"}, }, @@ -135,11 +143,20 @@ func TestRecursiveDNSResponse(t *testing.T) { IPProtocol: "ip4", IPProtocolFallback: true, QueryName: "example.com", + Recursion: true, ValidateAdditional: config.DNSRRValidator{ FailIfNotMatchesRegexp: []string{".*3600.*"}, }, }, false, }, + { + config.DNSProbe{ + IPProtocol: "ip4", + IPProtocolFallback: true, + QueryName: "example.com", + Recursion: false, + }, false, + }, } for _, protocol := range PROTOCOLS { @@ -166,6 +183,9 @@ func TestRecursiveDNSResponse(t *testing.T) { "probe_dns_authority_rrs": 0, "probe_dns_additional_rrs": 0, } + if !test.Probe.Recursion { + expectedResults["probe_dns_answer_rrs"] = 0 + } checkRegistryResults(expectedResults, mfs, t) } } @@ -474,6 +494,7 @@ func TestDNSProtocol(t *testing.T) { QueryName: "example.com", TransportProtocol: protocol, IPProtocol: "ip6", + Recursion: true, }, } registry := prometheus.NewRegistry() @@ -497,6 +518,7 @@ func TestDNSProtocol(t *testing.T) { Timeout: time.Second, DNS: config.DNSProbe{ QueryName: "example.com", + Recursion: true, TransportProtocol: protocol, IPProtocol: "ip4", }, @@ -523,6 +545,7 @@ func TestDNSProtocol(t *testing.T) { Timeout: time.Second, DNS: config.DNSProbe{ QueryName: "example.com", + Recursion: true, TransportProtocol: protocol, }, } @@ -548,6 +571,7 @@ func TestDNSProtocol(t *testing.T) { Timeout: time.Second, DNS: config.DNSProbe{ QueryName: "example.com", + Recursion: true, }, } registry = prometheus.NewRegistry() @@ -590,6 +614,7 @@ func TestDNSMetrics(t *testing.T) { IPProtocol: "ip4", IPProtocolFallback: true, QueryName: "example.com", + Recursion: true, }, } registry := prometheus.NewRegistry()