EC2에 HTTPS 적용하기 : 배포 중에 생긴 일

Miseon (MIMI)·2023년 11월 27일
0
post-thumbnail

🔖 개요

💡 'HTTPS에서 HTTP로의 요청은 불가능하다고?'
갈매기 프로젝트의 프론트엔드는 vercel로 배포되어 있다. vercel로 배포된 프로젝트는 기본적으로 HTTPS를 제공하지만, 우리가 구축한 AWS EC2 서버는 HTTP 상태이다. 그렇기에 HTTPS 클라이언트에서 HTTP 서버로 API 요청을 보내야 하는데, 아래와 같은 에러가 발생했다.

Mixed Content: The page at '<클라이언트>' was loaded over HTTPS, but requested an insecure resource '<서버>'. This request has been blocked; the content must be served over HTTPS.

배포 후 API 요청 중에 생기는 에러라고는 CORS 에러만 마주쳐봤는데, HTTPS to HTTP redirect 에러는 처음이었다. vercel로 배포한 프론트엔드를 건드릴 순 없으니, EC2에 HTTPS를 적용하는 작업을 해보기로 했다.

🔖 HTTPS에서 HTTP로의 요청

📍 왜 불가능한가?

브라우저에서는 보안상의 이유로 HTTPS에서 HTTP로의 요청이 허용되지 않는다. 기본적으로 HTTPS 통신에서는 암호화된 데이터가 오가도록 보안상으로 설계되어 있기에, 안전하지 않은 HTTP 요청이 제한될 수밖에 없다.

🔖 가비아 도메인 구입

📍 도메인 구입하기

기본적으로 웹사이트에 HTTPS를 적용하기 위해서는 도메인이 필요하다. 우리가 보유하고 있는 EC2에는 별도의 도메인이 존재하지 않으므로, 도메인을 구입해서 적용해주어야 한다.

https://www.gabia.com/

도메인 구매는 위와 같이 Gabia 웹사이트를 이용했다. 원하는 도메인을 입력하면 구매 가능한 도메인 목록이 나온다.

🔖 Route53에서 도메인 인증받기

📍 도메인 소유 인증

AWS의 Route 53에서는 내가 도메인을 소유하고 있음을 인증할 수 있는 서비스를 제공한다. 이 서비스를 이용하여 도메인 소유 인증을 해보겠다.

호스팅 영역을 생성한다. 도메인 이름에는 아까 구입한 도메인을 입력해 주고, 그 외에는 기본 설정으로 '호스팅 영역 생성'을 클릭한다

생성된 호스팅 영역의 레코드를 확인하면, 처음에는 'NS'와 'SOA' 유형만 존재한다. (필자는 이미 HTTPS 작업을 종료한 후에 캡쳐하여 다른 유형이 존재함)

다시 가비아로 돌아가서, 구입한 도메인 관리 페이지에 접속하여 4개의 네임서버를 확인해준다.

Route 53에서 아까 생성한 호스팅 영역 중 'NS' 유형의 레코드를 편집한다.
4개의 값에 4개의 네임서버를 각각 입력해준다.

여기까지 작업을 완료했다면, 가비아에서 구입했던 도메인이 내가 소유한 도메인임을 AWS가 알 수 있게 된다! 😎

🔖 Certificate Manager에서 SSL 인증서 발급받기

📍 ACM 인증서

본격적으로 HTTPS 적용을 위해서는 SSL 인증서가 필요하다. AWS의 Certificate Manager(ACM)에서 SSL 인증서를 발급받을 수 있다.

인증서 요청을 클릭하여 도메인 입력 후, 모두 기본 설정 상태로 인증서를 요청한다.

인증서 목록에서 발급받은 인증서를 확인할 수 있다.
인증서 ID를 클릭해준다.

'Route 53에서 레코드 생성'을 클릭하고, 도메인을 선택하여 '레코드 생성'을 해준다.

여기까지 작업을 완료했다면, 인증서의 상태가 '발급됨' 상태로 바뀌게 된다! 😎

🔖 Load Balancer를 이용한 HTTPS 리다이렉트

📍 Load Balancer란?

Load Balancer(로드 밸런서)는 네트워크 트래픽 또는 작업을 여러 대의 서버로 분산시켜주는 시스템을 말한다. 그렇기에 대표적인 장점으로는 부하 분산을 통한 서버 효율 향상이 있다.

AWS의 로드밸런서를 이용하면 여러 타겟 그룹을 생성하여 작업을 분산시킬 수 있다. 프로토콜 혹은 포트로 들어온 특정 요청을 인식하고, 이 요청을 어느 타겟으로 전달시킬지 지정할 수 있다.

그렇다면, 이러한 로드밸런서의 특징을 이용하여 두가지 규칙을 추가해둘 수 있다.

  1. HTTP 요청 -> 아래 HTTPS로 리다이렉트
    🌟 HTTPS로 리다이렉트된 EC2로 요청 가능!
  2. HTTPS 요청 -> HTTPS를 거쳐 로드밸런싱 -> 기존 HTTP 타겟 그룹(EC2)으로 전달
    🌟 본래 HTTP였던 EC2에 HTTPS를 거쳐 요청 가능!

📍 EC2 보안그룹 수정

로드밸런싱 작업 전에, 로드밸런싱을 적용할 EC2의 보안 그룹을 수정해주어야 한다.
보안그룹 ID를 클릭한다.

보안그룹의 '인바운드 규칙 편집'을 통해 위 사진에 체크된 것처럼 규칙을 추가해줘야 한다.

  1. IPv4, IPv6의 HTTPS TCP 443 허용
  2. IPv4, IPv6의 사용자 지정 TCP <HTTPS를 적용할 PORT> 허용
    (필자는 API 서버가 3004 포트에 열려있으므로 위와 같이 적용되어 있음)

📍 로드밸런싱 대상 그룹 생성

EC2 메뉴 중 '로드밸런싱 > 대상 그룹'을 클릭하여 대상 그룹을 생성한다.

포트는 HTTPS를 적용할 PORT로 입력하고, VPC는 EC2와 같은 VPC를 선택해주어야 한다.
등록할 인스턴스는 EC2를 선택하고, 포트는 HTTPS를 적용할 PORT로 지정하여 추가한다.
이 외에는 기본 설정으로 둔다.

📍 로드밸런서 생성

EC2 메뉴 중 '로드밸런싱 > 로드밸런서'를 클릭하여 'Application Load Balancer'로 로드밸런서를 생성한다. L7 로드밸런서에 해당한다.

EC2가 사용 중인 VPC를 선택하고, 매핑할 가용 영역은 EC2가 사용하는 VPC, 서브넷과 모두 일치해야 한다. 보안그룹도 EC2와 동일하게 지정한다.

생성된 로드밸런서의 리스너를 추가해주어야 한다.
'리스너 추가'를 클릭하여 HTTPS를 적용할 PORT를 HTTP로, 와 443 포트를 HTTPS로 지정하고
Foward to에는 아까 생성한 타겟 그룹을 지정해준다.
인증서는 ACM에서 생성한 인증서를 지정해준다.

📍 로드밸런서 리스너 규칙 추가

로드밸런서에 HTTPS를 적용할 PORT와 443 포트, 이렇게 두개의 리스너를 추가했었다.
이제 각 리스너에 규칙을 추가해주어야 한다.

HTTPS를 적용할 PORT의 규칙은 위와 같다. '호스트 헤더' 유형을 선택하고 도메인을 입력해주면 된다.

443 포트의 규칙은 기본값 규칙에서 대상 그룹만 수정해주면 된다. 생성했었던 대상 그룹으로 변경한 후, 저장해준다.

📍 A 레코드 생성

로드밸런서를 생성했으니, 이 로드밸런서(LB)를 호스팅 영역에 적용해주어야 한다

Route 53으로 돌아가 A 레코드를 생성한다.
'별칭' toggle을 on 상태로 변경하고, 'Application/Classic Load Balancer에 대한 별칭' 선택 후 생성한 LB를 지정해준다. (LB에 적용돼있는 가용 영역을 선택해주어야 목록에서 LB를 선택할 수 있다.)

📍 Healthy Check

대상 그룹에 지정된 포트로는 본인이 지정한 Healthy Check에 따라 요청을 지속적으로 보내게 된다. Healthy Check에 실패하면, 위 사진과 같이 Unhealthy 상태가 된다.
이 상태를 Health로 바꿔주어야 한다.

Healthy Check 설정을 기본값으로 두었다면, 위와 같을 것이다.
위 설정은 '/' 경로로 30초에 한번씩 요청을 보내는데, 5번 이상 응답이 200이라면 healthy 상태로 전환되는 방식이다.
따라서, EC2의 API에 '/' router를 추가하여 Healthy Check가 올바르게 이루어지도록 구성했다.
443 포트에 대해서는, 보안 그룹을 올바르게 지정해주었다면 보통 문제가 없을 것이다.
이 Healthy Check 방식은 편한 방법으로 바꾸어 주면 된다.

🔖 결론

Postman으로 HTTPS 도메인에 요청을 보내본 결과, 정상적으로 응답이 온다.
EC2에 HTTPS 적용하기 성공! 👏

profile
방황하는 개발자

0개의 댓글