From dcc66161743315466f999f3299b0d304bb73ead8 Mon Sep 17 00:00:00 2001 From: Roman Iuvshyn Date: Fri, 17 Apr 2020 11:01:58 +0300 Subject: [PATCH] Add use_proxy_dns to bypass local DNS resolution Changes picked up from original PR https://github.com/prometheus/blackbox_exporter/pull/554 which was rejected by maintainer. --- CONFIGURATION.md | 3 +++ config/config.go | 1 + prober/http.go | 42 +++++++++++++++++++++++++++--------------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CONFIGURATION.md b/CONFIGURATION.md index 7610bd4c..8cde55be 100644 --- a/CONFIGURATION.md +++ b/CONFIGURATION.md @@ -92,6 +92,9 @@ The other placeholders are specified separately. # HTTP proxy server to use to connect to the targets. [ proxy_url: ] + # Skip local DNS resolution when using an HTTP proxy server. + [ use_proxy_dns: | default = false ] + # The IP protocol of the HTTP probe (ip4, ip6). [ preferred_ip_protocol: | default = "ip6" ] [ ip_protocol_fallback: | default = true ] diff --git a/config/config.go b/config/config.go index 3f3daead..e15565d4 100644 --- a/config/config.go +++ b/config/config.go @@ -138,6 +138,7 @@ type HTTPProbe struct { FailIfHeaderMatchesRegexp []HeaderMatch `yaml:"fail_if_header_matches,omitempty"` FailIfHeaderNotMatchesRegexp []HeaderMatch `yaml:"fail_if_header_not_matches,omitempty"` Body string `yaml:"body,omitempty"` + UseProxyDNS bool `yaml:"use_proxy_dns,omitempty"` HTTPClientConfig config.HTTPClientConfig `yaml:"http_client_config,inline"` } diff --git a/prober/http.go b/prober/http.go index f4abdbe1..82381efc 100644 --- a/prober/http.go +++ b/prober/http.go @@ -285,7 +285,13 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr }) ) - for _, lv := range []string{"resolve", "connect", "tls", "processing", "transfer"} { + // Check the option to send the url unresolved to the proxy + skipDNS := module.HTTP.UseProxyDNS && module.HTTP.HTTPClientConfig.ProxyURL.URL != nil + + if !skipDNS { + durationGaugeVec.WithLabelValues("resolve") + } + for _, lv := range []string{"connect", "tls", "processing", "transfer"} { durationGaugeVec.WithLabelValues(lv) } @@ -315,12 +321,17 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr targetHost = targetURL.Host } - ip, lookupTime, err := chooseProtocol(ctx, module.HTTP.IPProtocol, module.HTTP.IPProtocolFallback, targetHost, registry, logger) - if err != nil { - level.Error(logger).Log("msg", "Error resolving address", "err", err) - return false + // Resolve the host unless letting the proxy do the job. + var ip *net.IPAddr + if !skipDNS { + var lookupTime float64 + ip, lookupTime, err = chooseProtocol(ctx, module.HTTP.IPProtocol, module.HTTP.IPProtocolFallback, targetHost, registry, logger) + if err != nil { + level.Error(logger).Log("msg", "Error resolving address", "err", err) + return false + } + durationGaugeVec.WithLabelValues("resolve").Add(lookupTime) } - durationGaugeVec.WithLabelValues("resolve").Add(lookupTime) httpClientConfig := module.HTTP.HTTPClientConfig if len(httpClientConfig.TLSConfig.ServerName) == 0 { @@ -367,18 +378,19 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr httpConfig.Method = "GET" } - // Replace the host field in the URL with the IP we resolved. + // Replace the host field in the URL with the IP we resolved unless letting a proxy server do the name resolution. origHost := targetURL.Host - if targetPort == "" { - if strings.Contains(ip.String(), ":") { - targetURL.Host = "[" + ip.String() + "]" + if !skipDNS { + if targetPort == "" { + if strings.Contains(ip.String(), ":") { + targetURL.Host = "[" + ip.String() + "]" + } else { + targetURL.Host = ip.String() + } } else { - targetURL.Host = ip.String() + targetURL.Host = net.JoinHostPort(ip.String(), targetPort) } - } else { - targetURL.Host = net.JoinHostPort(ip.String(), targetPort) } - var body io.Reader var respBodyBytes int64 @@ -515,7 +527,7 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr "end", trace.end, ) // We get the duration for the first request from chooseProtocol. - if i != 0 { + if i != 0 && !skipDNS { durationGaugeVec.WithLabelValues("resolve").Add(trace.dnsDone.Sub(trace.start).Seconds()) } // Continue here if we never got a connection because a request failed.