From 33ae924e5b2017db18721d85b8f1807693ac126c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Ask=20Bj=C3=B8rn=20Hansen?= Date: Tue, 12 Jun 2018 23:41:52 -0700 Subject: [PATCH] [dns] Add serial number metric for dns soa queries (#333) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Ask Bjørn Hansen --- example.yml | 5 +++++ prober/dns.go | 34 +++++++++++++++++++++++++--------- prober/dns_test.go | 27 +++++++++++++++++++++++---- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/example.yml b/example.yml index 690cb3b..17beee0 100644 --- a/example.yml +++ b/example.yml @@ -111,6 +111,11 @@ modules: validate_additional_rrs: fail_if_matches_regexp: - ".*127.0.0.1" + dns_soa: + prober: dns + dns: + query_name: "prometheus.io" + query_type: "SOA" dns_tcp_example: prober: dns dns: diff --git a/prober/dns.go b/prober/dns.go index 94e276d..d11aa64 100644 --- a/prober/dns.go +++ b/prober/dns.go @@ -107,6 +107,17 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry registry.MustRegister(probeDNSAuthorityRRSGauge) registry.MustRegister(probeDNSAdditionalRRSGauge) + qt := dns.TypeANY + if module.DNS.QueryType != "" { + var ok bool + qt, ok = dns.StringToType[module.DNS.QueryType] + if !ok { + level.Error(logger).Log("msg", "Invalid query type", "Type seen", module.DNS.QueryType, "Existing types", dns.TypeToString) + return false + } + } + var probeDNSSOAGauge prometheus.Gauge + var ip *net.IPAddr if module.DNS.TransportProtocol == "" { module.DNS.TransportProtocol = "udp" @@ -154,15 +165,6 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry } } - qt := dns.TypeANY - if module.DNS.QueryType != "" { - var ok bool - qt, ok = dns.StringToType[module.DNS.QueryType] - if !ok { - level.Error(logger).Log("msg", "Invalid query type", "Type seen", module.DNS.QueryType, "Existing types", dns.TypeToString) - return false - } - } msg := new(dns.Msg) msg.SetQuestion(dns.Fqdn(module.DNS.QueryName), qt) @@ -180,6 +182,20 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry probeDNSAuthorityRRSGauge.Set(float64(len(response.Ns))) probeDNSAdditionalRRSGauge.Set(float64(len(response.Extra))) + if qt == dns.TypeSOA { + probeDNSSOAGauge = prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "probe_dns_serial", + Help: "Returns the serial number of the zone", + }) + registry.MustRegister(probeDNSSOAGauge) + + for _, a := range response.Answer { + if soa, ok := a.(*dns.SOA); ok { + probeDNSSOAGauge.Set(float64(soa.Serial)) + } + } + } + if !validRcode(response.Rcode, module.DNS.ValidRcodes, logger) { return false } diff --git a/prober/dns_test.go b/prober/dns_test.go index e40f431..f0b6f40 100644 --- a/prober/dns_test.go +++ b/prober/dns_test.go @@ -165,11 +165,20 @@ func authoritativeDNSHandler(w dns.ResponseWriter, r *dns.Msg) { m := new(dns.Msg) m.SetReply(r) - a, err := dns.NewRR("example.com. 3600 IN A 127.0.0.1") - if err != nil { - panic(err) + if r.Question[0].Qtype == dns.TypeSOA { + a, err := dns.NewRR("example.com. 3600 IN SOA ns.example.com. noc.example.com. 1000 7200 3600 1209600 3600") + if err != nil { + panic(err) + } + m.Answer = append(m.Answer, a) + + } else { + a, err := dns.NewRR("example.com. 3600 IN A 127.0.0.1") + if err != nil { + panic(err) + } + m.Answer = append(m.Answer, a) } - m.Answer = append(m.Answer, a) authority := []string{ "example.com. 7200 IN NS ns1.isp.net.", @@ -213,6 +222,12 @@ func TestAuthoritativeDNSResponse(t *testing.T) { }, true, }, { + config.DNSProbe{ + PreferredIPProtocol: "ipv4", + QueryName: "example.com", + QueryType: "SOA", + }, true, + }, { config.DNSProbe{ PreferredIPProtocol: "ipv4", QueryName: "example.com", @@ -290,6 +305,10 @@ func TestAuthoritativeDNSResponse(t *testing.T) { "probe_dns_authority_rrs": 2, "probe_dns_additional_rrs": 3, } + if test.Probe.QueryType == "SOA" { + expectedResults["probe_dns_serial"] = 1000 + } + checkRegistryResults(expectedResults, mfs, t) } } -- 2.25.1