[Java] 1. 클라이언트 실제 접속 IP 가져오기


클라이언트 실제 접속 IP 가져오기


X-Forwarded-For (XFF) 헤더


기본적으로 HttpServletRequest 객체 내 함수로 클라이언트 IP를 가져올 수 있다. 가끔 기존에 만들어진 어플리케이션이나 개발 하다 보면 아래와 같이 사용되는걸 볼 수 있다.

import javax.servlet.http.HttpServletRequest;

request.getRemoteAddr();

하지만 보안관련해서 방화벽이나 클라우드로 운영하는 경우 클라이언트의 원 IP주소를 가져올 수 없다.

클라이언트가 요청을 하면 Web Server에서 프록시나 로드 밸런서를 통해 WAS에 요청하기 때문에 프록시나 로드 밸런서의 IP 주소만을 담고 있다. 그래서 원 IP를 못가져오는 현상이 발생한다.

우선 아래와 같이 샘플코드 형식으로 작성하면 원IP를 대체로 가져올 수 있다.

public static String getClientIp(HttpServletRequest req) {
    String ip = req.getHeader("X-Forwarded-For");
    if (ip == null) ip = req.getRemoteAddr();
    return ip;
}

X-Forwarded-For (XFF) 헤더는 HTTP 프록시나 로드 밸런서를 통해 웹 서버에 접속하는
클라이언트의 원 IP 주소를 식별하는 표준 헤더로 쓰이고 있다. 그래서 프록시나 로드밸런스 등을 사용할 경우 Apache/Nginx에서 설정이 되어있다는 가정하에 클라이언트의 실제 접속 IP를 가져올 수 있다.



아마 프로젝트마다 서버 환경이나 프록시 등 중개서버가 다르기에 Util로 만들어 놓은 코드이다.

public static String getClientIP(HttpServletRequest request) {
    String ip = request.getHeader("X-Forwarded-For");
    logger.info("> X-FORWARDED-FOR : " + ip);

    if (ip == null) {
        ip = request.getHeader("Proxy-Client-IP");
        logger.info("> Proxy-Client-IP : " + ip);
    }
    if (ip == null) {
        ip = request.getHeader("WL-Proxy-Client-IP");
        logger.info(">  WL-Proxy-Client-IP : " + ip);
    }
    if (ip == null) {
        ip = request.getHeader("HTTP_CLIENT_IP");
        logger.info("> HTTP_CLIENT_IP : " + ip);
    }
    if (ip == null) {
        ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        logger.info("> HTTP_X_FORWARDED_FOR : " + ip);
    }
    if (ip == null) {
        ip = request.getRemoteAddr();
        logger.info("> getRemoteAddr : "+ip);
    }
    logger.info("> Result : IP Address : "+ip);

    return ip;
}

참고: https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/X-Forwarded-For
https://linked2ev.github.io/devlog/2019/07/21/WEB-What-is-X-Forwarded-For/