AWS에서 보안 정적 웹사이트 호스팅: CloudFront + Origin Access Control가 적용된 프라이빗 S3 버킷
Source: Dev.to
최종 상태
Amazon S3에 호스팅된 정적 웹사이트가 Amazon CloudFront를 통해 전 세계에 비공개 액세스로 제공됩니다.
Browser / curl
↓
CloudFront Distribution (HTTPS)
↓
Origin Access Control (OAC)
↓
Private S3 bucket
↓
index.html
최종 작동 URL (튜토리얼을 완료하기 전까지는 동작하지 않음):
https://d11v1nvbkt9lgm.cloudfront.net/
모든 설정이 완료된 후 결과:
- HTTP 200
- S3에서 제공되는 콘텐츠
- CloudFront에 의해 캐시됨
- 버킷 공개 아님
단계별 수행 내용
1️⃣ S3 버킷 생성
- 버킷 이름:
devops-bucket-alok index.html업로드- Static Website Hosting 활성화
참고: S3 정적 웹사이트 호스팅 ≠ S3 REST API 엔드포인트.
2️⃣ CloudFront 배포 생성
- 오리진: 위에서 만든 S3 버킷
- 기본 동작:
* - 뷰어 정책: HTTP → HTTPS 리다이렉트
- 허용 메서드: GET, HEAD
생성된 CloudFront 도메인: d11v1nvbkt9lgm.cloudfront.net
❌ 문제 1 – CloudFront에서 403 AccessDenied
증상
-
브라우저에 XML 오류 페이지가 표시됨.
-
curl출력:HTTP/2 403 server: AmazonS3 x-cache: Error from cloudfront -
CloudFront는 S3에 도달했지만, 버킷에 CloudFront에 대한 권한이 없어서 S3가 요청을 거부함.
근본 원인
- CloudFront Origin Access Control (OAC) 은 S3 웹사이트 엔드포인트와 작동하지 않음(웹사이트 엔드포인트는 공개 액세스가 필요).
- OAC는 S3 REST 엔드포인트와만 작동함.
올바른 결정 – 버킷의 REST 엔드포인트를 사용.
devops-day0-oac 라는 Origin Access Control 을 생성하고 오리진에 연결했지만 여전히 403 오류가 발생함.
OAC는 마법이 아니다; CloudFront가 요청에 서명을 하지만 S3는 여전히 해당 서명된 요청을 허용하는 버킷 정책이 필요하다.
❌ 문제 4 – “어디서 연결 여부를 확인하나요?”
가장 답답한 부분은 CloudFront가 다음과 같이 알려준다는 점:
“이 정책 문을 사용하여 액세스를 허용해야 합니다”
AWS는 필수 버킷 정책을 자동으로 적용하지 않는다.
3️⃣ S3 버킷 정책 추가 (핵심 단계)
-
S3 콘솔에서: devops-bucket-alok → Permissions → Bucket policy 로 이동.
-
CloudFront가 생성한 정책을 붙여넣기. 이 정책은:
cloudfront.amazonaws.com허용- 배포 ARN에 대한 접근 제한
s3:GetObject권한 부여
정책을 적용한 후 요청 흐름이 성공함:
- CloudFront → S3
- 브라우저에 HTTP/2 200,
x-cache: Miss from cloudfront표시
## Hello from S3 + CloudFront!
이를 통해 CloudFront가 요청을 앞에서 처리하고, S3가 오리진이며, 접근 제어가 올바르게 설정되고 HTTPS가 동작함을 확인함.
배운 점
개념적
- 객체 저장소와 서버 호스팅의 차이.
- CDN과 오리진의 역할 구분.
- CloudFront가 존재하는 이유.
- S3 버킷을 공개하지 않아야 하는 이유.
- 403 오류는 네트워크 문제가 아니다.
AWS‑특화
- S3 웹사이트 엔드포인트와 REST 엔드포인트의 차이.
- OAC(최신)와 OAI(레거시).
- OAC를 사용할 때는 버킷 정책이 필수.
- 많은 CloudFront 오류가 실제로는 S3 권한 문제에서 비롯됨.
DevOps 현실
- AWS UI가 중요한 단계(예: 버킷 정책 연결)를 숨김.
- 오류 메시지는 기술적으로 정확하지만 종종 도움이 되지 않음.
- 트러블슈팅은 대부분 권한 추적에 관한 작업.
- 대부분의 시간은 하나의 누락된 정책 문 때문에 소모됨.