diff --git a/cmd/auth-handler.go b/cmd/auth-handler.go index efab56ddb..508c78597 100644 --- a/cmd/auth-handler.go +++ b/cmd/auth-handler.go @@ -500,11 +500,18 @@ func isSupportedS3AuthType(aType authType) bool { func setAuthHandler(h http.Handler) http.Handler { // handler for validating incoming authorization headers. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + tc, ok := r.Context().Value(contextTraceReqKey).(*traceCtxt) + aType := getRequestAuthType(r) if aType == authTypeSigned || aType == authTypeSignedV2 || aType == authTypeStreamingSigned { // Verify if date headers are set, if not reject the request amzDate, errCode := parseAmzDateHeader(r) if errCode != ErrNone { + if ok { + tc.funcName = "handler.Auth" + tc.responseRecorder.LogErrBody = true + } + // All our internal APIs are sensitive towards Date // header, for all requests where Date header is not // present we will reject such clients. @@ -516,6 +523,11 @@ func setAuthHandler(h http.Handler) http.Handler { // or in the future, reject request otherwise. curTime := UTCNow() if curTime.Sub(amzDate) > globalMaxSkewTime || amzDate.Sub(curTime) > globalMaxSkewTime { + if ok { + tc.funcName = "handler.Auth" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrRequestTimeTooSkewed), r.URL) atomic.AddUint64(&globalHTTPStats.rejectedRequestsTime, 1) return @@ -525,6 +537,12 @@ func setAuthHandler(h http.Handler) http.Handler { h.ServeHTTP(w, r) return } + + if ok { + tc.funcName = "handler.Auth" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrSignatureVersionNotSupported), r.URL) atomic.AddUint64(&globalHTTPStats.rejectedRequestsAuth, 1) }) diff --git a/cmd/generic-handlers.go b/cmd/generic-handlers.go index 6ce7258e3..c4935b843 100644 --- a/cmd/generic-handlers.go +++ b/cmd/generic-handlers.go @@ -97,12 +97,25 @@ func isHTTPHeaderSizeTooLarge(header http.Header) bool { // Limits body and header to specific allowed maximum limits as per S3/MinIO API requirements. func setRequestLimitHandler(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + tc, ok := r.Context().Value(contextTraceReqKey).(*traceCtxt) + // Reject unsupported reserved metadata first before validation. if containsReservedMetadata(r.Header) { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrUnsupportedMetadata), r.URL) return } + if isHTTPHeaderSizeTooLarge(r.Header) { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrMetadataTooLarge), r.URL) atomic.AddUint64(&globalHTTPStats.rejectedRequestsHeader, 1) return @@ -373,7 +386,14 @@ func hasMultipleAuth(r *http.Request) bool { // any malicious requests. func setRequestValidityHandler(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + tc, ok := r.Context().Value(contextTraceReqKey).(*traceCtxt) + if err := hasBadHost(r.Host); err != nil { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest) invalidReq.Description = fmt.Sprintf("%s (%s)", invalidReq.Description, err) writeErrorResponse(r.Context(), w, invalidReq, r.URL) @@ -383,6 +403,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler { // Check for bad components in URL path. if hasBadPathComponent(r.URL.Path) { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL) atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1) return @@ -391,6 +416,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler { for _, vv := range r.Form { for _, v := range vv { if hasBadPathComponent(v) { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL) atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1) return @@ -398,6 +428,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler { } } if hasMultipleAuth(r) { + if ok { + tc.funcName = "handler.Auth" + tc.responseRecorder.LogErrBody = true + } + invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest) invalidReq.Description = fmt.Sprintf("%s (request has multiple authentication types, please use one)", invalidReq.Description) writeErrorResponse(r.Context(), w, invalidReq, r.URL) @@ -408,6 +443,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler { bucketName, _ := request2BucketObjectName(r) if isMinioReservedBucket(bucketName) || isMinioMetaBucket(bucketName) { if !guessIsRPCReq(r) && !guessIsBrowserReq(r) && !guessIsHealthCheckReq(r) && !guessIsMetricsReq(r) && !isAdminReq(r) { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrAllAccessDisabled), r.URL) return } @@ -415,8 +455,18 @@ func setRequestValidityHandler(h http.Handler) http.Handler { // Deny SSE-C requests if not made over TLS if !globalIsTLS && (crypto.SSEC.IsRequested(r.Header) || crypto.SSECopy.IsRequested(r.Header)) { if r.Method == http.MethodHead { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = false + } + writeErrorResponseHeadersOnly(w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest)) } else { + if ok { + tc.funcName = "handler.ValidRequest" + tc.responseRecorder.LogErrBody = true + } + writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest), r.URL) } return diff --git a/cmd/http-tracer.go b/cmd/http-tracer.go index f16c49ca4..76fcf058d 100644 --- a/cmd/http-tracer.go +++ b/cmd/http-tracer.go @@ -97,13 +97,14 @@ func getOpName(name string) (op string) { op = strings.TrimSuffix(op, "Handler-fm") op = strings.Replace(op, "objectAPIHandlers", "s3", 1) op = strings.Replace(op, "adminAPIHandlers", "admin", 1) - op = strings.Replace(op, "(*webAPIHandlers)", "web", 1) - op = strings.Replace(op, "(*storageRESTServer)", "internal", 1) - op = strings.Replace(op, "(*peerRESTServer)", "internal", 1) - op = strings.Replace(op, "(*lockRESTServer)", "internal", 1) + op = strings.Replace(op, "(*storageRESTServer)", "storageR", 1) + op = strings.Replace(op, "(*peerRESTServer)", "peer", 1) + op = strings.Replace(op, "(*lockRESTServer)", "lockR", 1) op = strings.Replace(op, "(*stsAPIHandlers)", "sts", 1) - op = strings.Replace(op, "LivenessCheckHandler", "healthcheck", 1) - op = strings.Replace(op, "ReadinessCheckHandler", "healthcheck", 1) + op = strings.Replace(op, "ClusterCheckHandler", "health.Cluster", 1) + op = strings.Replace(op, "ClusterReadCheckHandler", "health.ClusterRead", 1) + op = strings.Replace(op, "LivenessCheckHandler", "health.Liveness", 1) + op = strings.Replace(op, "ReadinessCheckHandler", "health.Readiness", 1) op = strings.Replace(op, "-fm", "", 1) return op } @@ -163,7 +164,7 @@ func httpTracer(h http.Handler) http.Handler { // Calculate node name nodeName := r.Host - if nodeName == "" || globalIsDistErasure { + if globalIsDistErasure { nodeName = globalLocalNodeName } if host, port, err := net.SplitHostPort(nodeName); err == nil {