1
0
mirror of https://github.com/0rangebananaspy/authelia.git synced 2024-09-14 22:47:21 +07:00

fix(server): handled errors not logged correctly ()

This fixes an issue where errors handled by the ErrorHandler were not correctly logged. It also ensures the errors are logged with fields to make them easy to diagnose.

Fixes 
This commit is contained in:
James Elliott 2022-06-12 09:26:28 +10:00 committed by GitHub
parent 6f8ec531e7
commit 5e3a1fd863
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 18 deletions
internal/server

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"fmt"
"net" "net"
"os" "os"
"strconv" "strconv"
@ -9,6 +10,7 @@ import (
duoapi "github.com/duosecurity/duo_api_golang" duoapi "github.com/duosecurity/duo_api_golang"
"github.com/fasthttp/router" "github.com/fasthttp/router"
"github.com/sirupsen/logrus"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/expvarhandler" "github.com/valyala/fasthttp/expvarhandler"
"github.com/valyala/fasthttp/pprofhandler" "github.com/valyala/fasthttp/pprofhandler"
@ -23,9 +25,7 @@ import (
) )
// Replacement for the default error handler in fasthttp. // Replacement for the default error handler in fasthttp.
func handlerError() func(ctx *fasthttp.RequestCtx, err error) { func handleError() func(ctx *fasthttp.RequestCtx, err error) {
logger := logging.Logger()
headerXForwardedFor := []byte(fasthttp.HeaderXForwardedFor) headerXForwardedFor := []byte(fasthttp.HeaderXForwardedFor)
getRemoteIP := func(ctx *fasthttp.RequestCtx) string { getRemoteIP := func(ctx *fasthttp.RequestCtx) string {
@ -41,26 +41,43 @@ func handlerError() func(ctx *fasthttp.RequestCtx, err error) {
} }
return func(ctx *fasthttp.RequestCtx, err error) { return func(ctx *fasthttp.RequestCtx, err error) {
var (
statusCode int
message string
)
switch e := err.(type) { switch e := err.(type) {
case *fasthttp.ErrSmallBuffer: case *fasthttp.ErrSmallBuffer:
logger.Tracef("Request was too large to handle from client %s. Response Code %d.", getRemoteIP(ctx), fasthttp.StatusRequestHeaderFieldsTooLarge) statusCode = fasthttp.StatusRequestHeaderFieldsTooLarge
ctx.Error("request header too large", fasthttp.StatusRequestHeaderFieldsTooLarge) message = "Request from client exceeded the server buffer sizes."
case *net.OpError: case *net.OpError:
if e.Timeout() { if e.Timeout() {
logger.Tracef("Request timeout occurred while handling from client %s: %s. Response Code %d.", getRemoteIP(ctx), ctx.RequestURI(), fasthttp.StatusRequestTimeout) statusCode = fasthttp.StatusRequestTimeout
ctx.Error("request timeout", fasthttp.StatusRequestTimeout) message = "Request timeout occurred while handling request from client."
} else { } else {
logger.Tracef("An unknown error occurred while handling a request from client %s: %s. Response Code %d.", getRemoteIP(ctx), ctx.RequestURI(), fasthttp.StatusBadRequest) statusCode = fasthttp.StatusBadRequest
ctx.Error("error when parsing request", fasthttp.StatusBadRequest) message = "An unknown network error occurred while handling a request from client."
} }
default: default:
logger.Tracef("An unknown error occurred while handling a request from client %s: %s. Response Code %d.", getRemoteIP(ctx), ctx.RequestURI(), fasthttp.StatusBadRequest) statusCode = fasthttp.StatusBadRequest
ctx.Error("error when parsing request", fasthttp.StatusBadRequest) message = "An unknown error occurred while handling a request from client."
} }
logging.Logger().WithFields(logrus.Fields{
"method": string(ctx.Method()),
"path": string(ctx.Path()),
"remote_ip": getRemoteIP(ctx),
"status_code": statusCode,
}).WithError(err).Error(message)
ctx.Response.Reset()
ctx.SetStatusCode(statusCode)
ctx.SetContentType("text/plain; charset=utf-8")
ctx.SetBodyString(fmt.Sprintf("%d %s", statusCode, fasthttp.StatusMessage(statusCode)))
} }
} }
func handlerNotFound(next fasthttp.RequestHandler) fasthttp.RequestHandler { func handleNotFound(next fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) { return func(ctx *fasthttp.RequestCtx) {
path := strings.ToLower(string(ctx.Path())) path := strings.ToLower(string(ctx.Path()))
@ -76,11 +93,11 @@ func handlerNotFound(next fasthttp.RequestHandler) fasthttp.RequestHandler {
} }
} }
func handlerMethodNotAllowed(ctx *fasthttp.RequestCtx) { func handleMethodNotAllowed(ctx *fasthttp.RequestCtx) {
handlers.SetStatusCodeResponse(ctx, fasthttp.StatusMethodNotAllowed) handlers.SetStatusCodeResponse(ctx, fasthttp.StatusMethodNotAllowed)
} }
func getHandler(config schema.Configuration, providers middlewares.Providers) fasthttp.RequestHandler { func handleRouter(config schema.Configuration, providers middlewares.Providers) fasthttp.RequestHandler {
rememberMe := strconv.FormatBool(config.Session.RememberMeDuration != schema.RememberMeDisabled) rememberMe := strconv.FormatBool(config.Session.RememberMeDuration != schema.RememberMeDisabled)
resetPassword := strconv.FormatBool(!config.AuthenticationBackend.DisableResetPassword) resetPassword := strconv.FormatBool(!config.AuthenticationBackend.DisableResetPassword)
@ -307,10 +324,10 @@ func getHandler(config schema.Configuration, providers middlewares.Providers) fa
r.POST("/api/oidc/revoke", policyCORSRevocation.Middleware(middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthRevocationPOST)))) r.POST("/api/oidc/revoke", policyCORSRevocation.Middleware(middlewareOIDC(middlewares.NewHTTPToAutheliaHandlerAdaptor(handlers.OAuthRevocationPOST))))
} }
r.NotFound = handlerNotFound(middleware(serveIndexHandler)) r.NotFound = handleNotFound(middleware(serveIndexHandler))
r.HandleMethodNotAllowed = true r.HandleMethodNotAllowed = true
r.MethodNotAllowed = handlerMethodNotAllowed r.MethodNotAllowed = handleMethodNotAllowed
if config.Server.Path != "" { if config.Server.Path != "" {
return middlewares.StripPath(config.Server.Path)(middlewares.LogRequest(r.Handler)) return middlewares.StripPath(config.Server.Path)(middlewares.LogRequest(r.Handler))

View File

@ -17,8 +17,8 @@ import (
// CreateServer Create Authelia's internal webserver with the given configuration and providers. // CreateServer Create Authelia's internal webserver with the given configuration and providers.
func CreateServer(config schema.Configuration, providers middlewares.Providers) (*fasthttp.Server, net.Listener) { func CreateServer(config schema.Configuration, providers middlewares.Providers) (*fasthttp.Server, net.Listener) {
server := &fasthttp.Server{ server := &fasthttp.Server{
ErrorHandler: handlerError(), ErrorHandler: handleError(),
Handler: getHandler(config, providers), Handler: handleRouter(config, providers),
NoDefaultServerHeader: true, NoDefaultServerHeader: true,
ReadBufferSize: config.Server.ReadBufferSize, ReadBufferSize: config.Server.ReadBufferSize,
WriteBufferSize: config.Server.WriteBufferSize, WriteBufferSize: config.Server.WriteBufferSize,