add validation logs for configured Logger/Audit HTTP targets (#10274)

extra logs in-case of misconfiguration of audit/logger targets
master
Harshavardhana 4 years ago committed by GitHub
parent 01a2ccc52f
commit f7c1a59de1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      cmd/config-current.go
  2. 5
      cmd/consolelogger.go
  3. 4
      cmd/data-update-tracker_test.go
  4. 9
      cmd/logger/audit.go
  5. 5
      cmd/logger/target/console/console.go
  6. 65
      cmd/logger/target/http/http.go
  7. 21
      cmd/logger/targets.go

@ -455,28 +455,32 @@ func lookupConfigs(s config.Config, setDriveCount int) {
for _, l := range loggerCfg.HTTP { for _, l := range loggerCfg.HTTP {
if l.Enabled { if l.Enabled {
// Enable http logging // Enable http logging
logger.AddTarget( if err = logger.AddTarget(
http.New(http.WithEndpoint(l.Endpoint), http.New(http.WithEndpoint(l.Endpoint),
http.WithAuthToken(l.AuthToken), http.WithAuthToken(l.AuthToken),
http.WithUserAgent(loggerUserAgent), http.WithUserAgent(loggerUserAgent),
http.WithLogKind(string(logger.All)), http.WithLogKind(string(logger.All)),
http.WithTransport(NewGatewayHTTPTransport()), http.WithTransport(NewGatewayHTTPTransport()),
), ),
) ); err != nil {
logger.LogIf(ctx, fmt.Errorf("Unable to initialize console HTTP target: %w", err))
}
} }
} }
for _, l := range loggerCfg.Audit { for _, l := range loggerCfg.Audit {
if l.Enabled { if l.Enabled {
// Enable http audit logging // Enable http audit logging
logger.AddAuditTarget( if err = logger.AddAuditTarget(
http.New(http.WithEndpoint(l.Endpoint), http.New(http.WithEndpoint(l.Endpoint),
http.WithAuthToken(l.AuthToken), http.WithAuthToken(l.AuthToken),
http.WithUserAgent(loggerUserAgent), http.WithUserAgent(loggerUserAgent),
http.WithLogKind(string(logger.All)), http.WithLogKind(string(logger.All)),
http.WithTransport(NewGatewayHTTPTransport()), http.WithTransport(NewGatewayHTTPTransport()),
), ),
) ); err != nil {
logger.LogIf(ctx, fmt.Errorf("Unable to initialize audit HTTP target: %w", err))
}
} }
} }

@ -117,6 +117,11 @@ func (sys *HTTPConsoleLoggerSys) Subscribe(subCh chan interface{}, doneCh <-chan
sys.pubsub.Subscribe(subCh, doneCh, filter) sys.pubsub.Subscribe(subCh, doneCh, filter)
} }
// Validate if HTTPConsoleLoggerSys is valid, always returns nil right now
func (sys *HTTPConsoleLoggerSys) Validate() error {
return nil
}
// Send log message 'e' to console and publish to console // Send log message 'e' to console and publish to console
// log pubsub system // log pubsub system
func (sys *HTTPConsoleLoggerSys) Send(e interface{}, logKind string) error { func (sys *HTTPConsoleLoggerSys) Send(e interface{}, logKind string) error {

@ -42,6 +42,10 @@ type testingLogger struct {
t testLoggerI t testLoggerI
} }
func (t *testingLogger) Validate() error {
return nil
}
func (t *testingLogger) Send(entry interface{}, errKind string) error { func (t *testingLogger) Send(entry interface{}, errKind string) error {
t.mu.Lock() t.mu.Lock()
defer t.mu.Unlock() defer t.mu.Unlock()

@ -125,15 +125,6 @@ func (lrw *ResponseWriter) Size() int {
return lrw.bytesWritten return lrw.bytesWritten
} }
// AuditTargets is the list of enabled audit loggers
var AuditTargets = []Target{}
// AddAuditTarget adds a new audit logger target to the
// list of enabled loggers
func AddAuditTarget(t Target) {
AuditTargets = append(AuditTargets, t)
}
// AuditLog - logs audit logs to all audit targets. // AuditLog - logs audit logs to all audit targets.
func AuditLog(w http.ResponseWriter, r *http.Request, api string, reqClaims map[string]interface{}, filterKeys ...string) { func AuditLog(w http.ResponseWriter, r *http.Request, api string, reqClaims map[string]interface{}, filterKeys ...string) {
// Fast exit if there is not audit target configured // Fast exit if there is not audit target configured

@ -32,6 +32,11 @@ import (
// in plain or json format to the standard output. // in plain or json format to the standard output.
type Target struct{} type Target struct{}
// Validate - validate if the tty can be written to
func (c *Target) Validate() error {
return nil
}
// Send log message 'e' to console // Send log message 'e' to console
func (c *Target) Send(e interface{}, logKind string) error { func (c *Target) Send(e interface{}, logKind string) error {
entry, ok := e.(log.Entry) entry, ok := e.(log.Entry)

@ -18,12 +18,16 @@ package http
import ( import (
"bytes" "bytes"
"context"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt"
"net/http" "net/http"
"strings" "strings"
"time"
xhttp "github.com/minio/minio/cmd/http" xhttp "github.com/minio/minio/cmd/http"
"github.com/minio/minio/cmd/logger"
) )
// Target implements logger.Target and sends the json // Target implements logger.Target and sends the json
@ -45,6 +49,47 @@ type Target struct {
client http.Client client http.Client
} }
// Validate validate the http target
func (h *Target) Validate() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, h.endpoint, strings.NewReader(`{}`))
if err != nil {
return err
}
req.Header.Set(xhttp.ContentType, "application/json")
// Set user-agent to indicate MinIO release
// version to the configured log endpoint
req.Header.Set("User-Agent", h.userAgent)
if h.authToken != "" {
req.Header.Set("Authorization", h.authToken)
}
resp, err := h.client.Do(req)
if err != nil {
return err
}
// Drain any response.
xhttp.DrainBody(resp.Body)
if resp.StatusCode != http.StatusOK {
switch resp.StatusCode {
case http.StatusForbidden:
return fmt.Errorf("%s returned '%s', please check if your auth token is correctly set",
h.endpoint, resp.Status)
}
return fmt.Errorf("%s returned '%s', please check your endpoint configuration",
h.endpoint, resp.Status)
}
return nil
}
func (h *Target) startHTTPLogger() { func (h *Target) startHTTPLogger() {
// Create a routine which sends json logs received // Create a routine which sends json logs received
// from an internal channel. // from an internal channel.
@ -55,8 +100,11 @@ func (h *Target) startHTTPLogger() {
continue continue
} }
req, err := http.NewRequest(http.MethodPost, h.endpoint, bytes.NewReader(logJSON)) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
req, err := http.NewRequestWithContext(ctx, http.MethodPost,
h.endpoint, bytes.NewReader(logJSON))
if err != nil { if err != nil {
cancel()
continue continue
} }
req.Header.Set(xhttp.ContentType, "application/json") req.Header.Set(xhttp.ContentType, "application/json")
@ -70,13 +118,26 @@ func (h *Target) startHTTPLogger() {
} }
resp, err := h.client.Do(req) resp, err := h.client.Do(req)
cancel()
if err != nil { if err != nil {
h.client.CloseIdleConnections() logger.LogIf(ctx, fmt.Errorf("%s returned '%w', please check your endpoint configuration\n",
h.endpoint, err))
continue continue
} }
// Drain any response. // Drain any response.
xhttp.DrainBody(resp.Body) xhttp.DrainBody(resp.Body)
if resp.StatusCode != http.StatusOK {
switch resp.StatusCode {
case http.StatusForbidden:
logger.LogIf(ctx, fmt.Errorf("%s returned '%s', please check if your auth token is correctly set",
h.endpoint, resp.Status))
default:
logger.LogIf(ctx, fmt.Errorf("%s returned '%s', please check your endpoint configuration",
h.endpoint, resp.Status))
}
}
} }
}() }()
} }

@ -20,14 +20,33 @@ package logger
// a single log entry and Send it to the log target // a single log entry and Send it to the log target
// e.g. Send the log to a http server // e.g. Send the log to a http server
type Target interface { type Target interface {
Validate() error
Send(entry interface{}, errKind string) error Send(entry interface{}, errKind string) error
} }
// Targets is the set of enabled loggers // Targets is the set of enabled loggers
var Targets = []Target{} var Targets = []Target{}
// AuditTargets is the list of enabled audit loggers
var AuditTargets = []Target{}
// AddAuditTarget adds a new audit logger target to the
// list of enabled loggers
func AddAuditTarget(t Target) error {
if err := t.Validate(); err != nil {
return err
}
AuditTargets = append(AuditTargets, t)
return nil
}
// AddTarget adds a new logger target to the // AddTarget adds a new logger target to the
// list of enabled loggers // list of enabled loggers
func AddTarget(t Target) { func AddTarget(t Target) error {
if err := t.Validate(); err != nil {
return err
}
Targets = append(Targets, t) Targets = append(Targets, t)
return nil
} }

Loading…
Cancel
Save