Daylogs/Nginx

X-Forwared-For 헤더에서 실제 요청 IP 판단하기

ohgyun 2017. 7. 28. 09:58
발생일: 2017.01.05

키워드: AWS ELB, x-forwarded-for, IP 스푸핑, IP Spoofing

문제:
우린 앱서버로 node.js의 express를 사용한다.
express 로그에서 요청 IP를 파악할 땐, X-Forwarded-For 헤더의 값을 참조한다.

헌데, 로그를 살펴보니 X-Forwarded-For 헤더에 예상했던 것보다 많은 IP가 포함되어 있는 경우가 있다.
프록시를 여러 번 걸쳐 들어온 것 같은 요청도 있고, IP 스푸핑으로 보이는 것들도 있다.

X-Forwarded-For 헤더의 여러 IP 중에서 어떤 걸 진짜 사용자의 IP라고 보면 될까?


해결책:

우리는 express 서버 앞 단에 AWS ELB(엘라스틱 로드밸런서)와 nginx를 뒀다.

Client -> ELB -> nginx -> express 순이다.

로드밸런서는 X-Forwared-For 헤더에 클라이언트의 IP를 담아 전달한다.
요청에 이미 X-Forwarded-For 헤더가 있다면, 아래처럼 뒤에 덧붙인다.

X-Forwarded-For: ip-address-1, ip-address-2, client-ip-address


nginx는 리버스 프록시할 때, X-Forwarded-For 헤더에 특정 값을 할당할 수 있다.
우린 아래처럼 `$proxy_add_x_forwarded_for`로 설정해뒀는데, 이 땐 nginx의 IP를 헤더에 덧붙인다.

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

값을 `$remote_addr`로 설정했다면, nginx client의 IP만 할당한다.


따라서, 로드밸런서와 nginx를 타고 들어온 요청의 X-Forwarded-For 헤더는 아래와 같다.

X-Forwarded-For: client-ip-address, nginx-ip-address

요청에 이미 X-Forwarded-For 헤더가 있었다면, 아래처럼 구성된다.

X-Forwarded-For: ip-address-1, ip-address-2, client-ip-address, nginx-ip-address


각 서비스의 환경에 따라 다르겠지만, 우린 리버스 프록시하는 nginx의 IP를 제외한 마지막 IP가 클라이언트 IP라고 판단했다.


참고:
반응형