From 8b75b49c6e8cfe905d01ae31ab5db9ad30bcf8b5 Mon Sep 17 00:00:00 2001 From: Brian Brazil Date: Thu, 21 Sep 2017 14:15:48 +0100 Subject: [PATCH] Set TLS servername from target's host for HTTP probe. (#235) --- prober/http.go | 10 +++++--- prober/http_test.go | 57 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/prober/http.go b/prober/http.go index dcd81e0..afde979 100644 --- a/prober/http.go +++ b/prober/http.go @@ -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 diff --git a/prober/http_test.go b/prober/http_test.go index ad86f18..3d9bd76 100644 --- a/prober/http_test.go +++ b/prober/http_test.go @@ -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") + } +} -- 2.25.1