API 서버를 만들던 중 morgan 라이브러리를 사용하기 위해 클라이언트 IP를 받아올 필요가 있었다.
로그는 잘 나오는데 문제는 아래와 같이 localhost의 주소만 나온다는 것이다.
원인을 찾아보니 Nginx를 리버스 프록시로 설정해서 이런 문제가 발생했다.인터넷에 나온 정보들을 종합해서 Nginx 서버 블록을 재설정했다.
- proxy_set_header Host $host;
-> host 표시 (http or https)- proxy_set_header X-Real-IP $remote_addr;
-> 클라이언트 IP 표시- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
-> 거쳐온 모든 노드의 IP 표시
그리고 나서 header를 콘솔 로그로 출력 후 다시 API를 호출했는데
???
헤더에는 분명히 표시가 되는데 내 로깅에는 나오지 않는다.
혹시 로깅이 잘못 설정됐나 코드를 봤지만 아무리 봐도 이상 없었다.
대체 뭐가 문제인건가 하고 열심히 찾아봤다... 결국 알아낸건 Express 프레임워크 설정에 있었다.
프록시 환경에서 Express 앱은 기본값으로 req.connection.remoteAddress를 클라이언트 IP 주소로 받아온다. 직접 인터넷에 연결되어 있을 때는 문제 없지만, 지금 시스템처럼 Nginx를 리버스 프록시로 사용할 경우 리버스 프록시를 클라이언트로 등록되는 오류가 발생한다.
따라서 프록시 설정[1]을 해줘야 한다!
설정 방법은 app.set()을 하는 모듈에 들어가서 아래와 같이 프록시 설정을 해준다.
app.set('trust proxy', '127.0.0.1');
그리고 다시 서버를 재실행했더니
만족스럽게 잘 나온다!
리버스 프록시 환경일 때 Nginx 뿐만 아니라 사용하고 있는 서버도 확인해봐야 한다.
그리고 로드 밸런서를 적용하거나 서브넷 설정을 할 경우에는 진짜 클라이언트 IP만 오는게 맞는지 다시 확인해볼 필요가 있다.
끝!