관리 메뉴

JIE0025

https 적용기 (CloudFront, Certificate Manager, ELB, Route53) 본문

백엔드/웹, 배포

https 적용기 (CloudFront, Certificate Manager, ELB, Route53)

Kangjieun11 2023. 5. 2. 00:02
728x90

 

이전에 보면 좋은 글

 

📣 도메인 적용기! 

https://jie0025.tistory.com/504

 

[Domain] 도메인 구매해서 S3에 적용하기(가비아, AWS Route53)

✅ 선행 지식 먼저 도메인이 무엇인지, 도메인이 왜 필요한지에 대한 글은 여기에 있다! https://jie0025.tistory.com/503 [Domain] 도메인의 역할, 왜 필요할까? ✅ 도메인이란? 인터넷 상에서 특정한 웹사

jie0025.tistory.com

 

📣 http와 https

https://jie0025.tistory.com/512

 

http와 https, 안전한 데이터 통신을 하기 위한 사전지식

✅ http와 https http와 https는 무슨 차이가 있을까? http : 웹에서 데이터 교환을 위한 프로토콜, stateless하다는 특징이있다. https : http + SSL(Secure Socket Layer) 인증서 간단하게 말하면 https는 http 요청과

jie0025.tistory.com

 

 

 


 

 

✅ https의 적용을 결정한 이유  (도입배경)

https 적용하는것이 보안적으로 훌륭하다는것을 알아서 당연히 적용해야만 했지만, 

프로젝트 제출일 전까지 https를 적용할지 말지는 사실 Optional할 수도 있었다.

 

추후 개선하면서 적용할 수 도 있는것인데 

프로젝트 제출 전까진 꼭 적용을 하기로 결정을 해버렸다. 

 

 

1️⃣ 처음부터 UX를 신경쓰기로 했다.

 

프로젝트 데모에서 보여지는게 완벽하게 한 다음, 그 이후에 세부적인 개선을 하는것이 좋아보였다. 

 

만약 S3 저장소로 접근하는 URL을 제공하면

부트캠프 데모일에 분명 

엔지니어님들이나 다른 분들, 멘토님까지 우리 프로젝트를 구경할텐데 S3 저장소URL을 제공하는것이 옳은가? 를 고민했다.

 

그리고 도메인을 적용하고, 이왕이면 https까지 적용해 제출하면

사용자가 볼 때 안전한 사이트임을 확인하고 더 완성도 있음을 느낄것을 예상했다.

 

 

2️⃣ Refresh Token을 쿠키를 통해 보내기로 했다.

 

일반적인 경우 
Access Token은 헤더의 Authorization에,

Refresh Token은 쿠키에 담아 전송한다는것을 보았다. 

 

쿠키는 클라이언트에 저장되는 값이기 떄문에 노출될 가능성이 높고, 보안상 문제가 발생할 수 있다는 것도 보았다.

 

그래서 Refresh Token을 쿠키로 전송하려면 무조건 https를 사용해야 한다는 것을 알게 되었다. 

 

 

 

 

이런 2가지 이유로 초기 기획단계에서부터 HTTPS를 제출일 전까지 적용하기로 결정했다.

 

 

 


 

 

✅ CloudFront를 이용한 https 적용

 

✔️ AWS 공식문서 확인하기

https://docs.aws.amazon.com/ko_kr/AmazonCloudFront/latest/DeveloperGuide/using-https.html

 

CloudFront에서 HTTPS 사용 - Amazon CloudFront

SSL 재협상 유형 공격을 차단하기 위해 CloudFront는 최종 사용자와 오리진의 요청에 대한 재협상을 지원하지 않습니다.

docs.aws.amazon.com

 

✍️ CloudFront?

AWS에서 제공하는 CDN(Content Delivery Network) 서비스

 

CDN?

물리적으로 떨어졌있는 사용자에게 컨텐츠를 더 빠르게 제공하는 시스템

 

 

✔️ Cloud Front를 사용한 이유

 

먼저 S3 정적 웹 사이트 호스팅은 리다이렉트 시 https를 지원하지 않는다. 

 

https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/WebsiteHosting.html

 

Amazon S3를 사용하여 정적 웹 사이트 호스팅 - Amazon Simple Storage Service

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

CloudFront는 SSL인증서를 이용한 HTTPS 호스팅을 지원한다.

 

https://repost.aws/ko/knowledge-center/cloudfront-https-requests-s3

 

CloudFront를 사용하여 Amazon S3 버킷에 대한 HTTPS 요청 처리 | AWS re:Post

Amazon Simple Storage Service(Amazon S3)에 대한 HTTPS 요청을 처리하도록 Amazon CloudFront 배포를 구성하려면 어떻게 해야 합니까?

repost.aws

 

 

 

 

우리 서비스는 S3에 프론트 배포파일을 올려놓았기 때문에

간단하게 https를 적용 가능한 CloudFront를 사용하게 되었다. 

 

 

🔎 CloudFront의 구성

Origin Server

 원본 데이터를 가진 서버 (S3, EC2 인스턴스를 나타냄)

 

Edge Server

 AWS에서 실질적으로 제공하는, 전세계적으로 퍼져있는 서버

 캐싱 기능을 제공함으로써 요청받은 데이터를 빠르게 응답할 수 있다. 

 

 

🔎 CloudFront의 작동방식

1. 사용자로부터 요청이 발생

2. 요청이 발생한 Edge Server는 요청 발생한 데이터에 대해 캐싱 여부를 확인함.

3. 캐싱데이터가 존재시 요청에 맞게 응답. 만약 존재하지 않는다면 Origin Server로 요청한다.

4. Origin Server로부터 전달받은 데이터를 Edge Server는 캐싱데이터를 생성해 사용자에게 응답한다.

 

✅ SSL 인증서 발급과 등록

 

다음 글을 참고해서 SSL인증서를 발급 받고, https를 적용했다.

https://velog.io/@seeh_h/%EB%B0%B0%ED%8F%AC-AWS-S3%EB%A1%9C-%EB%B0%B0%ED%8F%AC%ED%95%9C-%EC%95%B1%EC%97%90-HTTPS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

 

Mixed Content 에러 발생  (안전하지 못한 요청)

에러메세지 

The page at "https://my-buddy.co.kr/ was loaded over HTTPS

but requested an insecur XMLHttpRequest endpoint 

http://ec2주소/v1/bulletin-posts/feed?page=1&size=12 

 

this request has been blocked

the content must be served over HTTPS

 

페이지는 https로 로드되었으나, 요청 엔드포인트가 http여서 요청이 블록되었다.

HTTPS를 이용해 전달되어야한다.... 

 

HTTPS가 적용된 사이트에서 HTTP로 요청을 전송할 경우 브라우저단에서 블록을 시킨건데

이는 보안이 이미 적용된 사이트에서 보안이 더 낮은 사이트로 연결할 수 없음을 의미한다. 

 

즉 서버단에도 SSL인증서를 검증할 수 있는 수단이 필요했다.

 

 

->  근본적인 해결책은 호출되는 서버를 SSL 구성할 수만 있다면 가장 깔끔한 방법. http => https 로 호출 변경해서 해결하면 된다고 하는데....   https://golottoshops.com/5

 

 

과연 합리적인 선택인지 고민하게 되었다.

 

 

 

0️⃣ EC2 인스턴스에 인증서 적용

EC2 인스턴스에 직접 SSL 인증서를 적용하여 HTTPS로 통신할 수 있도록 설정하여

Mixed Content 오류를 해결할 수 있다.

 

인스턴스를 1개만 사용하는 경우에 사용하면 된다.

 

https://dev.classmethod.jp/articles/try-configuring-ssl-tls-on-an-ec2-instance/

 

EC2 인스턴스에 SSL/TLS를 구성해 HTTPS로 접속해 보기 | DevelopersIO

EC2 인스턴스에 SSL/TLS를 구성해 보는 과정을 정리해 봤습니다.

dev.classmethod.jp

 

 

1️⃣  Nginx (웹서버)를 이용해 인증서 검증

엔진엑스(nginx)와 같은 웹서버를 사용하여, 프록시 서버를 생성하고

HTTPS로 연결된 CloudFront와 인증서를 검증하고

EC2 인스턴스와의 통신을 보안화하여 Mixed Content 오류를 해결할 수 있다.

 

 

2️⃣ 로드밸런서를 이용한 인증서 검증 😆 (우리의 선택)

Elastic Load Balancer와 같은 로드밸런서를 사용하여
HTTPS로 연결된 CloudFront와 인증서를 검증하고,

EC2 인스턴스와의 통신을 HTTP로 변경하여
Mixed Content 오류를 해결할 수 있다.

 

 

🤔 왜 로드밸런서를 이용해 인증서를 검증하는 방식을 채택했는가?

➡️ 배포에 사용된 도커와 도커컴포즈

우리 프로젝트의 특징이 하나 있었는데

바로 EC2에 서버의 배포를 도커와 도커 컴포즈를 이용했다는 점이다.

 

✍️ 도커란? 

컨테이너 기반의 오픈소스 가상화 플랫폼

애플리케이션을 격리된 환경인 컨테이너로 패키징해 배포가 가능하다

애플리케이션을 빠르고 일관된 방식으로 실행 할 수 있다.

 

✍️ 도커컴포즈란? 

도커 애플리케이션을 정의하고 실행하기 위한 도구

여러개의 컨테이너로 구성된 애플리케이션을 쉽게 배포하고 관리할 수 있다.

 

 

우리 서비스에서 사용된  도커, 도커컴포즈에 대해선 조금 더 분석하고 따로 게시글을 작성할 예정이다 :)

 

 

아무튼 우리 서비스는 도커, 도커컴포즈를 이용해 서버 배포를 완료했고, 

내가 서버 배포를 맡지는 않았지만 도커와 도커컴포즈는 쉬운배포와 확장이 장점이라는것을 알고 있었다. 

 

이 장점을 살리려면 유연한 확장을 신경쓰면 되었다! 

EC2자체에 인증서를 다운받아 검증하는것보다는, EC2 인스턴스의 확장을 고려한 ELB를 사용하는게 좀더 합리적이라고 생각했다.

 

 

 

 ✅ ELB를 이용한 https Mixed Contents 문제 해결

https://golottoshops.com/5

 

EC2에 HTTPS 적용하기 (feat. Mixed Content 에러)

Mixed Content 에러 발생 client 코드에서 Mixed Content 에러가 발생했다. Mixed Content: The page at '' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint ''. This request has been blocked; the content must be served over

golottoshops.com

 

당시에 내가 알지 못했던게  도메인을 구매했을때 해당 도메인의 서브도메인까지 내것으로 사용할 수 있다는 점이었다.

나는 my-buddy.co.kr을 구매하고... 추가적인 도메인의 SSL이 필요한 줄 알고 my-buddy.shop을 따로 구매해버렸다.



 

그래서 로드밸런서에 사용한 SSL 은 my-buddy.shop에 해당하는 인증서가 사용되었다

 

 

 

 

로드밸런서를 생성하고, 규칙에 대상그룹으로 전달하도록 했다. 

https 에선 이전에 만든 인증서를 설정했다.

 

 

 

로드밸런서에서 http의 입력과 https의 입력을 모두 대상그룹(8081 http -- application port )로 옮겨주도록 설정했다. 

 

 

 

 

마지막으로 Route53에서 도메인 호스팅영역 > 레코드에서

레코드 추가 - 레코드 유형 A (IPv4 및 ....)  - 별칭 On - 트래픽 라우팅대상을  Application/Classic Load Balancer에 대한 별칭 - 로드밸런서 선택 하면 https 적용이 끝난다!

 

 

 

 ✅ CORS를 위한 AllowedOrigin 추가 

서브도메인의 존재를 몰라서 

추가 도메인이 생긴 후 Allowed Origin에도 추가해주었다. 

 

 


 

 

 

정리하다보니 느낀건데 분명 이런저런 고민을 많이 했다고 생각했지만

아직도 부족하다는것...

 

추가적으로 개선되어야 하는게 너무많이 보인다. 

 

당시에 배포 및 발표자료까지 만드느라 시간이 많이 부족해서 적당히 알고 적용한 것들이 많았다. 

더 깊게 고민하고 적용해야겠다는 다짐을 하며 글을 마무리한다.