uncategorized

AWS Elastic Beanstalk에서 HTTPS 적용하기

문제 상황

광운대학교 미디어 기자재 대여 웹 서비스 프로젝트에서 AWS Elastic Beanstalk(이하 EBS)를 활용해 CICD를 구현했다. 문제는 EBS를 활용한 인프라에서 HTTPS 프로토콜을 적용해야 하는 상황에서 발생했다. 우리 서비스의 EBS는 새 버전을 배포할 때 새로운 EC2를 생성해서 빌드된 파일을 배포하도록 했다. 보통 HTTPS 프로토콜은 서버 측에 인증서가 저장되어 있어야 한다. 매번 새로운 EC2를 생성하는 현 방식에서는 어떻게 매번 새롭게 서버(EC2)에 인증서를 설치해야 하는 걸까? 그리고 꼭 그래야 할까? 다른 방법은 없는 걸까?

요구 사항

프론트에서 HTTPS로 백엔드와 통신해야 한다. 왜냐면 쿠키로 JSESSIONID를 주고 받아야 하는데 다른 오리진에서 설정한 쿠키가 요청에 포함되어 전달되려면 SAME-SITE=NONE, SECURE=TRUE이 설정되어야 한다. 이때 SECURE=TRUE로 설정하기 위해서는 HTTPS가 적용되어야 한다. 즉 백엔드에서 설정한 쿠키를 활용하기 위해서 프론트와 백엔드는 HTTPS로 통신해야 한다.

쿠키의 SameSite 속성

쿠키가 어떤 상황에서만 전송될 수 있는지를 지정한다. CSRF와 쿠키를 통한 정보 유출을 막기 위해 도입됐다.

다음 값으로 SameSite를 설정한 쿠키는 특정 조건에 만족해야만 함께 전송된다.

  1. Strict : 현재 사이트와 동일한 출처(오리진)로 요청할 때만 쿠키가 전송된다.
  2. Lax(기본값) : 현재 사이트에서 다른 오리진의 이미지를 로드하는 요청과 같은 경우에는 쿠키를 포함하지 않되, 현재 사이트에서 다른 링크로 이어지는 경우에는 요청에 포함된다.
  3. None : 동일한 출처가 아니더라도 쿠키가 함께 전송된다. 이 경우에는 Secure가 포함되어야 한다.(즉, HTTPS가 적용되어야 한다.)

문제 해결

일단 AWS 공식문서에 내가 하고 있는 고민에 대해 설명하고 있다.

Configuring HTTPS for your Elastic Beanstalk environment

위 문서에 따르면 EBS 환경에 가장 쉽게 HTTPS를 사용하는 방법은 로드밸런서에 서버 인증서를 할당하는 것이라 한다. EBS는 로드밸런서가 일종의 프록시처럼 백엔드의 서버 인스턴스들을 프론트엔드에 노출시키지 않고 소통한다. 즉 프론트엔드와 백엔드가 HTTPS 통신하려면 로드밸런서에 서버 인증서를 할당하여 프론트엔드와 HTTPS 통신하도록 하고, 로드밸런서 뒷편의 EC2들은 HTTP로 통신함으로써 서버 인스턴스에 추가적인 설정을 하지 않아도 요구사항을 충족할 수 있게 된다.

로드밸런서에 서버 인증서를 할당할 때는 AWS Certificate Manager를 활용하는 것이 쉽다. ACM은 AWS 서비스 및 연결된 리소스에 SSL/TLS 인증서를 관리해주는 서비스다. AWS의 리소스를 사용하고 있다면 별도의 비용을 지불하지 않고도 쉽게 인증서를 발급받아 사용할 수 있다.

실습

도메인 레코드 설정하기

나는 kwmedialab.com을 가비아를 통해 구입해놨었다. 이제 프론트가 백엔드와 통신할 도메인을 도메인 레코드를 통해 추가해본다.

여기서 CNAME 타입으로 백엔드 도메인을 서브 도메인으로 추가했다. 값/위치에 실제 연결되는 주소를 적어주면 된다. 우리의 경우는 EBS 환경의 주소를 넣어주면 된다. (참고로 EBS 환경의 주소는 로드밸런서 주소의 도메인 주소이다.)

ACM을 통해 인증서 발급하기


ACM을 들어가면 다음과 같이 인증서 요청 버튼이 있다. 눌러준다.


인증서 유형은 퍼블릭 인증서를 요청한다.


완전히 정규화된 도메인 이름(즉 우리의 경우에는 back-dev.kwmedialab.com)을 입력해주고 아래는 사진과 동일하게 한다.
검증이 이뤄지고 나면 인증서 발급된다.

로드밸런서에 인증서 할당하고 포트 포워딩 설정

이제 ACM에서 만든 인증서를 로드밸런서에 설정하고 포트 포워딩하도록 하자.
EBS의 환경에서 구성 -> 인스턴스 트래픽 및 크기 조정 구성 -> 리스너 로 가서 리스너를 추가하면 된다. HTTPS의 443포트로 HTTPS 프로토콜로 설정하고 SSL 인증서를 우리가 ACM에서 만든 인증서를 할당하면 된다.

이렇게 설정하고 https://{완전히 정규화된 도메인 주소}로 요청을 보내서 정상 작동을 확인하면 끝난다!

더 나아가기

현재의 방식은 주어진 요구 사항을 해결하기 위한 솔루션이다. 프론트엔드에서 백엔드의 로드밸런서까지만 HTTPS 통신할 수 있고 로드밸런서부터 서버 인스턴스까지는 HTTP 통신을 한다.

만약 서버 인스턴스까지 HTTP 통신을 하려면 인증서를 로드 밸런서가 아닌 EC2 서버에 할당해야 한다. 이 경우에는 EBS에서 procfile을 통해 매번 EC2가 새롭게 실행될 때마다 터미널에 실행할 명령어를 적어줄 수 있다. procfile을 통해 새 EC2에 인증서를 설치할 수 있다.

다만 이 솔루션은 배포 과정에서 인증서 설치 과정이 포함된다. 그래서 배포 시간이 더 길어질 수 있다.

Share