Add option to disable TLS certificate check in DoT (#644)
authorAndré Cruz <acruz@cloudflare.com>
Thu, 18 Jun 2020 08:54:54 +0000 (09:54 +0100)
committerGitHub <noreply@github.com>
Thu, 18 Jun 2020 08:54:54 +0000 (09:54 +0100)
Signed-off-by: André Cruz <acruz@cloudflare.com>
CONFIGURATION.md
config/config.go
prober/dns.go

index 2d7fe5fb6f13f62a6949ac494f692b4ccbef1c81..dbb852a3ddde34e806070dee857becbbf84e0aaf 100644 (file)
@@ -156,6 +156,10 @@ tls_config:
 # Whether to use DNS over TLS. This only works with TCP.
 [ dns_over_tls: <boolean | default = false> ]
 
+# Configuration for TLS protocol of DNS over TLS probe.
+tls_config:
+  [ <tls_config> ]
+
 query_name: <string>
 
 [ query_type: <string> | default = "ANY" ]
index a13468017ebcddde621296b3a6976ae430f9940a..5309b0ef87f425fc9be1494fc5a2c70e11a737ed 100644 (file)
@@ -172,18 +172,19 @@ type ICMPProbe struct {
 }
 
 type DNSProbe struct {
-       IPProtocol         string         `yaml:"preferred_ip_protocol,omitempty"`
-       IPProtocolFallback bool           `yaml:"ip_protocol_fallback,omitempty"`
-       DNSOverTLS         bool           `yaml:"dns_over_tls,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.
-       ValidateAnswer     DNSRRValidator `yaml:"validate_answer_rrs,omitempty"`
-       ValidateAuthority  DNSRRValidator `yaml:"validate_authority_rrs,omitempty"`
-       ValidateAdditional DNSRRValidator `yaml:"validate_additional_rrs,omitempty"`
+       IPProtocol         string           `yaml:"preferred_ip_protocol,omitempty"`
+       IPProtocolFallback bool             `yaml:"ip_protocol_fallback,omitempty"`
+       DNSOverTLS         bool             `yaml:"dns_over_tls,omitempty"`
+       TLSConfig          config.TLSConfig `yaml:"tls_config,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.
+       ValidateAnswer     DNSRRValidator   `yaml:"validate_answer_rrs,omitempty"`
+       ValidateAuthority  DNSRRValidator   `yaml:"validate_authority_rrs,omitempty"`
+       ValidateAdditional DNSRRValidator   `yaml:"validate_additional_rrs,omitempty"`
 }
 
 type DNSRRValidator struct {
index a69a7812304a35c2f0f39e95499153d281a2caa7..d53c7958466773b890ed9898f025b7692dee3333 100644 (file)
@@ -23,6 +23,7 @@ import (
        "github.com/go-kit/kit/log/level"
        "github.com/miekg/dns"
        "github.com/prometheus/client_golang/prometheus"
+       pconfig "github.com/prometheus/common/config"
 
        "github.com/prometheus/blackbox_exporter/config"
 )
@@ -166,24 +167,24 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
        if module.DNS.TransportProtocol == "" {
                module.DNS.TransportProtocol = "udp"
        }
-       if module.DNS.TransportProtocol == "udp" || module.DNS.TransportProtocol == "tcp" {
-               targetAddr, port, err := net.SplitHostPort(target)
-               if err != nil {
-                       // Target only contains host so fallback to default port and set targetAddr as target.
-                       port = "53"
-                       targetAddr = target
-               }
-               ip, _, err = chooseProtocol(ctx, module.DNS.IPProtocol, module.DNS.IPProtocolFallback, targetAddr, registry, logger)
-               if err != nil {
-                       level.Error(logger).Log("msg", "Error resolving address", "err", err)
-                       return false
-               }
-               target = net.JoinHostPort(ip.String(), port)
-       } else {
+       if !(module.DNS.TransportProtocol == "udp" || module.DNS.TransportProtocol == "tcp") {
                level.Error(logger).Log("msg", "Configuration error: Expected transport protocol udp or tcp", "protocol", module.DNS.TransportProtocol)
                return false
        }
 
+       targetAddr, port, err := net.SplitHostPort(target)
+       if err != nil {
+               // Target only contains host so fallback to default port and set targetAddr as target.
+               port = "53"
+               targetAddr = target
+       }
+       ip, _, err = chooseProtocol(ctx, module.DNS.IPProtocol, module.DNS.IPProtocolFallback, targetAddr, registry, logger)
+       if err != nil {
+               level.Error(logger).Log("msg", "Error resolving address", "err", err)
+               return false
+       }
+       targetIP := net.JoinHostPort(ip.String(), port)
+
        if ip.IP.To4() == nil {
                dialProtocol = module.DNS.TransportProtocol + "6"
        } else {
@@ -202,6 +203,20 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
        client := new(dns.Client)
        client.Net = dialProtocol
 
+       if module.DNS.DNSOverTLS {
+               tlsConfig, err := pconfig.NewTLSConfig(&module.DNS.TLSConfig)
+               if err != nil {
+                       level.Error(logger).Log("msg", "Failed to create TLS configuration", "err", err)
+                       return false
+               }
+               if tlsConfig.ServerName == "" {
+                       // Use target-hostname as default for TLS-servername.
+                       tlsConfig.ServerName = targetAddr
+               }
+
+               client.TLSConfig = tlsConfig
+       }
+
        // Use configured SourceIPAddress.
        if len(module.DNS.SourceIPAddress) > 0 {
                srcIP := net.ParseIP(module.DNS.SourceIPAddress)
@@ -224,10 +239,10 @@ func ProbeDNS(ctx context.Context, target string, module config.Module, registry
        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, "class", qc)
+       level.Info(logger).Log("msg", "Making DNS query", "target", targetIP, "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)
+       response, _, err := client.Exchange(msg, targetIP)
        if err != nil {
                level.Error(logger).Log("msg", "Error while sending a DNS query", "err", err)
                return false