query_name: <string>
[ query_type: <string> | default = "ANY" ]
+[ query_class: <string> | default = "IN" ]
# List of valid response codes.
valid_rcodes:
yaml "gopkg.in/yaml.v3"
+ "github.com/miekg/dns"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/common/config"
)
IPProtocolFallback bool `yaml:"ip_protocol_fallback,omitempty"`
SourceIPAddress string `yaml:"source_ip_address,omitempty"`
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.
if s.QueryName == "" {
return errors.New("query name must be set for DNS module")
}
+ if s.QueryClass != "" {
+ if _, ok := dns.StringToClass[s.QueryClass]; !ok {
+ return fmt.Errorf("query class '%s' is not valid", s.QueryClass)
+ }
+ }
+ if s.QueryType != "" {
+ if _, ok := dns.StringToType[s.QueryType]; !ok {
+ return fmt.Errorf("query type '%s' is not valid", s.QueryType)
+ }
+ }
+
return nil
}
ConfigFile: "testdata/invalid-dns-module.yml",
ExpectedError: "error parsing config file: query name must be set for DNS module",
},
+ {
+ ConfigFile: "testdata/invalid-dns-class.yml",
+ ExpectedError: "error parsing config file: query class 'X' is not valid",
+ },
+ {
+ ConfigFile: "testdata/invalid-dns-type.yml",
+ ExpectedError: "error parsing config file: query type 'X' is not valid",
+ },
{
ConfigFile: "testdata/invalid-http-header-match.yml",
ExpectedError: "error parsing config file: regexp must be set for HTTP header matchers",
--- /dev/null
+modules:
+ dns_test:
+ prober: dns
+ timeout: 5s
+ dns:
+ query_name: example.com
+ query_class: X
+ query_type: A
--- /dev/null
+modules:
+ dns_test:
+ prober: dns
+ timeout: 5s
+ dns:
+ query_name: example.com
+ query_class: CH
+ query_type: X
registry.MustRegister(probeDNSAuthorityRRSGauge)
registry.MustRegister(probeDNSAdditionalRRSGauge)
+ qc := uint16(dns.ClassINET)
+ if module.DNS.QueryClass != "" {
+ var ok bool
+ qc, ok = dns.StringToClass[module.DNS.QueryClass]
+ if !ok {
+ level.Error(logger).Log("msg", "Invalid query class", "Class seen", module.DNS.QueryClass, "Existing classes", dns.ClassToString)
+ return false
+ }
+ }
+
qt := dns.TypeANY
if module.DNS.QueryType != "" {
var ok bool
}
msg := new(dns.Msg)
- msg.SetQuestion(dns.Fqdn(module.DNS.QueryName), qt)
+ msg.Id = dns.Id()
+ msg.RecursionDesired = true
+ msg.Question = make([]dns.Question, 1)
+ msg.Question[0] = dns.Question{dns.Fqdn(module.DNS.QueryName), qt, qc}
- level.Info(logger).Log("msg", "Making DNS query", "target", target, "dial_protocol", dialProtocol, "query", module.DNS.QueryName, "type", qt)
+ level.Info(logger).Log("msg", "Making DNS query", "target", target, "dial_protocol", dialProtocol, "query", module.DNS.QueryName, "type", qt, "class", qc)
timeoutDeadline, _ := ctx.Deadline()
client.Timeout = time.Until(timeoutDeadline)
response, _, err := client.Exchange(msg, target)
panic(err)
}
m.Answer = append(m.Answer, a)
-
+ } else if r.Question[0].Qclass == dns.ClassCHAOS && r.Question[0].Qtype == dns.TypeTXT {
+ txt, err := dns.NewRR("example.com. 3600 CH TXT \"goCHAOS\"")
+ if err != nil {
+ panic(err)
+ }
+ m.Answer = append(m.Answer, txt)
} else {
a, err := dns.NewRR("example.com. 3600 IN A 127.0.0.1")
if err != nil {
QueryName: "example.com",
QueryType: "SOA",
}, true,
- }, {
+ },
+ {
+ config.DNSProbe{
+ IPProtocol: "ip4",
+ IPProtocolFallback: true,
+ QueryClass: "CH",
+ QueryName: "example.com",
+ QueryType: "TXT",
+ ValidateAnswer: config.DNSRRValidator{
+ FailIfMatchesRegexp: []string{".*IN.*"},
+ FailIfNotMatchesRegexp: []string{".*CH.*"},
+ },
+ }, true,
+ },
+ {
config.DNSProbe{
IPProtocol: "ip4",
IPProtocolFallback: true,