nginx real_ip_header 및 X-Forwarded-For가 잘못된 것 같습니다


58

HTTP 헤더의 위키 백과 설명 X-Forwarded-For은 다음과 같습니다.

X-Forwarded-For : client1, proxy1, proxy2, ...

지시문에 대한 nginx 문서는 real_ip_header다음과 같습니다.

이 지시문은 대체 IP 주소를 전송하는 데 사용되는 헤더 이름을 설정합니다.
X-Forwarded-For의 경우,이 모듈은 X-Forwarded-For 헤더 의 마지막 ip를 대체 용으로 사용합니다. [엠파 시스 광산]

이 두 가지 설명은 서로 상충되는 것 같습니다. 이 시나리오에서 X-Forwarded-For헤더는 정확히 설명 된대로 클라이언트의 "실제"IP 주소가 가장 왼쪽에있는 항목입니다. 마찬가지로 nginx의 동작은 가장 올바른 값 을 사용하는 것입니다. 이는 분명히 프록시 서버 중 하나 일뿐입니다.

나의 이해 X-Real-IP가되는 것입니다 가정 결정하는 데 사용되는 실제 - 클라이언트 IP 주소 하지 프록시를. 내가 누락되었거나 nginx의 버그입니까?

그리고 그 너머로 ? 의 정의에 표시된 것처럼 X-Real-IP헤더를 가장 왼쪽 값으로 표시하는 방법에 대한 제안 이 X-Forwarded-For있습니까?

답변:


95

여러 IP가 연결될 때 X-Forwarded-For 문제를 해결하는 열쇠는 최근에 도입 된 구성 옵션입니다 real_ip_recursive(nginx 1.2.1 및 1.3.0에 추가됨). 로부터 의 nginx의 realip 워드 프로세서 :

재귀 검색을 사용하는 경우 신뢰할 수있는 주소 중 하나와 일치하는 원래 클라이언트 주소가 요청 헤더 필드에 전송 된 신뢰할 수없는 마지막 주소로 바뀝니다.

nginx는 기본적으로 체인에서 마지막 IP 주소를 가져 왔습니다. 그것이 신뢰할 수있는 유일한 주소이기 때문입니다. 그러나 새로운 real_ip_recursive기능을 사용하고 여러 set_real_ip_from옵션을 사용하면 여러 개의 신뢰할 수있는 프록시를 정의 할 수 있으며 마지막으로 신뢰할 수없는 IP를 가져옵니다.

예를 들어이 구성을 사용하면

set_real_ip_from 127.0.0.1;
set_real_ip_from 192.168.2.1;
real_ip_header X-Forwarded-For;
real_ip_recursive on;

그리고 X-Forwarded-For 헤더는 다음과 같습니다.

X-Forwarded-For: 123.123.123.123, 192.168.2.1, 127.0.0.1

nginx는 이제 클라이언트의 IP 주소로 123.123.123.123을 선택합니다.

nginx가 가장 왼쪽의 IP 주소를 선택하지 않고 신뢰할 수있는 프록시를 명시 적으로 정의해야하는 이유는 쉬운 IP 스푸핑을 방지하기위한 것입니다.

클라이언트의 실제 IP 주소는 123.123.123.123입니다. 또한 클라이언트가 좋지 않다고 말하고 IP 주소를 스푸핑하려고합니다 11.11.11.11. 이 헤더가 이미있는 서버로 요청을 보냅니다.

X-Forwarded-For: 11.11.11.11

리버스 프록시는 단순히이 X-Forwarded-For 체인에 IP를 추가하기 때문에 nginx에 도달하면 다음과 같이 표시됩니다.

X-Forwarded-For: 11.11.11.11, 123.123.123.123, 192.168.2.1, 127.0.0.1

가장 왼쪽에있는 주소를 잡았다면 클라이언트가 자신의 IP 주소를 쉽게 스푸핑 할 수 있습니다. 그러나 위의 예제 nginx 설정을 사용하면 nginx는 마지막 두 주소 만 프록시로 신뢰합니다. 즉 123.123.123.123, 스푸핑 된 IP가 실제로 가장 왼쪽에 있지만 nginx가 IP 주소로 올바르게 선택 됩니다.


1
정말 고마워요, 정말 도움이되었습니다. 이것이 정답입니다.
José F. Romaniello

1
기본적으로 X-실시간 IP가 따라 것 같다 real_ip_header nginx.org/en/docs/http/ngx_http_realip_module.html 무작위 X-실시간 IP로 요청을 보낼 수는 악의적 인 사용자를 뜻하고는 REMOTE_ADDR $로 사용됩니다 nginx에서 (또한 응용 프로그램에 전달 될 수 있습니까)?
gansbrest

set_real_ip_from은 신뢰할 수있는 호스트를 제한하기 때문에 @gansbrest 아니요.
El Yobo

9

X-Forwarded-For헤더 의 파싱 은 실제로 nginx real_ip 모듈에 결함이 있습니다.

len = r->headers_in.x_forwarded_for->value.len;
ip = r->headers_in.x_forwarded_for->value.data;

for (p = ip + len - 1; p > ip; p--) {
  if (*p == ' ' || *p == ',') {
    p++;
    len -= p - ip;
    ip = p;
    break;
  }
}

헤더 문자열의 맨 오른쪽에서 시작하고 공백이나 쉼표가 보이면 IP 변수에서 공백이나 쉼표의 오른쪽 부분을 찾고 중지합니다. 따라서 가장 최근의 프록시 주소를 원래 클라이언트 주소로 취급합니다.

사양에 따라 잘 재생되지 않습니다. 이것은 RFC에서 명백히 명백한 용어로 설명하지 않을 위험이 있습니다.

따로 : Squid가 원래 정의한 형식에서 좋은 기본 소스를 찾기조차 어렵습니다. 문서를 살펴보면 순서가 확인됩니다. 가장 왼쪽은 원래 클라이언트이고 가장 오른쪽은 가장 최근의 추가입니다. 위키 백과 페이지에 [citation needed] 을 ( 를) 추가하고 싶은 마음이 듭니다 . 하나의 익명 편집 은 해당 주제에 대한 인터넷의 권한 인 것으로 보입니다.

가능하면 중간 프록시가 헤더 끝에 자신을 추가하지 않고 실제 클라이언트 주소로만 남겨 두도록 할 수 있습니까?


답장을 보내 주셔서 감사합니다, @Shane. 실제로, nginx에 도달하면 X-Forwarded-For이미 존재합니다. (올바른 클라이언트 IP 주소) nginx 자체가로드 밸런서 (이전 홉)의 IP 주소를 X-Forwarded-For헤더에 추가합니다. (아마도 "원격 주소"로 보이는 것을 추가하는 것) 단순히 그렇게하지 않았다면, X-Forwarded-For전처럼 헤더를 사용할 수있을 것 입니다. (최근에 nginx로 마이그레이션했습니다)
Kirk Woll

@ Kirk 따라서 nginx가 헤더를 가져올 때 원래 클라이언트의 주소입니까? 그러나 처리 할 때 연결 프록시 서버의 헤더에 추가됩니까? 추가하지는 않습니다. 헤더를 만질 때만 연결을 통해 다른 프록시에 연결을 보낼 때 proxy_pass뿐입니다 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;.
Shane Madden

심지어 W3C이 잘못을 얻을 : 자신의 문서는 "프록시가에 대한 요청의 개시제의 IP 주소를 추가해야합니다 상태 끝에 쉼표를에 X-전달-를 들어 HTTP 헤더 필드에 구분 된 목록", 그것은 명시해야 시작 .
Ian Kemp

3
@IanKemp, 아니오, 이 맞습니다. 프록시의 서버 측 에서 요청개시 자 (예 : TCP 요청)는 이전 프록시입니다 (있는 경우). 이전 프록시는 이미 X-Forwarded-For왼쪽에 원래 클라이언트 주소와 함께 추가 된 이전 프록시가 있는 헤더를 보냅니다 . 따라서 현재 서비스중인 프록시는 이전 프록시 (= 개시 자)를 해당 목록의 끝에 추가하고 이렇게 확장 된 X-Forwarded-For헤더를 다음 업스트림 홉에 제공합니다. 물론 그들은 더 분명한 표현을 선택할 수있었습니다.
blubberdiblub

5

X-Real-IP는 서버가 대화하는 실제 클라이언트 (서버의 "실제"클라이언트)의 IP 주소이며 프록시 연결의 경우 프록시 서버입니다. 이것이 X-Real-IP가 X-Forwarded-For 헤더의 마지막 IP를 포함하는 이유입니다.


1
알았어. 그러나 그것은 결코 유용한 정보가 아니다. 클라이언트의 원래 IP 주소를 얻고 싶습니다. 이는 중요하며 읽은 모든 내용에 따라 이러한 헤더의 목적입니다. 프록시 서버의 IP 주소를 알고 싶은 이유는 무엇입니까?
Kirk Woll

그것이 당신에게 유용하지 않으면 당신에게 도움이되지 않습니다. 아무도 당신이 X-Real-IP를 사용하도록 강요하지 않습니다. 응용 프로그램에서 사용자의 IP가 필요한 경우 응용 프로그램에서 X-Forwarded-For (X-Forwarded-를 설정하지 않은 프록시 (인터넷 보안 어플라이언스 / 방화벽)가 있으므로 항상 신뢰할 수있는 것은 아닙니다)를 구문 분석하십시오. 에 대한). nginx와 관련하여 X-Forwarded-For는 nginx의 클라이언트 인 마지막 항목 (X-Real-IP)을 제외하고는 클라이언트와 대화하지 않으므로 중요하지 않습니다. 당신이 필요하지 않은 경우 해제, 그것을 설정하지 않는, 또는 그냥 무시 : /
user558061

2
아니,이 무슨 뜻인지, 왜 것 X-Real-IP내 자신의 프록시 서버의 IP 주소를 반환 이제까지 유용?
Kirk Woll

대단하다. 이 정확한 정보를 찾고있었습니다. 프록시 서버에서 ncat 서버와 대화해야하므로 즉시 필요합니다.
Yugal Jindle
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.