EC2에 HTTPS 적용하기

변현섭·2023년 8월 15일
11
post-thumbnail

사실 예전 포스팅에서 HTTPS 적용방법에 대해 다루기는 하였으나, 여기에는 문제점이 하나 있습니다.
>> HTTPS 적용하기
도메인만 입력한 경우에 대해서는 https가 잘 적용되지만 API의 엔드포인트와 결합되는 순간 https 적용이 안 된다는 것입니다. 그래서 이번 포스팅에서는 조금 더 실질적인 방법으로, EC2에 HTTPS를 적용하는 방법에 대해 알아보기로 하겠습니다.

1. 가비아에서 도메인 구매하기

실습을 진행하기 위해선 본인만의 도메인이 있어야 한다. 도메인 구매 방법에 대해서는 이전에 다루었기 때문에 여기서는 생략하기로 한다.
>> 가비아 도메인 구매하기

2. 도메인 인증하기

① AWS Management Console에 접속한 후 Route 53 서비스로 이동한다.

② 좌측 메뉴 > 호스팅 영역 > 호스팅 영역 생성 버튼을 클릭한다.

③ 도메인 이름만 입력하고, 나머지는 기본 값을 유지한 채 호스팅 영역을 생성한다.

④ 호스팅 영역 이름을 클릭한다.

⑤ 레코드 생성 버튼을 클릭한다.

⑥ 값 부분에만 본인의 EC2 Public IP를 넣으면 된다.

⑦ NS 유형에 해당하는 값/트래픽 라우팅 대상이 4개 생긴 것을 알 수 있다.

3. 가비아 네임서버 설정 변경하기

① 가비아 홈페이지에 접속한 후, My가비아 > 서비스 관리 > 도메인 통합 관리툴을 클릭한다.

② 좌측 메뉴 > 도메인 정보 변경 > 도메인 명을 클릭한다. 스크롤을 내려 네임서버 설정 버튼을 클릭한다.

③ Route 53에서 확인한 NS 유형에 해당하는 값/트래픽 라우팅 대상에 적혀있던 4개의 주소를 네임서버 1~4차에 차례대로 입력한다. 입력할 때에는 반드시 마지막의 .은 빼고 입력해야 한다.

4. ACM(AWS Certificate Manager)

① AWS Certificate Manager에 들어와 인증서 요청 버튼을 클릭한다.

② 퍼블릭 인증서 요청을 선택한다.

③ 완전히 정규화된 도메인 이름에는 본인의 도메인을 입력하면 된다. *.은 선택사항이다.

④ 검증 버튼을 클릭한다. 그 후 인증서 ID를 클릭한다.

⑤ Route 53에서 레코드 생성 버튼을 클릭한다.

⑥ Route 53에 등록된 본인의 도메인에 아래와 같이 CNAME 값이 값/트래픽 라우팅 대상에 등록되면 완료된 것이다.

⑦ 10분 정도 지나야 아래와 같이 발급이 완료된다.

5. 로드밸런서 생성하기

한 대의 EC2만 사용할 예정이어도, https를 적용하려면 로드밸런서가 필요하다.

1) 대상 그룹 생성하기

① EC2에 들어간 후 좌측 메뉴 > 로드 밸런싱 > 대상 그룹 > 대상 그룹 생성 버튼을 클릭한다.

② 아래와 같이 설정한 후 생성 버튼을 클릭한다.

③ 대상 그룹 메뉴로 돌아와서 편집 버튼을 클릭한다.

④ 본인의 EC2 인스턴스를 선택 후 등록된 항목에 추가 버튼을 클릭하고 저장한다.

⑤ 인스턴스의 상태가 unhealthy로 뜰 경우, 아래와 같이 HTTP status 200을 반환하는 임의의 api를 만들어 서버에 올려주어야 한다. 대상 그룹 이름에 우클릭 > 상태 검사 편집을 클릭한 후 경로에 /healthcheck를 넣어주어야 한다.

  • 아무 Controller에나 아래의 코드를 추가하면 된다.
@GetMapping("/healthcheck")
public String healthcheck() {
	return "OK";
}

2) 로드밸런서 생성하기

① EC2에 들어간 후 좌측 메뉴 > 로드 밸런싱 > 로드밸런서 생성 버튼을 클릭한다.

② ALB(Application Load Balacer)를 선택한다.

③ 로드 밸런서의 이름을 지정하고, 가용 영역은 northest-2a와 northeast-2c를 선택한다. (가용 영역은 2개 이상 선택해야 하고 선택한 가용 영역에 EC2가 위치해 있어야 한다.)

④ 방금 발급 받은 인증서를 선택한다.

⑤ 기존에 사용하던 보안그룹을 써도 되고, 새로 생성해도 된다. 보안그룹은 HTTPS를 모든 소스로부터 443포트를 열어주는 것만 할 수 있으면 된다. 하지만, 기존 EC2 보안 그룹을 그대로 사용할 것을 권장한다.

  • EC2 인스턴스에 사용된 보안그룹은 아래와 같다.

⑥ 방금 생성한 대상 그룹을 선택한다.

⑦ 대상 등록에서 본인의 EC2를 선택해 등록된 항목에 추가하고 로드밸런서를 생성한다.

⑧ 좌측 메뉴 > 로드밸런서 > 리스너 > HTTP 8080 규칙 보기/편집 버튼을 클릭한다.

⑨ + 탭을 누르고 규칙 삽입 버튼을 클릭한다.

⑩ 아래와 같이 입력한다.

⑪ 우상단에서 HTTPS:443으로 변경한 후, 이번에는 연필 아이콘을 눌러 아래와 같이 기존 설정을 수정한다.

⑫ 다시 Route 53으로 이동하여 호스팅 영역 > A 유형의 레코드를 체크한다.

⑬ 레코드 편집 버튼을 클릭하고, 아래와 같이 설정한다. 방금 만든 로드밸런서를 선택하면 된다.

6. HTTPS 적용 결과 확인하기

① EC2에서 서버를 가동한 후 본인의 EC2 Public IP 주소를 8080포트로 접속해보자.

  • http로 접속이 되어야 한다.

② 이번에는 EC2의 IP 대신 도메인을 입력해보자.

  • 8080 포트번호를 반드시 붙여주어야 한다.
  • hello-there.shop:8080으로 접속했음에도 https로 리다이렉션되었음을 확인할 수 있다.

③ 또는 https로 바로 접속해도 된다. 이는 https로 오는 요청이 대상그룹의 EC2로 전달되기 때문이다.

④ 하지만, 현재는 포트번호를 생략하면, https 리다이렉션이 적용되지 않는다.

⑤ 리스너 추가 버튼을 클릭하여 80포트를 추가한다.

⑥ 규칙 보기/편집 버튼을 클릭해 80, 443, 8080 포트에 대해 아래와 같이 규칙을 설정한다.

  • 80 포트
  • 443 포트
  • 8080 포트

⑦ 이제 포트번호를 생략해도 https 리다이렉션이 정상적으로 진행된다.

⑧ healthcheck API를 실행해보자. API의 엔드포인트는 본인이 설정한 것과 맞게 변경하면 된다. 여기서는 /users/healthcheck를 사용하였다.

정확한 내용은 아니지만, ELB 설정과 Route 53 설정을 모두 마쳤다 하더라도 https 적용이 잘 안 될 수도 있다. 아무래도 https가 완전히 적용되기까지 시간이 조금 필요한 듯 하다. 위의 설정을 모두 마쳤음에도 불구하고, https로 api 호출이 안되거나 브라우저에서 리다이렉션이 잘 안 된다면 충분한 시간을 두고 기다려보자.

7. 리다이렉션 주의사항

Postman에서 API를 테스트해보면 한 가지 문제점이 발견될 것이다. 바로 GET, POST, PATCH, PUT, DELETE 요청이 모두 GET 요청으로 인식된다는 점이다.

1) API의 엔드포인트는 동일하고 HTTP 메서드만 다른 경우

게시글을 생성하는 API를 https로 호출하면, 게시글이 잘 생성되는 것을 볼 수 있다.

그러나 https를 http로 변경하여 호출하는 순간, 다른 응답이 나타난다.

이 응답은 원래 GET으로 해당 엔드포인트를 호출했을 때 나타나야 한다.

즉, GET 이외의 다른 HTTP 메서드로 보낸 요청이 모두 GET으로 변경되고 있는 것이다.

2) GET으로 호출할 수 없는 엔드포인트인 경우

만약 POST로만 호출할 수 있는 API라면 어떻게 될까? 아래는 POST로만 호출할 수 있는 로그인 API의 응답 결과이다.

Method Not Allowed는 HTTP 메서드가 잘못되었을 때 발생하는 에러이다. 즉, POST로 호출해야 할 엔드포인트를 GET으로 잘못 호출했기 때문에 발생하고 있는 것이다.

3) 해결 방법

분명히 POST로 요청했음에도 Postman에서 GET으로 인식하는 이유가 뭘까? 그 이유는 로드밸런서의 규칙에서 정의한 리다이렉션의 상태 코드가 301이기 때문이다.

301 또는 302는 URL이 리다이렉트 되었을 때, 처음 요청한 HTTP 메서드와 무관하게 항상 GET으로 변경시킨다. 이와 달리 307 또는 308은 리다이렉트 되기 전에 사용한 HTTP 메서드를 그대로 유지하면서 리다이렉션한다. 참고로, 301과 308은 영구적인 리다이렉션을, 302와 307은 일시적인 리다이렉션을 의미한다.

하지만 안타깝게도 ELB에서는 현재 307 또는 308 리다이렉션 기능을 제공하지 않는다. 지원하지 않는 이유는 오래된 브라우저의 경우 307과 308 코드를 처리할 수 없기 때문이라고 한다.

다시 말해, GET 이외의 메서드는 반드시 HTTPS로만 호출해야 한다.

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

3개의 댓글

comment-user-thumbnail
2024년 2월 3일

덕분에 좋은 정보 잘 보고 갑니다.

특히나 리다이렉션 주의사항 관련해서 알려주셔서 저도 제 코드의 문제가 뭔지 깨달을 수 있었어요!!!
정말 감사합니다

답글 달기
comment-user-thumbnail
2024년 5월 18일

현재 aws ui 가 많이 변경된 상태이지만, 참고해서 완벽히 따라갈 수 있었습니다.
자세히 설명해주셔서 감사합니다.

답글 달기
comment-user-thumbnail
2024년 7월 16일

감사합니다..감사합니다..

답글 달기