Nginx CORS + HTTPS 설정하기
본 포스팅은 AWS EC2 인스턴스(Ubuntu 24.04 LTS)를 기준으로 작성하였습니다.
1. Nginx Install
$sudo apt-get install nginx
$nginx -v #nginx version 확인
2. Nginx Config Settings
Nginx의 동작 방식을 결정하는 nginx.conf 파일은 /etc/nginx 에 위치해 있다. 해당 파일에서는 Basic Settings, SSL Settings, Logging Settings, Gzip Settings and Virtual Host Configs 등 다양한 값을 세팅할 수 있다. 이번 포스팅에서는 Virtual Host Configs의 /etc/nginx/sites-enabled/* 을 커스터 마이징 하여 Nginx CORS 및 HTTPS를 적용한 방법에 대해서 설명하도록 하겠다.
http {
##
# Basic Settings
##
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
##
# Gzip Settings
##
...
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
(※ nginx.conf의 include 커멘드는 특정 경로에 있는 파일을 import 하는 의미로 사용된다.)
/etc/nginx 내부를 확인해보면, sites-available, sites-enabled 두 개의 디렉터리를 확인할 수 있다.
- sites-available: 모든 Nginx 설정 파일을 저장하는 용도
- sites-enabled: sites-available에 생성된 설정 파일 중 실제 Nginx 서버에 적용할 설정 파일의 심볼릭 링크를 생성하는 용도
3. Nginx HTTPS
Nginx는 SSL을 적용하여 HTTPS 연결을 지원한다. 이번 포스팅에서는 무료로 SSL 인증서를 발급해 주는 Let's Encrypt 서비스를 사용하였다.
Certbot install
$sudo apt install certbot
$sudo apt install python3-certbot-nginx
Certbot 설치가 완료된 후, Let's Encrypt 인증서를 발급해야 한다. 단, 인증서 발급 단계 진행을 위해서는 사전에 등록된 도메인이 필요하다. 따라서, HTTPS를 적용할 IP에 도메인 호스팅이 되어 있지 않다면 해당 작업을 마친 후에 아래 단계를 따라야 한다.
Let's Encrypt 인증서 발급
$sudo certbot certonly --nginx
인증서 발급을 마치면 아래 위치에 각각 2종류의 인증서가 생성된다.
/etc/letsencrypt/live/[Domain Name]/fullchain.pem # 인증서 파일
/etc/letsencrypt/live/[Domain Name]/privkey.pem # 개인키 파일
위 과정을 마친 후, /etc/nginx/sites-available/[설정파일명].conf 에 SSL 정보를 추가한다.
server {
listen 80;
server_name survey-dingdong.site;
return 301 https://$server_name$request_uri; #HTTP 요청 시 HTTPS로 리다이렉트
}
server {
listen 443 ssl; # SSL 포트번호
server_name survey-dingdong.site;
ssl_certificate /etc/letsencrypt/live/[Domain Name]/fullchain.pem; #인증서 파일 경로
ssl_certificate_key /etc/letsencrypt/live/[Domain Name]/privkey.pem; #개인키 파일 지정
include /etc/letsencrypt/options-ssl-nginx.conf; # SSL 설정파일
location / {
include proxy_params;
proxy_pass http://127.0.0.1:8000;
}
}
작업을 마친 후, 심볼릭 링크 생성을 통해 sites-enabled 내부에 설정 파일을 동기화 해준다.
Nginx Symlink
$sudo ln -s /etc/nginx/sites-available/[설정파일명].conf /etc/nginx/sites-enabled/[설정파일명].conf
마지막으로 nginx.conf 파일의 유효성 검증 및 Nginx 서버 재시작을 통해 정상 동작 여부를 확인한다.
$sudo nginx -t #nginx.conf 유효성 검증
$sudo nginx -s reload #Nginx 서버 재시작
4. Nginx CORS
API 서버를 보호하고 개발 환경의 HTTP 요청(localhost)을 허용하기 위해 Nginx CORS(Cross-Origin Resource Sharing)를 설정 하였다. CORS의 메커니즘에는 다음 두 가지 요소가 핵심으로 자리잡고 있다.
- OPTIONS Method
- 브라우저가 실제 요청 전에 서버의 CORS 정책을 확인(preflight 요청)하는데 필요
- 복잡한 CORS 요청(예: 비표준 HTTP Method 또는 Header 사용)에 대해 자동으로 실행
- Access-Control-Allow-Origin Header
- CORS 정책의 가장 기본적이고 중요한 부분
- 서버가 어떤 출처(Origin)의 요청을 허용하는지 명시하고, 브라우저는 이를 확인하여 요청의 허용 여부를 결정
/etc/nginx/sites-available/[설정파일명].conf 에 CORS 정보를 추가한다.
map $http_origin $allowed_origin {
default "";
"http://localhost:3000" $http_origin;
"https://[Domain Name]" $http_origin;
}
server {
...
location / {
include proxy_params;
add_header "Access-Control-Allow-Origin" $allowed_origin always;
add_header "Access-Control-Allow-Methods" "GET, POST, DELETE, PUT, PATCH, OPTIONS" always;
add_header "Access-Control-Allow-Headers" "Content-Type, Authorization" always;
add_header "Access-Control-Allow-Credentials" "true" always;
if ($request_method = "OPTIONS") {
return 204;
}
proxy_pass http://127.0.0.1:8000;
}
}
- Access-Control-Allow-Origin Header
- map 블록이 동작하는 로직이 포함되어 있으며, $http_origin(요청의 Origin Header) 값을 기준으로 $allowed_origin 에 값을 할당
- 매칭되는 Origin이 있으면 사용, 아닌 경우 빈 문자열 반환
- Access-Control-Allow-Methods
- 허용되는 HTTP Method 지정
- Access-Control-Allow-Headers
- 허용되는 HTTP 헤더 지정
- Access-Control-Allow-Credentials
- 인증 정보(쿠키, HTTP 인증)를 포함한 요청 허용 여부 지정=
add_header 지시문에서 always 키워드가 의미하는 바는?
Nginx 설정에서 always 키워드는 주로 add_header 지시문과 함께 사용되며, 중요한 의미를 가지고 있다.
1. 기본 동작: always 없이 add_header를 사용하면, Nginx는 성공적인 응답(2xx 상태 코드)에만 해당 헤더를 추가한다.
2. always의 역할: add_header 지시문에 always 플래그를 추가하면, Nginx는 모든 응답에 해당 헤더를 추가한다. 이는 성공 응답뿐만 아니라 오류 응답(4xx, 5xx 상태 코드)에도 적용된다.