X-Forwarded-For를 이용해 Proxy 환경에서 Client 실제 IP 가져오기

Minu·2023년 10월 27일
1

네트워크

목록 보기
1/3

X-Forwarded-For란?

X-Forwarded-For (XFF) 헤더는 HTTP 프록시나 로드 밸런서를 통해 웹 서버에 접속하는 클라이언트의 원 IP 주소를 식별하는 사실상의 표준 헤더다. 클라이언트와 서버 중간에서 트래픽이 프록시나 로드 밸런서를 거치면, 서버 접근 로그에는 프록시나 로드 밸런서의 IP 주소만을 담고 있다. 클라이언트의 원 IP 주소를 보기위해 X-Forwarded-For 요청 헤더가 사용된다.


실제 배포중이던 서버 문제점

현재 배포중인 서버에서 500 에러가 발생하면 디스코드에 메세지를 전송하도록 했는데 ENDPOINT 가 서버 도메인이 아닌 localhost 로 나오고 IP 또한 로컬로 찍힌다. 또한 서버 log 를 봐도 해당 사진 처럼 모든 요청이 local 로 찍힌다.
로컬 개발환경에서는 IP 잘 찍혀서 배포 했는데..


원인

현재 내가 배포중인 서버 구성

AWS 에서 ubuntu 안에 프론트서버는 nginx, 백엔드 서버는 SpringBoot 로 배포중이다.

그림을보면 IP 가 200.100.10.2 인 클라이언트가 우리서버 도메인에 요청을 보내면 nginx 가 첫번째로 요청을 받게 되는데, nginx 클라이언트의 IP 와 우리 로컬서버의 IP로 이루어진다.
그리고 nginx 에서 springboot 로 클라이언트의 정보를 보낼 때, client 의 IP가 아닌 ProxyIP 가 springboot 로 전송이 되어 springboot 에서는 클라이언트가 요청 보낸 endpoint 와 ip 가 로컬로 찍혔던 것이다.


해결

이런 문제점을 극복하기 위해 프록시,로드 밸런서는 클라이언트의 IP를 X-Forwarded-For 헤더를 웹 요청에 추가할 수 있다.
X-Forwarded-For 헤더에는 Client-IP 와 Proxy,로드 밸런서 장비의 IP가 있다
(맨 왼쪽에 Client-IP,장비1 IP,장비2 IP...)

1. nginx proxy 설정

2. springBoot에서 X-Forwarded 헤더 가져오기

public static String getClientProxyIP(HttpServletRequest req) {
        String clientIP = req.getHeader("X-Forwarded-For");
        if (clientIP == null || clientIP.isEmpty()
            || "unknown".equalsIgnoreCase(clientIP)) {
            clientIP = req.getHeader("X-Real-IP");
        }
        if (clientIP == null || clientIP.isEmpty()
            || "unknown".equalsIgnoreCase(clientIP)) {
            clientIP = req.getRemoteAddr();
        }
        return clientIP;
    }

이렇게 해서

return clientIP // 실제 clientIP

proxy 정보가 아닌 실제 클라이언트의 IP 가 잘 찍혔다..!

정리

원래는 Spring 에서 HttpServlet.getRemoteAddr() 를 하면 클라이언트의 IP 를 가져왔지만, 윗 내용처럼 Proxy 정보를 가져오기 때문에 X-Forwarded 헤더에 있는 실제 ClientIP 를 가져왔다.

0개의 댓글

관련 채용 정보