EC2에 HTTPS 통신 붙이기
현재 백엔드 스프링부트의 테스트 서버를 배포중이다. 테스트용이기 때문에 일단 EC2에 띄워두긴 했는데 어쨋든 iOS와 통신을 위해선 HTTPS를 셋팅해둬야했다.
HTTPS 설정방법은 크게 두가지이다.
1. Spring Boot 에서 SSL 인증서 사용 (Self-signed 또는 Let's Encrypt 인증서 사용)
2. AWS ALB (Application Load Balancer) + ACM (AWS Certificate Manager) 사용
이번 프로젝트에서는 두번째 방법을 선택했다. 이유는 아래와 같다
1. Spring Boot 에서 SSL 인증서 사용 (Self-signed 또는 Let's Encrypt 인증서 사용)
01. Let's Encrypt 인증서 발급 (certbot certonly --standalone)
02. 인증서를 .p12 포맷으로 변환 (openssl pkcs12)
03. Spring Boot HTTPS 설정 (application.properties)
04. EC2 보안 그룹에서 443 포트 열기
05. Spring Boot HTTPS 실행 (java -jar ...)
06. 인증서 자동 갱신 설정 (certbot renew --quiet && systemctl restart)
이와 같은 방법은 Spring Boot에서 내장 Tomcat을 활용해 직접 HTTPS(SSL/TLS)를 적용하는 방법으로 가장 큰 장점은 "공짜"다. 하지만 단점이 너무 치명적인데 TLS 암호화/복호화를 톰캣이 직접 처리하다보니 01. 트래픽이 많아지면 EC2가 부하를 견디질 못하고 02. 더 큰 문제점은 로드밸런싱이 힘들어진다.
01. 트래픽이 많아지면 EC2가 부하를 못견딤
🔹 일반적인 HTTP 요청 처리 과정 (부하가 적음)
클라이언트 → 서버 (EC2)
├─> 요청: HTTP(80) 평문 전송
├─> 서버에서 요청을 받고, 바로 응답 생성
├─> 응답: HTTP(80) 평문 응답
🔹 HTTPS 요청 처리 과정 (부하가 큼)
클라이언트 → 서버 (EC2)
├─> TLS 핸드셰이크 (비용 ↑)
├─> 요청 데이터 암호화 (비용 ↑)
├─> 서버에서 암호화된 데이터를 복호화 (비용 ↑)
├─> 응답 데이터 암호화 후 전송 (비용 ↑)
02. 더 큰 문제점은 로드밸런싱이 힘들어짐
클라이언트가 HTTPS(443)로 서버에 연결할 때, TLS 핸드셰이크(TLS Handshake) 과정이 필요하다. 이 때 암호화방식을 유지하기위해 비대칭키 방식으로 연결을 암호화하게 되는데 그 과정을 요약하면 아래와 같다.
1️⃣ 클라이언트 → 서버: "TLS 연결을 시작하자" (Client Hello)
2️⃣ 서버 → 클라이언트: "좋아, 이 암호화 키를 사용하자" (Server Hello + Certificate)
3️⃣ 클라이언트 ↔ 서버: 서로 공개 키를 주고받고, 암호화된 세션 키를 생성
4️⃣ 이후 모든 요청은 세션 키를 이용한 암호화 통신
이러한 일련의 과정을 동일한 서버를 로드밸런싱할 때 동일한 TLS핸드셰이크를 매번 중복해서 하게된다.
또한 모든 EC2가 똑같은 암복호화 작업을 톰캣내에서 하게되어 불필요한 CPU 리소스 마저 낭비되게 되어 이와같은 HTTPS 셋팅방법은 프로덕션 환경에선 잘 쓰이지 않는다.
2. AWS ALB (Application Load Balancer) + ACM (AWS Certificate Manager) 사용
약간의 비용을 지불하고 AWS ALB를 사용하면 위와 같은 문제를 해결할 수 있다. AWS ALB가 앞단에서 TLS핸드셰이크를 처리해주고 실제 EC2 서버로 보낼 땐 단순히 http요청을 보냄으로써 불필요한 암복호화 중복 작업을 생략할 수 있다. 구체적인 셋팅 방법은 아래와 같다.
시작하기 앞서 HTTPS 셋팅을 설명할 것이기 때문에 이전에 이미 EC2에 스프링부트 백엔드를 배포한 상태임을 가정했다!
1. Route53에서 도메인 셋팅
2. AWS ACM에서 SSL 인증서 발급
3. AWS ALB(Application Load Balancer) 생성 및 HTTPS 설정
4. 기존 EC2 보안 그룹 수정
5. 스프링부트에서 HTTP -> HTTPS 자동 리디렉션 설정
6. HTTPS 적용확인