fix: rate limiting X-Real-IP from the real peer
This commit is contained in:
1 parent
9b47685002
commit
0e050c36ff
11 files changed
+439
-8
No files matched your search
@@ -0,0 +1,44 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func TrustedProxyRealIP(trustedProxies []string) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
realIP := r.Header.Get("X-Real-IP")
|
||||
if realIP != "" && isTrustedProxy(r.RemoteAddr, trustedProxies) {
|
||||
r.RemoteAddr = withRewrittenHost(r.RemoteAddr, realIP)
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func isTrustedProxy(remoteAddr string, trustedProxies []string) bool {
|
||||
host := hostOf(remoteAddr)
|
||||
for _, trusted := range trustedProxies {
|
||||
if host == trusted {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func hostOf(remoteAddr string) string {
|
||||
host, _, err := net.SplitHostPort(remoteAddr)
|
||||
if err != nil {
|
||||
return remoteAddr
|
||||
}
|
||||
return host
|
||||
}
|
||||
|
||||
func withRewrittenHost(remoteAddr string, newHost string) string {
|
||||
_, port, err := net.SplitHostPort(remoteAddr)
|
||||
if err != nil {
|
||||
return newHost
|
||||
}
|
||||
return net.JoinHostPort(newHost, port)
|
||||
}
|
||||
+4
-4
@@ -52,7 +52,7 @@ func NewArticleRouter(container *UseCases) http.Handler {
|
||||
return r
|
||||
}
|
||||
|
||||
func NewAuthRouter(container *UseCases, isProduction bool, rateLimit config.AuthRateLimitSettings) http.Handler {
|
||||
func NewAuthRouter(container *UseCases, isProduction bool, rateLimit config.AuthRateLimitSettings, trustedProxies []string) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
|
||||
loginHandler := auth.NewLoginHandler(container.Token, container.CreateUserUseCase, container.AuthenticateUserUseCase, isProduction)
|
||||
@@ -61,13 +61,13 @@ func NewAuthRouter(container *UseCases, isProduction bool, rateLimit config.Auth
|
||||
|
||||
r.Post("/register", loginHandler.Register)
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(chimiddleware.RealIP)
|
||||
r.Use(middleware.TrustedProxyRealIP(trustedProxies))
|
||||
r.Use(middleware.NewRateLimiter(rateLimit.MaxAttempts, rateLimit.Window))
|
||||
r.Post("/login", loginHandler.Login)
|
||||
})
|
||||
r.Post("/logout", loginHandler.Logout)
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(chimiddleware.RealIP)
|
||||
r.Use(middleware.TrustedProxyRealIP(trustedProxies))
|
||||
r.Use(middleware.NewRateLimiter(rateLimit.MaxAttempts, rateLimit.Window))
|
||||
r.Post("/password-reset", passwordResetHandler.RequestPasswordReset)
|
||||
})
|
||||
@@ -94,7 +94,7 @@ func InitBackendRoutes(container *UseCases, settings config.Settings) *chi.Mux {
|
||||
r.Use(jwtauth.Verifier(container.Token))
|
||||
r.Mount("/article", NewArticleRouter(container))
|
||||
})
|
||||
r.Mount("/auth", NewAuthRouter(container, settings.IsProduction(), settings.AuthRateLimit))
|
||||
r.Mount("/auth", NewAuthRouter(container, settings.IsProduction(), settings.AuthRateLimit, settings.TrustedProxies))
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user