만족
[Express] proxy 환경에서 클라이언트의 ip 확인하기 본문
[Express] proxy 환경에서 클라이언트의 ip 확인하기
Backend/Express Satisfaction 2022. 7. 17. 19:08결론만 보고싶다면 스크롤 맨밑으로 ㅎㅎ..
현재 apache+express 조합으로 서비스를 운영중이다.
client가 request를 보냈을 때 express project까지 도달하는 과정은 위와 같다.
그런데 express에서 req.ip 값을 확인하니,
전부 127.0.0.1로 찍혀 있었다.
왜 그럴까?
사실 express의 관점에서는
앞단에서 아파치가 프록시를 해주고 뭐고 그런건 관심없고
apache가 express에게 request를 보내는 것으로 인식된다.
따라서 자기 자신에게 포트 번호만 바꿔서 보내는 것으로 작동하므로,
요청 ip가 127.0.0.1로 찍히는 것이다.
req.ip
express의 req.ip는 어떻게 구현되어 있을까?
expressjs
https://github.com/expressjs/express/blob/master/lib/request.js
forwared
https://github.com/jshttp/forwarded/blob/af3830a175dbe316be3d943f505171c73853eb04/index.js#L46
proxy-addr
https://github.com/jshttp/proxy-addr/blob/master/index.js
코드를 살펴보면, proxyaddr이 리턴한 값을 req.ip로 취급한다.
proxyaddr()은 X-Forwarded-For값을 가져와서 reverse한 후
trust()에 순차적으로 넣는 것을 반복하여
가장 먼저 나오는 not-trustable ip 또는 마지막 ip를 리턴한다.
다시 req.ip 구현으로 돌아와보면
req.ip는 XFF에서 가장 나중에 나오는 not-trustable한 IP값이라고 할 수 있다.
(proxyaddr은 XFF를 reverse시키고 반복문에서 필터링한다는 것을 다시 상기하자)
XFF(X-Forwarded-For)
https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-Forwarded-For
XFF는 client와 거쳐온 proxy들의 ip를 포함하고 있는 헤더 값이다.
클라이언트에서 출발해서, proxy를 거칠 때마다 해당 proxy-ip가 뒤에 덧붙여진다.
위 그림에서처럼 client-> proxy1-> proxy2-> server를 거쳤을 때,
server가 받게 되는 XFF는 <client-ip, proxy1-ip, proxy2-ip>가 된다.
이 구조에서 express가 받게 되는 XFF는 <client-ip, server-ip>가 되는 것을 알 수 있다.
위에서 req.ip 구현에 대해 살펴보았듯 proxyaddr에서 XFF를 다룰 때
배열을 뒤집고, 가장 먼저 나오는 not-trustable ip를 리턴하므로
이 경우 <server-ip, client-ip> 에서 가장 먼저 나오는 ip인 server-ip가 req.ip로 결정된다.
trust proxy setting
이제 프록시 환경에서 왜 req.ip가 클라이언트 주소를 표시해주지 못하는지 알았다.
기본적으로 false로 설정되어 있어, req.ip는 XFF의 맨 마지막 IP를 리턴한다.
http://expressjs.com/en/4x/api.html#trust.proxy.options.table
우리가 원하는 것은 XFF의 첫 번째 아이피인 client-ip이다.
따라서 다양한 옵션 값들이 있지만, 우리는 client ip(XFF의 첫 번째 아이피)를 얻는 것이 목적이므로
trust proxy 값을 true로 설정해 준다.
// app.js
app.set('trust proxy', true);
이렇게 하면 모든 IP가 trustable하므로 XFF의 첫 번째 아이피(client-ip)가 req.ip값에 설정된다.
이제 로그에도 아이피가 정상적으로 찍힌다.
'Backend > Express' 카테고리의 다른 글
[Express] mongoose 로 쿼리할 때 lean을 이용해 메모리 사용량 줄이기 (0) | 2024.01.08 |
---|---|
[Express] forever로 배포한 서비스가 오류로 종료된 후 다시 시작되지 않는 현상 (0) | 2020.12.18 |
[Express] Apache와 연동해 배포하기 (0) | 2020.11.05 |
[Express] Response (res) (2) | 2020.06.28 |
[Express] Request (req) (0) | 2020.06.28 |