- 사전 필요사항
- AWS CloudFront 설정
1. 메뉴
- AWS 웹 콘솔 -> CloudFront -> 대상 CloudFront ID(도메인에 맵핑된) -> Behaviors -> 해당 Behaviors 선택 -> Edit
2. Cache key and origin requests 영역 설정
1) Cache policy and origin request policy (recommended) 선택
2) Cache policy 를 CachingDisabled 로 설정
- CloudFront를 동적 컨텐츠 전송 목적과 위치정보 헤더 값등 필요 헤더를 획득할 목적이기 때문에
- 참고: https://aws.amazon.com/ko/cloudfront/dynamic-content/
- 참고: https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/using-managed-cache-policies.html
3) Origin request policy - optional 에 커스텀 policy추가해서 반영
- 샘플) CloudFront에서 추가되는 헤더를 모두 선택한 경우
- Java 샘플소스
/**
* 클라이언트 요청자의 IP를 가져옴(WAS 앞단에 로드밸런서 등이 존재할 수 있음을 감안한 메소드)
* - AWS CloudFront -> ALB(LB) -> Nginx-> 톰캣을 사용하는 케이스를 감안한 메소드
* - AWS CloudFront사용시 해당 헤더의 IP정보를 최우선으로 신뢰함(즉, IP를 얻어오는 순서에 의미가 있음)
* - 주의: Spring webflux는 해당 메소드를 사용불가(대신 ServerWebExchange exchange.getRequest().getRemoteAddress().getAddress().getHostAddress() 같은 메소드를 사용해야함)
*
* @param request HttpServletRequest
* @return
*/
public static String getClientIp(HttpServletRequest request) {
//참고 https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/using-cloudfront-headers.html#cloudfront-headers-viewer-location
//참고 https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/WhatsNew.html
final String awsCfAddress = request.getHeader("CloudFront-Viewer-Address"); //ex) 123.45.67.89:46532
if (StringUtils.isNotBlank(awsCfAddress)) {
log.trace("\nIP획득 출처: AWS CloudFront-Viewer-Address\n\t요청 http header => {}", HttpRequestUtil.getRequestHeaderToMap(request));
return awsCfAddress.split(":")[0].trim(); //구분자 :
}
//프록시 레이어를 감안한 XFF값
//TODO: XFF는 spoofed(속일 수 있음)가 가능하기 때문에 오른쪽부터 IP를 가져오도록 수정해야함. 이때 신뢰하는 프록시IP들은 제외하는 로직 작업도 필요 https://news.hada.io/topic?id=6098
//https://en.wikipedia.org/wiki/X-Forwarded-For
//https://blog.lael.be/post/8989
final String xForwardedFor = request.getHeader("X-Forwarded-For"); //ex) 123.456.78.99,15.162.1.11
if (StringUtils.isNotBlank(xForwardedFor)) {
log.trace("\nIP획득 출처: X-Forwarded-For\n\t요청 http header => {}", HttpRequestUtil.getRequestHeaderToMap(request));
return xForwardedFor.split(",")[0].trim(); //구분자 ,
}
final String realIp = request.getHeader("X-Real-IP"); //일반적으로는 인프라(프록시) 설정 들이 잘되어 있다면 다른 언어 및 프레임웤에서는 보안문제 때문에 Real IP가 XFF보다 우선순위 높음
if (StringUtils.isNotBlank(realIp)) {
log.trace("\nIP획득 출처: X-Real-IP\n\t요청 http header => {}", HttpRequestUtil.getRequestHeaderToMap(request));
return realIp;
}
log.trace("\nIP획득 출처: request.getRemoteAddr\n\t요청 http header => {}", HttpRequestUtil.getRequestHeaderToMap(request));
return request.getRemoteAddr();
}
'JAVA > Java 일반' 카테고리의 다른 글
java잡담: java virtual thread의 draft(2023/03/06 created) (0) | 2023.03.23 |
---|---|
java jjwt라이브러리를 이용한 알고리즘에 맞는 Secretkey 생성 (0) | 2023.03.17 |
apple in app purchase(IAP)를 API로 가져오기 (0) | 2022.09.08 |
java 11 vs 17 performance (0) | 2022.09.02 |
Java Optional에 대한 생각 (0) | 2022.07.12 |