From a4b69b00181963a9df1fc2de239a0eb6c5937dd7 Mon Sep 17 00:00:00 2001 From: Ruslan Date: Thu, 14 May 2026 07:41:51 +0000 Subject: [PATCH] Fix real IP: trust upstream forwardedHeaders in Traefik, use X-Forwarded-For[0] --- app/main.py | 6 ++---- traefik/traefik.yml | 10 ++++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/main.py b/app/main.py index f020ab8..e599a13 100644 --- a/app/main.py +++ b/app/main.py @@ -67,10 +67,7 @@ logger = logging.getLogger("portal") templates = Jinja2Templates(directory="templates") def _get_real_ip(request) -> str: - """Return real client IP. NPM sets X-Real-IP to the actual client IP.""" - real_ip = request.headers.get("x-real-ip", "").strip() - if real_ip: - return real_ip + """Real client IP from X-Forwarded-For (Traefik trusts NPM via trustedIPs).""" forwarded_for = request.headers.get("x-forwarded-for", "") if forwarded_for: return forwarded_for.split(",")[0].strip() @@ -494,6 +491,7 @@ async def request_access(request: Request, db: Session = Depends(get_db)): f"{products_text}" ) + log_event("ip_headers", xff=request.headers.get("x-forwarded-for","–"), xri=request.headers.get("x-real-ip","–"), client=str(request.client.host if request.client else "–")) ip = _get_real_ip(request) geo = _get_geo(ip) geo_text = "" diff --git a/traefik/traefik.yml b/traefik/traefik.yml index fd7ef21..d916428 100644 --- a/traefik/traefik.yml +++ b/traefik/traefik.yml @@ -1,8 +1,18 @@ entryPoints: web: address: ":80" + forwardedHeaders: + trustedIPs: + - "10.0.0.0/8" + - "172.16.0.0/12" + - "192.168.0.0/16" websecure: address: ":443" + forwardedHeaders: + trustedIPs: + - "10.0.0.0/8" + - "172.16.0.0/12" + - "192.168.0.0/16" providers: docker: