업무 중 한 업체로 부터 홈페이지의 관리자 페이지에 접속이 안된다고 연락이 왔습니다.
업체의 홈페이지는 관리자 페이지의 접속을 특정 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
'일지 > JAVA' 카테고리의 다른 글
[JAVA] Spring Boot 3.0.X 버전 주의할 점(class file has wrong version 61.0, should be 52) (0) | 2023.05.11 |
---|---|
[JAVA] Spring 에러 : root-context.xml ( cvc-complex-type.2.3 ) (0) | 2023.02.16 |
[JavaScript] 얕은 복사, 깊은 복사 (0) | 2022.11.15 |
[JavaScript] 전개연산자 '...' (0) | 2022.11.15 |
댓글