From 35bff424f189a9c8199b04e8e1b8a0d834b71bc9 Mon Sep 17 00:00:00 2001 From: Mikhail Romanko Date: Wed, 21 Oct 2026 20:37:48 +0300 Subject: [PATCH] Fix internal nginx config --- docker/nginx.conf | 13 +++++++------ frontend/nginx.conf.example | 11 ++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/docker/nginx.conf b/docker/nginx.conf index 40f9a17..796a4c8 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -23,17 +23,18 @@ server { # Proxy the API to the Go backend running alongside nginx. # - # X-Forwarded-For is set to $remote_addr (the peer nginx actually saw), NOT - # $proxy_add_x_forwarded_for. The latter appends to any client-supplied - # header, which would let a client spoof its own IP since the backend trusts - # the leftmost value. If you deploy behind another trusted proxy, switch to - # $proxy_add_x_forwarded_for and make the backend read the correct hop. + # This nginx normally sits behind a parent (SSL-terminating) proxy, so the + # parent has already resolved the real client IP into X-Forwarded-For. + # Appending with $proxy_add_x_forwarded_for preserves that first entry, which + # is what the backend reads (auth.ExtractIP uses the leftmost value). + # Do NOT use $remote_addr here: it would replace the parent's header with the + # parent's own address (e.g. the Docker bridge gateway 172.20.0.1). location /api/ { proxy_pass http://${BACKEND_HOST}:${BACKEND_PORT}; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } diff --git a/frontend/nginx.conf.example b/frontend/nginx.conf.example index 5161ff8..3ed0c99 100644 --- a/frontend/nginx.conf.example +++ b/frontend/nginx.conf.example @@ -27,16 +27,17 @@ server { # Reverse proxy the API to the Go service. Keeping the same origin means # the session cookie (SameSite=Lax) and CSRF cookie work without CORS. # - # X-Forwarded-For uses $remote_addr (the immediate peer) so a client cannot - # spoof its recorded session IP; the backend trusts the leftmost value. If - # this nginx sits behind another trusted proxy, use $proxy_add_x_forwarded_for - # and make the backend read the appropriate hop instead. + # $proxy_add_x_forwarded_for appends the immediate peer to X-Forwarded-For, + # so when a parent proxy resolves the real client IP first, the backend + # (which reads the leftmost value) still sees it. Only switch to $remote_addr + # if this nginx is the outermost/edge proxy and you want to reject + # client-supplied X-Forwarded-For. location /api/ { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } }