From 94d5822426879b2c9a3b93c53532c394f27c54e8 Mon Sep 17 00:00:00 2001 From: Holger Obermaier <40787752+ho-ob@users.noreply.github.com> Date: Wed, 20 Sep 2023 17:33:08 +0200 Subject: [PATCH] Add basic authentication support --- receivers/httpReceiver.go | 30 ++++++++++++++++++++++++++++++ receivers/httpReceiver.md | 12 ++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/receivers/httpReceiver.go b/receivers/httpReceiver.go index 27e94d9..c243e41 100644 --- a/receivers/httpReceiver.go +++ b/receivers/httpReceiver.go @@ -28,6 +28,11 @@ type HttpReceiverConfig struct { // should be larger than the measurement interval to keep the connection open IdleTimeout string `json:"idle_timeout"` idleTimeout time.Duration + + // Basic authentication + Username string `json:"username"` + Password string `json:"password"` + useBasicAuth bool } type HttpReceiver struct { @@ -58,6 +63,8 @@ func (r *HttpReceiver) Init(name string, config json.RawMessage) error { if len(r.config.Port) == 0 { return errors.New("not all configuration variables set required by HttpReceiver") } + + // Check idle timeout config if len(r.config.IdleTimeout) > 0 { t, err := time.ParseDuration(r.config.IdleTimeout) if err == nil { @@ -65,6 +72,18 @@ func (r *HttpReceiver) Init(name string, config json.RawMessage) error { r.config.idleTimeout = t } } + + // Check basic authentication config + if len(r.config.Username) > 0 || len(r.config.Password) > 0 { + r.config.useBasicAuth = true + } + if r.config.useBasicAuth && len(r.config.Username) == 0 { + return errors.New("basic authentication requires username") + } + if r.config.useBasicAuth && len(r.config.Password) == 0 { + return errors.New("basic authentication requires password") + } + r.meta = map[string]string{"source": r.name} p := r.config.Path if !strings.HasPrefix(p, "/") { @@ -100,11 +119,22 @@ func (r *HttpReceiver) Start() { } func (r *HttpReceiver) ServerHttp(w http.ResponseWriter, req *http.Request) { + + // Check request method, only post method is handled if req.Method != http.MethodPost { http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) return } + // Check basic authentication + if r.config.useBasicAuth { + username, password, ok := req.BasicAuth() + if !ok || username != r.config.Username || password != r.config.Password { + http.Error(w, "Unauthorized", http.StatusUnauthorized) + return + } + } + d := influx.NewDecoder(req.Body) for d.Next() { diff --git a/receivers/httpReceiver.md b/receivers/httpReceiver.md index 873cf6d..affe1e4 100644 --- a/receivers/httpReceiver.md +++ b/receivers/httpReceiver.md @@ -10,7 +10,10 @@ The `http` receiver can be used receive metrics through HTTP POST requests. "type": "http", "address" : "", "port" : "8080", - "path" : "/write" + "path" : "/write", + "idle_timeout": "120s", + "username": "myUser", + "password": "myPW" } } ``` @@ -19,6 +22,9 @@ The `http` receiver can be used receive metrics through HTTP POST requests. - `address`: Listen address - `port`: Listen port - `path`: URL path for the write endpoint +- `idle_timeout`: Maximum amount of time to wait for the next request when keep-alives are enabled should be larger than the measurement interval to keep the connection open +- `username`: username for basic authentication +- `password`: password for basic authentication The HTTP endpoint listens to `http://
:/` @@ -28,7 +34,9 @@ The HTTP endpoint listens to `http://
:/` - Use curl to send message to `http` receiver ```bash - curl http://localhost:8080/write --data \ + curl http://localhost:8080/write \ + --user "myUser:myPW" \ + --data \ "myMetric,hostname=myHost,type=hwthread,type-id=0,unit=Hz value=400000i 1694777161164284635 myMetric,hostname=myHost,type=hwthread,type-id=1,unit=Hz value=400001i 1694777161164284635" ```