From a056e1ba189665a8f1ff9c076ce94ac21f6151b5 Mon Sep 17 00:00:00 2001 From: Jiongxuan Zhang Date: Thu, 10 Oct 2024 23:13:28 +0800 Subject: [PATCH] feat(authentication): improve IP logging by extracting real client IP from X-Forwarded-For header - Added getRealRemoteIP function to retrieve the real client IP address when behind a reverse proxy. - Updated authentication logging to use the extracted IP instead of r.RemoteAddr. - Ensured compatibility for both proxy and non-proxy setups, falling back to r.RemoteAddr when X-Forwarded-For is not present. --- lib/handler.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/handler.go b/lib/handler.go index aef0238..dbc4a90 100644 --- a/lib/handler.go +++ b/lib/handler.go @@ -84,9 +84,12 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if len(h.users) > 0 { w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`) + // Retrieve the real client IP address using the updated helper function + remoteAddr := getRealRemoteIP(r) + // Gets the correct user for this request. username, password, ok := r.BasicAuth() - zap.L().Info("login attempt", zap.String("username", username), zap.String("remote_address", r.RemoteAddr)) + zap.L().Info("login attempt", zap.String("username", username), zap.String("remote_address", remoteAddr)) if !ok { http.Error(w, "Not authorized", http.StatusUnauthorized) return @@ -99,7 +102,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } if !h.noPassword && !user.checkPassword(password) { - zap.L().Info("invalid password", zap.String("username", username), zap.String("remote_address", r.RemoteAddr)) + zap.L().Info("invalid password", zap.String("username", username), zap.String("remote_address", remoteAddr)) http.Error(w, "Not authorized", http.StatusUnauthorized) return } @@ -159,6 +162,15 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { user.ServeHTTP(w, r) } +// getRealRemoteIP retrieves the client's actual IP address, considering reverse proxies. +func getRealRemoteIP(r *http.Request) string { + ip := r.Header.Get("X-Forwarded-For") + if ip == "" { + ip = r.RemoteAddr + } + return ip +} + type responseWriterNoBody struct { http.ResponseWriter }