Прокси-заголовки: не доверять произвольному X-Forwarded-For

entrypoint.sh: --forwarded-allow-ips сужен с "*" до loopback + приватных сетей
compose (переопределяемо FORWARDED_ALLOW_IPS) — uvicorn сканирует XFF справа и
берёт реальный адрес, подставленное клиентом левое значение игнорируется.
Caddyfile: reverse_proxy перезаписывает X-Forwarded-For реальным пиром
(header_up {remote_host}) вместо добавления. Итог — достоверный IP для throttle
и аудита. Инфра-часть проверяется на test-клоне. #58

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XfTsytzT6TojfmprRDKiV6
This commit is contained in:
2026-09-13 17:21:27 +03:00
co-authored by Claude Opus 4.8
parent ce7fbad58e
commit ec65f104ee
2 changed files with 24 additions and 5 deletions
+14 -3
View File
@@ -5,8 +5,13 @@
# forbidden-stars.ru → 127.0.0.1:9001 ← ПК (по требованию) DEV/TEST
#
# Caddy сам терминирует TLS (он и есть edge: видит реального клиента), а вниз к
# приложению добавляет X-Forwarded-Proto=https / X-Forwarded-For / Host —
# приложению передаёт X-Forwarded-Proto=https / X-Forwarded-For / Host —
# приложение это учитывает (uvicorn --proxy-headers). Положи файл в /etc/caddy/Caddyfile.
#
# X-Forwarded-For ПЕРЕЗАПИСЫВАЕМ реальным пиром (header_up ... {remote_host}), а не
# добавляем: иначе клиент мог бы подставить своё левое значение и подменить IP для
# throttle и аудита (#58). Вместе с сужением forwarded-allow-ips в entrypoint.sh это
# делает клиентский IP достоверным.
# Сертификаты — см. deploy/vps/README.md (fullchain = leaf + промежуточные одним файлом).
#
# SSE (/api/events): отдельный handle БЕЗ encode и с flush_interval -1 — иначе сжатие/
@@ -65,11 +70,14 @@ forbiddenstars.ru {
handle @sse {
reverse_proxy 127.0.0.1:9000 {
flush_interval -1
header_up X-Forwarded-For {remote_host}
}
}
handle {
encode zstd gzip
reverse_proxy 127.0.0.1:9000
reverse_proxy 127.0.0.1:9000 {
header_up X-Forwarded-For {remote_host}
}
}
import edge
}
@@ -80,11 +88,14 @@ forbidden-stars.ru {
handle @sse {
reverse_proxy 127.0.0.1:9001 {
flush_interval -1
header_up X-Forwarded-For {remote_host}
}
}
handle {
encode zstd gzip
reverse_proxy 127.0.0.1:9001
reverse_proxy 127.0.0.1:9001 {
header_up X-Forwarded-For {remote_host}
}
}
import edge
}