본문 바로가기
일지/JAVA

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

by 닉닉눅 2023. 7. 17.
728x90
반응형

업무 중 한 업체로 부터 홈페이지의 관리자 페이지에 접속이 안된다고 연락이 왔습니다.

업체의 홈페이지는 관리자 페이지의 접속을 특정 IP로 제한하여 등록된 IP외에는 접근을 제한하고 있습니다.

원인은 접근하는 IP가 EX) 255.255.255.255 와 255.255.255.254 2개로 고정되어 들어오는 것이 문제 였습니다.

 

최근 홈페이지 서버를 클라우드로 전환하는 일이 있었으며 로드 밸런싱(LB, Load balancing) 기능이 포함되어 있습니다.

접속하는 IP를 확인해 보니 2개의 IP는 로드 밸런싱 쪽 IP로 확인이 되었으며, 접속 IP를 가져올 때 실제 클라이언트의 IP를 가져오는 것이 아닌 LB쪽 IP를 가져오는 것이 었습니다.

 

 

보통 다음과 같이 `HttpServletRequest` 클래스의 `getRemoteAddr()`를 사용하여 클라이언트의 IP를 가져오지만 프록시 서버를 거치거 로드 밸런싱을 통하면 HTTP 요청은 프록시 서버의 IP( 또는 로드 밸런싱 IP) 주소로 보낸 후 프록시 서버( 또는 로드 밸런싱 서버)는 요청을 실제 서버로 전달합니다. 따라서 getRemoteAddr() 함수는 프록시 서버의 IP ( 또는 로드 밸런싱 IP)주소를 반환하게 됩니다.

import javax.servlet.http.HttpServletRequest;

request.getRemoteAddr();

원인

Web Server에서 프록시나 로드 밸런서를 통해 WAS에 요청하기 때문에 프록시나 로드 밸런서의 IP 주소만을 담고 있습니다.

 

 

 


 

 

X-Forwarded-For (XFF) 헤더

 

X-Forwarded-For 헤더는 일반적으로 프록시 서버나 로드 밸런서에 의해 설정되며, IP 주소 목록을 포함합니다.

 

목록의 첫 번째 IP 주소는 클라이언트의 IP 주소이고, 후속 IP 주소는 클라이언트의 요청이 통과한 프록시 서버나 로드 밸런서의 IP 주소입니다.

 

X-Forwarded-For 헤더는 다양한 목적으로 사용될 수 있습니다. 예를 들어, 트래픽 소스를 추적하고, 보안을 위해 사용하고, 로드 밸런싱을 위해 사용할 수 있습니다.

 

사용예제

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    PrintWriter out = response.getWriter();

    String xForwardedFor = request.getHeader("X-Forwarded-For"); //X-Forwarded-For 헤더 가져오기
    if (xForwardedFor != null) { 	                      // X-Forwarded-For 헤더가 있을 경우
        out.println("X-Forwarded-For: " + xForwardedFor); // X-Forwarded-For 내용 출력
    } else {                                              // X-Forwarded-For 헤더가 없을 경우
        out.println("X-Forwarded-For: None");             // X-Forwarded-For : NONE 문자열 출력
    }

    out.println("Remote Address: " + request.getRemoteAddr()); // 요청을 보낸 클라이언트의 IP 주소 출력
}

 OR

public static String getClientIp(HttpServletRequest req) {
    String ip = req.getHeader("X-Forwarded-For");  // X-Forwarded-For헤더 가져오기
    if (ip == null) ip = req.getRemoteAddr();      // X-Forwarded-For헤더 없을 경우 
                                                  //getRemoteAddr() -> Remote Address가져오기
    return ip;      // ip 반환
}

코드 출처 : https://linked2ev.github.io/java/2019/05/22/JAVA-1.-java-get-clientIP/

 

IP를 가져오는 다양한 방법

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://linked2ev.github.io/java/2019/05/22/JAVA-1.-java-get-clientIP/

참고

 

https://linked2ev.github.io/java/2019/05/22/JAVA-1.-java-get-clientIP/

 

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

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

linked2ev.github.io

 

728x90
반응형

댓글