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 '<unknown>'
This commit is contained in:
Harshavardhana 2022-06-28 05:04:10 -07:00 committed by GitHub
parent 94b98222c2
commit 2070c215a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 76 additions and 7 deletions

View File

@ -500,11 +500,18 @@ func isSupportedS3AuthType(aType authType) bool {
func setAuthHandler(h http.Handler) http.Handler { func setAuthHandler(h http.Handler) http.Handler {
// handler for validating incoming authorization headers. // handler for validating incoming authorization headers.
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tc, ok := r.Context().Value(contextTraceReqKey).(*traceCtxt)
aType := getRequestAuthType(r) aType := getRequestAuthType(r)
if aType == authTypeSigned || aType == authTypeSignedV2 || aType == authTypeStreamingSigned { if aType == authTypeSigned || aType == authTypeSignedV2 || aType == authTypeStreamingSigned {
// Verify if date headers are set, if not reject the request // Verify if date headers are set, if not reject the request
amzDate, errCode := parseAmzDateHeader(r) amzDate, errCode := parseAmzDateHeader(r)
if errCode != ErrNone { if errCode != ErrNone {
if ok {
tc.funcName = "handler.Auth"
tc.responseRecorder.LogErrBody = true
}
// All our internal APIs are sensitive towards Date // All our internal APIs are sensitive towards Date
// header, for all requests where Date header is not // header, for all requests where Date header is not
// present we will reject such clients. // present we will reject such clients.
@ -516,6 +523,11 @@ func setAuthHandler(h http.Handler) http.Handler {
// or in the future, reject request otherwise. // or in the future, reject request otherwise.
curTime := UTCNow() curTime := UTCNow()
if curTime.Sub(amzDate) > globalMaxSkewTime || amzDate.Sub(curTime) > globalMaxSkewTime { 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) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrRequestTimeTooSkewed), r.URL)
atomic.AddUint64(&globalHTTPStats.rejectedRequestsTime, 1) atomic.AddUint64(&globalHTTPStats.rejectedRequestsTime, 1)
return return
@ -525,6 +537,12 @@ func setAuthHandler(h http.Handler) http.Handler {
h.ServeHTTP(w, r) h.ServeHTTP(w, r)
return return
} }
if ok {
tc.funcName = "handler.Auth"
tc.responseRecorder.LogErrBody = true
}
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrSignatureVersionNotSupported), r.URL) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrSignatureVersionNotSupported), r.URL)
atomic.AddUint64(&globalHTTPStats.rejectedRequestsAuth, 1) atomic.AddUint64(&globalHTTPStats.rejectedRequestsAuth, 1)
}) })

View File

@ -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. // Limits body and header to specific allowed maximum limits as per S3/MinIO API requirements.
func setRequestLimitHandler(h http.Handler) http.Handler { func setRequestLimitHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
tc, ok := r.Context().Value(contextTraceReqKey).(*traceCtxt)
// Reject unsupported reserved metadata first before validation. // Reject unsupported reserved metadata first before validation.
if containsReservedMetadata(r.Header) { if containsReservedMetadata(r.Header) {
if ok {
tc.funcName = "handler.ValidRequest"
tc.responseRecorder.LogErrBody = true
}
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrUnsupportedMetadata), r.URL) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrUnsupportedMetadata), r.URL)
return return
} }
if isHTTPHeaderSizeTooLarge(r.Header) { if isHTTPHeaderSizeTooLarge(r.Header) {
if ok {
tc.funcName = "handler.ValidRequest"
tc.responseRecorder.LogErrBody = true
}
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrMetadataTooLarge), r.URL) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrMetadataTooLarge), r.URL)
atomic.AddUint64(&globalHTTPStats.rejectedRequestsHeader, 1) atomic.AddUint64(&globalHTTPStats.rejectedRequestsHeader, 1)
return return
@ -373,7 +386,14 @@ func hasMultipleAuth(r *http.Request) bool {
// any malicious requests. // any malicious requests.
func setRequestValidityHandler(h http.Handler) http.Handler { func setRequestValidityHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 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 err := hasBadHost(r.Host); err != nil {
if ok {
tc.funcName = "handler.ValidRequest"
tc.responseRecorder.LogErrBody = true
}
invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest) invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest)
invalidReq.Description = fmt.Sprintf("%s (%s)", invalidReq.Description, err) invalidReq.Description = fmt.Sprintf("%s (%s)", invalidReq.Description, err)
writeErrorResponse(r.Context(), w, invalidReq, r.URL) 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. // Check for bad components in URL path.
if hasBadPathComponent(r.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) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL)
atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1) atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1)
return return
@ -391,6 +416,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler {
for _, vv := range r.Form { for _, vv := range r.Form {
for _, v := range vv { for _, v := range vv {
if hasBadPathComponent(v) { if hasBadPathComponent(v) {
if ok {
tc.funcName = "handler.ValidRequest"
tc.responseRecorder.LogErrBody = true
}
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInvalidResourceName), r.URL)
atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1) atomic.AddUint64(&globalHTTPStats.rejectedRequestsInvalid, 1)
return return
@ -398,6 +428,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler {
} }
} }
if hasMultipleAuth(r) { if hasMultipleAuth(r) {
if ok {
tc.funcName = "handler.Auth"
tc.responseRecorder.LogErrBody = true
}
invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest) invalidReq := errorCodes.ToAPIErr(ErrInvalidRequest)
invalidReq.Description = fmt.Sprintf("%s (request has multiple authentication types, please use one)", invalidReq.Description) invalidReq.Description = fmt.Sprintf("%s (request has multiple authentication types, please use one)", invalidReq.Description)
writeErrorResponse(r.Context(), w, invalidReq, r.URL) writeErrorResponse(r.Context(), w, invalidReq, r.URL)
@ -408,6 +443,11 @@ func setRequestValidityHandler(h http.Handler) http.Handler {
bucketName, _ := request2BucketObjectName(r) bucketName, _ := request2BucketObjectName(r)
if isMinioReservedBucket(bucketName) || isMinioMetaBucket(bucketName) { if isMinioReservedBucket(bucketName) || isMinioMetaBucket(bucketName) {
if !guessIsRPCReq(r) && !guessIsBrowserReq(r) && !guessIsHealthCheckReq(r) && !guessIsMetricsReq(r) && !isAdminReq(r) { 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) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrAllAccessDisabled), r.URL)
return return
} }
@ -415,8 +455,18 @@ func setRequestValidityHandler(h http.Handler) http.Handler {
// Deny SSE-C requests if not made over TLS // Deny SSE-C requests if not made over TLS
if !globalIsTLS && (crypto.SSEC.IsRequested(r.Header) || crypto.SSECopy.IsRequested(r.Header)) { if !globalIsTLS && (crypto.SSEC.IsRequested(r.Header) || crypto.SSECopy.IsRequested(r.Header)) {
if r.Method == http.MethodHead { if r.Method == http.MethodHead {
if ok {
tc.funcName = "handler.ValidRequest"
tc.responseRecorder.LogErrBody = false
}
writeErrorResponseHeadersOnly(w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest)) writeErrorResponseHeadersOnly(w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest))
} else { } else {
if ok {
tc.funcName = "handler.ValidRequest"
tc.responseRecorder.LogErrBody = true
}
writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest), r.URL) writeErrorResponse(r.Context(), w, errorCodes.ToAPIErr(ErrInsecureSSECustomerRequest), r.URL)
} }
return return

View File

@ -97,13 +97,14 @@ func getOpName(name string) (op string) {
op = strings.TrimSuffix(op, "Handler-fm") op = strings.TrimSuffix(op, "Handler-fm")
op = strings.Replace(op, "objectAPIHandlers", "s3", 1) op = strings.Replace(op, "objectAPIHandlers", "s3", 1)
op = strings.Replace(op, "adminAPIHandlers", "admin", 1) op = strings.Replace(op, "adminAPIHandlers", "admin", 1)
op = strings.Replace(op, "(*webAPIHandlers)", "web", 1) op = strings.Replace(op, "(*storageRESTServer)", "storageR", 1)
op = strings.Replace(op, "(*storageRESTServer)", "internal", 1) op = strings.Replace(op, "(*peerRESTServer)", "peer", 1)
op = strings.Replace(op, "(*peerRESTServer)", "internal", 1) op = strings.Replace(op, "(*lockRESTServer)", "lockR", 1)
op = strings.Replace(op, "(*lockRESTServer)", "internal", 1)
op = strings.Replace(op, "(*stsAPIHandlers)", "sts", 1) op = strings.Replace(op, "(*stsAPIHandlers)", "sts", 1)
op = strings.Replace(op, "LivenessCheckHandler", "healthcheck", 1) op = strings.Replace(op, "ClusterCheckHandler", "health.Cluster", 1)
op = strings.Replace(op, "ReadinessCheckHandler", "healthcheck", 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) op = strings.Replace(op, "-fm", "", 1)
return op return op
} }
@ -163,7 +164,7 @@ func httpTracer(h http.Handler) http.Handler {
// Calculate node name // Calculate node name
nodeName := r.Host nodeName := r.Host
if nodeName == "" || globalIsDistErasure { if globalIsDistErasure {
nodeName = globalLocalNodeName nodeName = globalLocalNodeName
} }
if host, port, err := net.SplitHostPort(nodeName); err == nil { if host, port, err := net.SplitHostPort(nodeName); err == nil {