Set TLS servername from target's host for HTTP probe. (#235)
authorBrian Brazil <brian.brazil@robustperception.io>
Thu, 21 Sep 2017 13:15:48 +0000 (14:15 +0100)
committerGitHub <noreply@github.com>
Thu, 21 Sep 2017 13:15:48 +0000 (14:15 +0100)
prober/http.go
prober/http_test.go

index dcd81e0f7354db7a51f1233fae5a6e7e68965bfb..afde9794cc0d3b90cb87dca70d2dd5ffc87dae99 100644 (file)
@@ -134,9 +134,13 @@ func ProbeHTTP(ctx context.Context, target string, module config.Module, registr
                return false
        }
 
-       httpClientConfig := &module.HTTP.HTTPClientConfig
-
-       client, err := pconfig.NewHTTPClientFromConfig(httpClientConfig)
+       httpClientConfig := module.HTTP.HTTPClientConfig
+       if len(httpClientConfig.TLSConfig.ServerName) == 0 {
+               // If there is no `server_name` in tls_config, use
+               // the hostname of the target.
+               httpClientConfig.TLSConfig.ServerName = targetHost
+       }
+       client, err := pconfig.NewHTTPClientFromConfig(&httpClientConfig)
        if err != nil {
                level.Error(logger).Log("msg", "Error generating HTTP client", "err", err)
                return false
index ad86f1871eea1a826996770df598e2315452742d..3d9bd76ac31160fbeae3375813d08295e48f3ecb 100644 (file)
@@ -15,9 +15,12 @@ package prober
 
 import (
        "context"
+       "crypto/tls"
        "fmt"
+       "io/ioutil"
        "net/http"
        "net/http/httptest"
+       "os"
        "strings"
        "testing"
        "time"
@@ -486,3 +489,57 @@ func TestTLSConfigIsIgnoredForPlainHTTP(t *testing.T) {
        }
        checkRegistryResults(expectedResults, mfs, t)
 }
+
+func TestHTTPUsesTargetAsTLSServerName(t *testing.T) {
+       // Create test certificates valid for 1 day.
+       certExpiry := time.Now().AddDate(0, 0, 1)
+       testcert_pem, testkey_pem := generateTestCertificate(certExpiry, false)
+
+       // CAFile must be passed via filesystem, use a tempfile.
+       tmpCaFile, err := ioutil.TempFile("", "cafile.pem")
+       if err != nil {
+               t.Fatalf("Error creating CA tempfile: %s", err)
+       }
+       if _, err := tmpCaFile.Write(testcert_pem); err != nil {
+               t.Fatalf("Error writing CA tempfile: %s", err)
+       }
+       if err := tmpCaFile.Close(); err != nil {
+               t.Fatalf("Error closing CA tempfile: %s", err)
+       }
+       defer os.Remove(tmpCaFile.Name())
+
+       testcert, err := tls.X509KeyPair(testcert_pem, testkey_pem)
+       if err != nil {
+               panic(fmt.Sprintf("Failed to decode TLS testing keypair: %s\n", err))
+       }
+
+       ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+       }))
+       ts.TLS = &tls.Config{
+               Certificates: []tls.Certificate{testcert},
+       }
+       ts.StartTLS()
+       defer ts.Close()
+
+       registry := prometheus.NewRegistry()
+       module := config.Module{
+               Timeout: time.Second,
+               HTTP: config.HTTPProbe{
+                       PreferredIPProtocol: "ip4",
+                       HTTPClientConfig: pconfig.HTTPClientConfig{
+                               TLSConfig: pconfig.TLSConfig{
+                                       CAFile: tmpCaFile.Name(),
+                               },
+                       },
+               },
+       }
+
+       // Replace IP address with hostname.
+       url := strings.Replace(ts.URL, "127.0.0.1", "localhost", -1)
+       url = strings.Replace(url, "[::1]", "localhost", -1)
+
+       result := ProbeHTTP(context.Background(), url, module, registry, log.NewNopLogger())
+       if !result {
+               t.Fatalf("TLS probe failed unexpectedly")
+       }
+}