Tagged: X-Forwarded-For

[번역] Nginx $proxy_add_x_forwarded_for and real_ip_header

이글은 다음의 글을 번역한 것입니다.

나는 대략 다음과 같은 구조로 Nginx 와 또 다른 프론트 로드 밸런서 뒤에 webapp 을 가지고 있다.

Client(a.a.a.a) -> LB(b.b.b.b) -> NGX(c.c.c.c) -> WEBAPP(d.d.d.d)

이것이 내 Nginx 설정의 일부다.

1. 로드 밸런서는 X-Forwarded-For 필드에 Client IP 를 추가 한다.

    2. Nginx 는 X-Forwarded-For 헤더에서 LB IP(b.b.b.b) 를 생략하고 Client 에 Real IP를 찾는데, $remote_addr 은 b.b.b.b 에서 a.a.a.a 로 변경되고 따라서 proxy_set_header X-Real-IP $remote_addr 은 맞는 설정이다. (내가 원하는 설정대로다.)

    그런데, Nginx 는 X-Forwarded-For 헤더를 b.b.b.b 대신에 a.a.a.a IP 로 바꾼다.

    3. WEBAPP 은 다음과 같은 헤더를 수신한다.

    내가 필요한 것은 먼저 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_forwarded_for를 설정한 다음 실제 IP를 검색하고 $remote_addr 값을 바꾸는 기능입니다.

    이 문제를 어떻게 해결해야 하는지 알려줄 사람?

    답1

     $proxy_add_x_forwarded_for 는 $http_x_forwarded_for,$remote_addr 와 동일하고 $remote_addr 값은 http_realip_module 을 사용될때에 변경됩니다. 그래서 당신은 그 헤더에서 마지막 Proxy 주소를 얻을 수 없습니다. nginx 설정은 선언적이기 때문에 지시어의 순서 변경은 영향을 주지 않습니다.

    http_realip_module 를 사용하면,  $realip_remote_addr 값은 (nginx >= 1.9.7)  오리지널 $remote_addr 처럼 사용될 수 있습니다. (역, $realip_remote_addr 은 Nginx 앞에 있는 서버에 IP, 여기서는 LB(b.b.b.b) 를 가리킨다) 따라서 다음과 같이 X-Forwarded-For 를 세팅할 수 있습니다.

    답2

    나도 같은 문제로 여기까지 왔는데, 이러한 현상은 real_ip_recursive on; 으로 발생된다는 결론을 내렸습니다. Nginx 의 공식문서에 다음과 같이 나옵니다.

    If recursive search is enabled, an original client address that matches one of the trusted addresses is replaced by the last non-trusted address sent in the request header field.

    당신은 b.b.b.b 를 신뢰하도록 만들었다. 그래서 기대했던 a.a.a.a, b.b.b.b 가 a.a.a.a, a.a.a.a 로 바뀐 것입니다. 다음의 소스가 나에게 확신을 주었다. https://serverfault.com/questions/314574/nginx-real-ip-header-and-x-forwarded-for-seems-wrong