Files
document-haness/docs/clean-architecture-backend-template/tech-log-studio/duplicate-mechanisms/case/case-trust-policy-lives-in-nginx-not-in-the-code.md
T

107 lines
5.9 KiB
Markdown

---
kind: CASE
slug: trust-policy-lives-in-nginx-not-in-the-code
title: 테스트 Nginx 설정은 forwarded 헤더를 교체하지만 운영 경로는 확인하지 않았다
topic: duplicate-mechanisms
project: clean-architecture-backend-template
status: 게시 전
sourceRevision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916
rootTreeNode: case:trust-policy-lives-in-nginx-not-in-the-code
evidenceCapturedOn: 2026-09-01
assets:
- key: trust-policy-lives-in-nginx-not-in-the-code
file: ../../../final/evidence/rendered/trust-policy-lives-in-nginx-not-in-the-code.svg
evidence:
- ../../../final/evidence/raw/trust-policy-lives-in-nginx-not-in-the-code.txt
source:
- 원본 분석 절은 final/document.md#3-1 · final/document.md#a14 §32.2 이다.
---
# 테스트 Nginx 설정은 forwarded 헤더를 교체하지만 운영 경로는 확인하지 않았다
웹 리프의 프록시 패키지는 421줄로 신뢰 프록시 정책과 헤더 정화기와 정규화 타입을 갖는다. 이번 evidence에서 확인한 `nginxProxyTest` 설정은 들어온 forwarded 헤더를 authoritative value로 교체한다. 이 테스트 설정이 실제 운영 배포의 trust boundary인지까지는 확인하지 않았다.
## 관계
- **중복 장치를 찾으면 어느 쪽이 조립됐는지 먼저 확인한다**
이 사례가 그 규칙의 인프라 판이다.
- **요청 식별자를 클라이언트가 고를 수 없다는 정책이 다른 필터에서 뒤집힌다**
같은 웹 리프에서 Java 정책과 프록시 설정이 중복되어 실제 신뢰 경계를 어느 쪽이 결정하는지 다시 확인해야 했다.
## 문제
웹 리프의 프록시 패키지는 네 파일로 421 줄이다.
TrustedProxyPolicy 161 줄
NormalizedForwardedHeaders 158 줄
ForwardedHeaderSanitizer 72 줄
UntrustedForwardedHeaderException 30 줄
이 코드는 신뢰할 프록시를 판정하고 forwarded 헤더를 정규화한다.
문제는 이것이 실제 판정 경로인가다.
## 결론
확인한 테스트용 Nginx 설정은 Java 앞단에서 forwarded 헤더를 교체한다.
프록시 헤더 설정 파일의 주석은 이 파일을 forwarded 헤더의 authoritative 설정으로 두고 모든 location에서 include하도록 요구한다.
설정 내용은 교체다.
Host 를 host 변수로 설정
X-Real-IP 를 remote_addr 로 설정
X-Forwarded-For 를 remote_addr 로 설정
X-Forwarded-Host 를 이 배포의 공개 이름으로 설정
주석이 모든 줄이 SET 이고 ADD 가 아니라고 못 박는다. 클라이언트가 보낸 X-Forwarded-For 는 remote_addr 로 교체되고 X-Forwarded-Host 는 이 배포의 공개 이름으로 교체된다.
이 테스트 구성에서는 애플리케이션에 도달하기 전에 forwarded 헤더가 교체된다. 하지만 운영 배포가 같은 설정을 사용한다는 evidence는 없으므로 실제 운영에서 Java 정책이 불필요하다고 단정하지 않는다.
Java 쪽 참조 수도 그것과 맞는다.
ForwardedHeaderSanitizer : main 참조 0
TrustedProxyPolicy : main 참조 1, test 참조 2
UntrustedForwardedHeaderException : main 참조 1, test 참조 1
NormalizedForwardedHeaders : main 참조 2
같은 설정 파일의 주석은 Nginx 배열 지시어가 병합되지 않고 교체되기 때문에 include 방식을 쓴다고 설명한다. location 안에서 `proxy_set_header`를 하나라도 다시 선언하면 server 수준에서 상속받던 같은 계열 지시어를 잃을 수 있다. 따라서 forwarded 헤더 설정을 location마다 부분적으로 재정의하면 애플리케이션이 받는 신뢰 입력이 달라질 수 있다.
이 테스트 설정이 운영에서도 trust boundary라면 인프라 설정 실수가 애플리케이션이 받는 forwarded 헤더 의미를 바꿀 수 있다. 다만 이번 searched direct-reference evidence만으로는 운영 시 fallback이 될 Java trust policy의 실제 framework/lifecycle wiring을 확정하지 못했다.
## 검증 환경
Nginx 설정 : 웹 리프의 nginxProxyTest 소스셋 아래 proxy_headers.conf
확인 방식 : 파일 LOC 계수와 타입별 참조 계수, 설정 파일 대조
소스 수정 : x
## 재현 조건
1. 웹 리프의 proxy 패키지 파일과 줄 수를 센다. 네 파일 421 줄이다.
2. 각 타입의 main 참조와 test 참조를 센다.
3. Nginx 프록시 헤더 설정을 읽는다. 모든 지시어가 SET 이다.
4. 그 설정의 주석에서 include 방식을 택한 이유를 읽는다.
## 본문
<!-- body:start -->
forwarded 헤더를 다루는 Java 정책이 421 LOC 있고 searched direct reference 기준으로 사용 지점이 매우 적다. 별도로 `nginxProxyTest` 설정은 forwarded 헤더를 authoritative value로 교체한다. 두 사실을 확인했지만 이 테스트 설정이 운영 배포의 실제 trust boundary인지와 Java 정책의 모든 framework/lifecycle wiring 부재까지는 확인하지 않았다.
## 판정을 실제로 하는 곳
:::evidence key="trust-policy-lives-in-nginx-not-in-the-code" alt="분석 문서 final/document.md 에서 이 기록의 근거 절을 그대로 잘라낸 18줄. 코드베이스를 측정한 것이 아니라 원본 판정이 무엇을 적었는지를 보여 준다." caption="final/document.md 발췌 — 18줄" zoom="true"
:::
## Java 코드와 프록시 설정을 함께 봐야 한다
운영 배포가 이 프록시 설정을 실제로 사용한다면 Java 코드만 검토해서는 forwarded 헤더 교체 정책을 검증할 수 없다. 반대로 운영 설정을 확인하지 않은 상태에서는 Java 변경이 동작에 영향을 주지 않는다고 단정할 수도 없다.
## 확인하지 못한 것
이 Nginx 설정이 실제 배포에서 쓰이는 설정과 같은지 확인하지 않았다. 확인한 파일은 웹 리프의 테스트 소스셋 아래에 있다. 별도로 인프라 디렉터리에 파일서버용 Nginx 설정이 있고 그것은 다른 파일이다.
Java 정책이 어떤 경로에서 호출되는지 그 한 건씩의 참조를 추적하지 않았다.
<!-- body:end -->