From 2070c215a298405b8606be1a8215e26d47a9653a Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Tue, 28 Jun 2022 05:04:10 -0700 Subject: [PATCH] handle missing funcNames for handlers (#15188) also use designated names for internal calls - storageREST calls are storageR - lockREST calls are lockR - peerREST calls are just peer Named in this fashion to facilitate wildcard matches by having prefixes of the same name. Additionally, also enable funcNames for generic handlers that return errors, currently we disable '' --- cmd/auth-handler.go | 18 +++++++++++++++ cmd/generic-handlers.go | 50 +++++++++++++++++++++++++++++++++++++++++ cmd/http-tracer.go | 15 +++++++------ 3 files changed, 76 insertions(+), 7 deletions(-) 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 {