[AdvICE] AWS CloudFront와 EC2 간 HTTPS 통신 설정 및 Nginx로 Mixed Content 오류 해결
목차
1. Nginx 프록시 설정
2. Mixed Content 오류
3. React 애플리케이션에서 API 요청을 CloudFront 도메인으로 변경
4. CloudFront 설정에서 경로 프록시 구성 변경
5. Nginx 서버에서 HTTPS 설정 추가
AWS CloudFront로 프론트 정적 웹 사이트(React)를 배포 완료했고, 이제는 EC2로 배포한 백 서버(SpringBoot)의 API를 연동해줘야한다.
HTTP와 HTTPS의 차이점과 그 중요성
인터넷을 이용하면서 웹사이트 주소 앞에 http://나 https://를 본 적이 있을 것이다. 이 두 프로토콜은 모두 웹에서 정보를 주고받는 방식이지만, 그 사이에는 중요한 차이점이 존재한다. 이번 글에
kanado2000.tistory.com
우선, AWS CloudFront로 배포한 사이트를 HTTP에서 HTTPS로 전환하려면 인증된 구매한 도메인이 필요합니다. HTTPS를 사용하기 위해서는 SSL/TLS 인증서가 필요했다.
AWS CloudFront로 배포한 사이트의 도메인을 가비아에서 구매해서 연동하고, 구매한 도메인으로 AWS에서 SSL 인증서를 요청한 다음에 받은 SSL 인증서를 CloudFront 배포와 연동했다.
1. Nginx 프록시 설정
CloudFront가 원본 서버로 요청하기 위해 Nginx 서버와 같은 프록시가 필요하다.
참고: Nginx는 "리버스 프록시"로 동작할 수 있다. 리버스 프록시란, 클라이언트의 요청을 받으면 해당 요청을 백엔드 서버(즉, 실제 애플리케이션 서버)로 전달하고, 그 응답을 다시 클라이언트로 돌려주는 역할을 하는 것이다. 즉, 프록시 서버는 클라이언트와 원본 서버 사이에서 중개자 역할을 하여 요청과 응답을 전달한다.
Nginx와 같은 프록시를 사용하면 CloudFront가 원본 서버에 안전하고 효율적으로 접근할 수 있으며, SSL/TLS 처리를 통해 보안을 강화하고 로드 밸런싱과 캐싱을 통해 성능을 향상시킬 수 있다. 이는 시스템의 효율성, 확장성, 보안을 높이는 데 도움이 된다.
먼저, Nginx를 설치해야한다. 백 서버를 배포한 EC2 인스턴스에서 터미널로 다은과 같이 입력한다.
sudo apt-get update
sudo apt-get install nginx -y
Nginx를 설치하면 기본 설정 파일이 생성되는데, 그 파일을 다음 명령으로 열고,
sudo nano /etc/nginx/sites-available/default
다음과 같이 설정해준다.
server {
listen 80;
server_name your_EC2_server_IP; # 서버의 실제 IP 주소를 입력합니다.
location / {
proxy_pass your_backend_server_IP; # 백엔드 서버 주소
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
설정 파일을 저장한 후, 다음과 같이 Nginx 설정을 테스트하고 적용한다.
# 설정 파일 저장 후, 설정 테스트
sudo nginx -t
# 설정이 올바르면 Nginx 재시작
sudo systemctl restart nginx
2. Mixed Content 오류
하지만 이상태에서 CloudFrontd의 프론트 정적 웹 사이트(React)에 EC2의 백 서버(SpringBoot)의 API를 연동하면
main.ee9bf56b.js:2 Mixed Content: The page at 'https://ice-advice.co.kr/' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint
위와 같이 "Mixed Content" 오류가 발생한다.
Mixed Content 오류가 발생하는 이유는 클라이언트가 직접 원본 서버로 요청하고 있는 것이였다. 현재 문제는 클라이언트(React 애플리케이션)가 CloudFront를 거치지 않고 직접 원본 서버의 HTTP 엔드포인트(http://your_EC2_server_IP:8080/api/v1/auth/sign-in)로 요청을 보내고 있다. 클라이언트는 https://ice-advice.co.kr을 통해 HTTPS로 로드되었는데, HTTP로 요청을 보내기 때문에 Mixed Content 오류가 발생한다. 즉, React 앱의 API 요청은 http://your_EC2_server_IP:8080으로 직접 가고 있어, 이 요청이 CloudFront를 통해 프록시되지 않고 있다.
해결 방법은 모든 클라이언트 요청이 CloudFront를 거치도록 하는 것인데 순서가 크게 다음과 같다:
1. React 애플리케이션에서 API 요청을 CloudFront 도메인으로 변경: React 애플리케이션에서 API 요청 URL을 http://your_EC2_server_IP:8080이 아닌, CloudFront 도메인(https://api.ice-advice.co.kr/*)으로 변경한다. 이를 통해 클라이언트 요청이 CloudFront를 거치게 되고, 클라이언트와 CloudFront 간의 통신은 HTTPS로 유지된다.
2. CloudFront 설정에서 경로 프록시 구성 변경: CloudFront에서 /api/* 요청을 원본 서버(예: http://your_EC2_server_IP:8080)로 전달하도록 설정해야 한다.
이렇게 하면 모든 API 요청이 클라이언트(React) → CloudFront → EC2 원본 서버(SpringBoot)로 흐르게 되어, Mixed Content 오류가 해결될 수 있다.
3. React 애플리케이션에서 API 요청을 CloudFront 도메인으로 변경
React 프로젝트에서 모든 API 도메인을 https://api.ice-advice.co.kr/*로 수정한다.
4. CloudFront 설정에서 경로 프록시 구성 변경
우선 도메인을 구매한 사이트에서 도메인 설정에 api.ice-advice.co.kr이라는 호스트 레코드를 추가하고, 해당 레코드의 값(값/위치)으로 서버의 IP 주소(your_EC2_server_IP)를 넣어줘야 한다.
CloudFront 배포 ID를 선택한 다음, 원본 탭으로 이동하여 오른쪽에 보이는 원본 생성 버튼을 누른다.
"원본 생성" 페이지에서 다음과 같이 설정하고, 하단에 있는 변경 사항 저장 또는 원본 생성 버튼을 누른다.
그 다음, CloudFront 배포에서 동작 탭으로 이동하여 오른쪽에 보이는 동작 생성 버튼을 누른다.
"동작 생성" 페이지에서 다음과 같이 설정하고, 나머지 설정은 기본 값으로 두고 하단에 있는 동작 생성 버튼을 누른다.
5. Nginx 서버에서 HTTPS 설정 추가
클라이언트와 Nginx 간의 통신 뿐만 아니라 Nginx와 백엔드 서버 간의 통신도 보안하기 위해 즉, 전 구간에 걸쳐 데이터를 암호화하여 보안을 강화하기 위해 백엔드 서버에 HTTPS를 적용할것이다.
먼저 Nginx 설정 파일을 열어서 기존 설정에 HTTPS를 추가하고, Let's Encrypt 인증 기관을 통해 SSL 인증서를 발급받는다.
sudo apt-get install certbot python3-certbot-nginx -y
sudo certbot --nginx -d api.ice-advice.co.kr
이제 Nginx 설정 파일 수정한다.
sudo nano /etc/nginx/sites-available/default
server {
listen 80;
# CloudFront에서 전달된 요청을 받을 도메인
server_name api.ice-advice.co.kr;
# HTTP를 HTTPS로 리다이렉트
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name api.ice-advice.co.kr;
ssl_certificate /etc/letsencrypt/live/api.ice-advice.co.kr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.ice-advice.co.kr/privkey.pem;
location / {
proxy_pass http://your_EC2_server_IP:8080; # 백엔드 서버 주소와 포트
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
- 첫 번째 서버 블록에서는 CloudFront에서 전달된 요청을 받을 도메인(api.ice-advice.co.kr)을 설정하고, HTTP 요청을 HTTPS로 리다이렉트한다.
- 두 번째 서버 블록에서는 SSL 인증서를 사용하여 HTTPS 연결을 설정하고, 백엔드 서버로 요청을 프록시하여 백엔드 서버에서도 SSL 인증서를 적용하고 HTTPS 포트를 열어준다.
설정 파일을 저장한 후, 다음과 같이 Nginx 설정을 테스트하고 적용한다.
# 설정 파일 저장 후, 설정 테스트
sudo nginx -t
# 설정이 올바르면 Nginx 재시작
sudo systemctl restart nginx
끝!