From 2894df6135bda15a8067c85645c7f70e8b1040db Mon Sep 17 00:00:00 2001 From: Lyas Spiehler Date: Wed, 1 Feb 2023 07:35:13 -0600 Subject: [PATCH] Add hostname parameter for TCP probe (#981) This adds the ability to set the TLS server name for TCP probes using the hostname parameter, just like #823 did for HTTP probes * add hostname parameter for tcp probe * only add servername if TLS is true * add even if TLS isn't true in case of STARTTLS * added test hostname parameter with TCP probe * remove unnecessary function and inline assignment --------- Signed-off-by: Lyas Spiehler Co-authored-by: Lyas Spiehler --- prober/handler.go | 6 +++++ prober/handler_test.go | 54 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/prober/handler.go b/prober/handler.go index f449cac..2a8a1d9 100644 --- a/prober/handler.go +++ b/prober/handler.go @@ -107,6 +107,12 @@ func Handler(w http.ResponseWriter, r *http.Request, c *config.Config, logger lo } } + if module.Prober == "tcp" && hostname != "" { + if module.TCP.TLSConfig.ServerName == "" { + module.TCP.TLSConfig.ServerName = hostname + } + } + sl := newScrapeLogger(logger, moduleName, target) level.Info(sl).Log("msg", "Beginning probe", "probe", module.Prober, "timeout_seconds", timeoutSeconds) diff --git a/prober/handler_test.go b/prober/handler_test.go index a144fb9..40039d4 100644 --- a/prober/handler_test.go +++ b/prober/handler_test.go @@ -16,8 +16,10 @@ package prober import ( "bytes" "fmt" + "net" "net/http" "net/http/httptest" + "strconv" "strings" "testing" "time" @@ -203,3 +205,55 @@ func TestHostnameParam(t *testing.T) { t.Errorf("probe request handler returned wrong status code: %v, want %v", status, http.StatusBadRequest) } } + +func TestTCPHostnameParam(t *testing.T) { + c := &config.Config{ + Modules: map[string]config.Module{ + "tls_connect": { + Prober: "tcp", + Timeout: 10 * time.Second, + TCP: config.TCPProbe{ + TLS: true, + IPProtocol: "ip4", + TLSConfig: pconfig.TLSConfig{InsecureSkipVerify: true}, + }, + }, + }, + } + + // check that 'hostname' parameter make its way to server_name in the tls_config + hostname := "foo.example.com" + + ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Host != hostname { + t.Errorf("Unexpected Host: expected %q, got %q.", hostname, r.Host) + } + w.WriteHeader(http.StatusOK) + })) + defer ts.Close() + + requrl := fmt.Sprintf("?module=tls_connect&debug=true&hostname=%s&target=%s", hostname, ts.Listener.Addr().(*net.TCPAddr).IP.String()+":"+strconv.Itoa(ts.Listener.Addr().(*net.TCPAddr).Port)) + + req, err := http.NewRequest("GET", requrl, nil) + if err != nil { + t.Fatal(err) + } + + rr := httptest.NewRecorder() + + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + Handler(w, r, c, log.NewNopLogger(), &ResultHistory{}, 0.5, nil) + }) + + handler.ServeHTTP(rr, req) + + if status := rr.Code; status != http.StatusOK { + t.Errorf("probe request handler returned wrong status code: %v, want %v", status, http.StatusOK) + } + + // check debug output to confirm the server_name is set in tls_config and matches supplied hostname + if !strings.Contains(rr.Body.String(), "server_name: "+hostname) { + t.Errorf("probe failed, response body: %v", rr.Body.String()) + } + +} -- 2.25.1