HTTP 핵심 모듈이란 HTTP 서버의 모든 기반 블록, 지시어, 변수를 포함하는 구성 요소입니다.
해당 모듈을 통해서 Nginx를 컴파일하면 기능들이 활성화됩니다.
또한, Nginx의 모듈 중 가장 규모가 크며, 주 블록인 http, server, location의 논리적 구조를 이해하는 것이 중요합니다.
http
구성 파일의 최상위에 삽입되며, http와 관련된 사항들이 담깁니다.
만약 http 블록이 여러 번 추가된다면, 가장 마지막 블록에 담긴 사항이 적용됩니다.
server
웹 사이트 하나를 선언할 수 있습니다. 즉, Nginx가 특정 웹 사이트를 인식하고 해당 요소에 필요한 구성들이 담깁니다.
location
웹 사이트의 특정 위치(경로)에만 적용되는 설정을 정의하는 데 사용됩니다.
해당 블록은 server 및 다른 location 블록 안에 중첩으로 사용 가능합니다.
http {
# gzip on
gzip on;
sever {
server_name localhost;
listen 80;
# 해당 블록에서도 gzip 지시어가 활성 됨
location /downloads/ {
gzip off; # /downloads/ 내의 문서에 한하여 gzip off 가 적용됨
}
}
}
❗Nginx에서는 설정 상속 원리가 적용됩니다.
위에서도 언급했듯이, 상위 블록에 적용된 지시어가 하위 블록에도 상속되어 적용됩니다.
-> 하위 블록에 상속된 값에 대해서 명시적으로 gzip off와 같이 상속받은 값을 덮어 쓰는 것이 가능합니다.
http, server, location 블록에 대해서 계속해서 알아보고 있듯이, 세 블록에 대해서 각각 주로 사용되는 사례에 따른 지시어를 살펴보겠습니다.
| 지시어 | 설명 |
|---|---|
listen | 요청을 수신할 IP 주소 및 포트를 지정 |
server_name | 요청을 처리할 도메인 이름 지정 |
ssl | SSL을 사용한 HTTPS 통신 설정 |
default_server | 기본 가상 서버로 지정 (선택적 listen 옵션) |
resolver | DNS 해석에 사용할 네임서버 지정 |
proxy_pass | 요청을 백엔드 서버로 프록시할 때 사용 (소켓 포함 가능) |
http {
resolver 8.8.8.8 1.1.1.1 valid=300s;
server {
listen 443 ssl default_server;
server_name www.example.com example.com;
ssl_certificate /etc/nginx/ssl/example.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
proxy_pass http://unix:/var/run/app.sock:;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
server {
listen 80;
server_name www.example.com example.com;
# HTTP 요청을 HTTPS로 리디렉션
return 301 https://$host$request_uri;
}
}
| 지시어 | 설명 |
|---|---|
listen 443 ssl default_server; | 443 포트(HTTPS)를 수신하며, 이 서버 블록을 기본 가상 서버로 지정 |
server_name www.example.com example.com; | 해당 도메인에 대한 요청 처리 |
ssl_certificate, ssl_certificate_key | SSL 인증서 및 키 파일 경로 |
resolver 8.8.8.8 1.1.1.1; | 외부 도메인을 proxy_pass할 경우 사용할 DNS 서버 설정 |
proxy_pass http://unix:/var/run/app.sock:; | 백엔드 앱과 Unix 도메인 소켓으로 연결 |
listen 80; | HTTP 기본 포트를 수신 |
return 301 https://$host$request_uri; | HTTP 요청을 HTTPS로 리디렉션 |
- 리디렉션에 활용된 301 Status code?
301 Moved Permanently는 클라이언트(브라우저 등)에게 "이 리소스는 영구적으로 다른 위치로 이동되었으니, 앞으로는 새 주소를 사용하라"고 알려주는 영구 리디렉션 코드입니다.
- 사용자가 http://example.com으로 접속하면,
- 서버는 클라이언트에게 301 응답을 주며,
- 클라이언트는 https://example.com으로 자동 이동하게 됩니다.
⁉️ Note: 301 vs 302
| 코드 | 이름 | 설명 |
|---|---|---|
| 301 | Moved Permanently | 영구 이동, 검색엔진도 새 URL을 인식 |
| 302 | Found (Temporary) | 임시 이동, 원래 URL 유지 권장 |
/img/logo.png 요청 시 → 실제 경로: /var/www/img/logo.png
location /img/ { root /var/www; }
localhost/admin 요청 시 → 실제 경로: /var/www/locked/
server{ server_name localhost; root /var/www/website.com/html; location /admin { alias /var/www/locked/; } }
요청에 아무런 파일명도 지정되지 않았을 때, Nginx가 default로 제공할 페이지를 정의합니다.
index 지시어에 여러 파일 명을 지정하면 발견되는 첫 파일이 요청자에게 제공됩니다.
/ 요청 시 /var/www/html/index.html을 먼저 찾고, 없으면 index.htm을 찾음
location / { root /var/www/html; index index.html index.htm; }
지정한 순서대로 파일이나 디렉토리의 존재 여부를 확인하여, 처음으로 존재하는 항목을 반환합니다.
마지막 인자는 "fallback 동작" (예: 오류 코드, 내부 리디렉션 등)으로 사용됩니다.
실제 요청 파일이 없으면 /fallback.html로 대신 응답
location / { root /var/www/html; try_files $uri $uri/ $uri.html $ uri.xml /fallback.html; }
- /var/www/html 기준으로 $uri 경로의 파일이 있는지 확인 (예: /index.html)
- 없으면 $uri/, $uri.html, $ uri.xml 디렉토리가 있는지 순차적으로 확인
- 모두 다 없으면 /fallback.html을 대신 반환
아래와 같이 모든 파일이 없는 경우 http 404 에러를 반환하도록 설정도 가능합니다.
try_files $uri $uri/ =404;
요청한 URI가 디렉토리이고, 해당 디렉토리에 index 지시어로 지정된 기본 문서(예: index.html)가 없을 경우, autoindex on;이면 디렉토리 안의 파일 목록을 HTML 형태로 출력합니다.
브라우저에서 http://localhost/files/ 접속 시, /var/www/data/files/ 디렉토리 내의 파일 목록을 자동으로 보여줌 (index.html 없을 때)
server { listen 80; server_name localhost; location /files/ { root /var/www/data; autoindex on; } }결과 화면 예시)
| 지시어 | 설명 | 예제 |
|---|---|---|
location | 특정 URI 경로에 대한 처리 정의 | location /images/ { ... } |
root | URI 경로를 실제 파일 경로에 매핑 | root /var/www/html; |
alias | URI 경로를 지정된 경로로 직접 대체 | alias /data/images/; |
index | 디렉토리 요청 시 반환할 기본 문서 | index index.html index.htm; |
try_files | 요청한 파일이 없을 때 대체할 파일 시도 | try_files $uri $uri/ =404; |
autoindex | 디렉토리 목록 출력 여부 | autoindex on; |
http {
keepalive_timeout 20s 10s;
keepalive_requests 100;
keepalive_disable msie6;
upstream backend {
server 127.0.0.1:8000;
keepalive 32;
}
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
}
예제에서 특이한 점❓
keepalive_timeout 지시어 사용 시, 하나의 지시어에 20s과 10s 을 각각 명시해둔 것을 확인 가능합니다.
이는 클라이언트 연결 유지 시간과 응답 헤더로 전달할 Keep-Alive 헤더 값을 각각 설정하는 것입니다.
서버에 설정된 내용
keepalive_timeout 20s 10s;
실제 브라우저에서 받는 응답 헤더 값
Connection: keep-alive
Keep-Alive: timeout=10
즉, 클라이언트 연결 유지 시간에 대하여 서버는 20초 유지, 브라우저에는 10초만 유지하라고 헤더를 통해 안내
| 지시어 | 적용 블록 | 설명 |
|---|---|---|
keepalive_timeout | http, server, location | 클라이언트 연결 유지 시간 설정 |
keepalive_requests | http, server, location | 하나의 keepalive 연결에서 처리할 최대 요청 수 |
keepalive_disable | http, server, location | 특정 브라우저에 대해 keepalive 비활성화 |
keepalive | upstream | 백엔드(upstream) 서버와의 연결을 재사용하도록 설정 |
keepalive_time | http, server, location | 연결 풀에서 사용되지 않은 TCP 연결의 유효 시간 (Nginx 1.15.3+) |
| 지시어 | 설명 |
|---|---|
limit_except | 특정 HTTP 메서드만 허용 |
client_max_body_size | 클라이언트 요청 본문(파일 업로드 등)의 최대 크기 제한 |
allow / deny | IP 기반 접근 제어 |
auth_basic | 요청 시 인증 요구 |
auth_basic_user_file | 사용자 인증 파일 경로 지정 |
return | 특정 조건에서 응답 반환 (리디렉션 등) |
rewrite | 요청 URI를 재작성 |
error_page | 오류 발생 시 대체 페이지 지정 |
server {
listen 80;
server_name example.com;
# 최대 업로드 파일 크기: 10MB
client_max_body_size 10M;
location /upload/ {
limit_except POST {
deny all;
}
root /var/www/data;
# 인증 요구
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
location /admin/ {
allow 192.168.1.0/24;
deny all;
}
# 오류 페이지 설정
error_page 403 /custom_403.html;
error_page 404 /custom_404.html;
location = /custom_403.html {
root /var/www/errors;
}
location = /custom_404.html {
root /var/www/errors;
}
}
예제에서는 GET 요청만 허용하고, POST, PUT, DELETE 등은 모두 차단합니다.
보통 업로드 API 보호에 사용location /upload/ { limit_except GET { deny all; } }2. client_max_body_size
- 요청 본문 크기(주로 파일 업로드)의 최대 허용 크기를 제한합니다.
클라이언트가 5MB를 초과하는 파일을 업로드하면 413 Request Entity Too Large 에러 반환
server { client_max_body_size 5M; }3. large_client_header_buffers
- 클라이언트 요청 헤더에 대한 최대 크기와 개수를 제한합니다.
최대 4개의 8KB 크기 헤더를 허용, 그 이상이면 400 Bad Request 반환
server { large_client_header_buffers 4 8k; }
클라이언트(IP 기준)는 /api/에 초당 10개 요청 가능, 순간적으로는 최대 5개까지 초과 허용
http { limit_req_zone $binary_remote_addr zone=req_zone:10m rate=10r/s; server { location /api/ { limit_req zone=req_zone burst=5 nodelay; } } }
같은 IP는 /download/에 한 번에 하나의 연결만 허용
http { limit_conn_zone $binary_remote_addr zone=conn_zone:10m; server { location /download/ { limit_conn conn_zone 1; } } }
다운로드 시 처음 1MB는 빠르게 전송, 이후부터는 200KB/s 속도로 제한
location /files/ { limit_rate 200k; limit_rate_after 1m; }
| 범주 | 지시어 | 설명 |
|---|---|---|
| 요청 메서드 제한 | limit_except | 특정 HTTP 메서드만 허용하고 나머지는 차단 |
| 요청 본문 크기 제한 | client_max_body_size | 업로드 가능한 최대 크기 제한 |
| 요청 헤더 크기 제한 | large_client_header_buffers | 헤더의 최대 크기/버퍼 수 제한 |
| 요청 횟수 제한 | limit_req_zone, limit_req | 초당 요청 수 제한 (DoS 방지) |
| 동시 연결 수 제한 | limit_conn_zone, limit_conn | IP당 동시 연결 수 제한 |
| 응답 속도 제한 | limit_rate, limit_rate_after | 파일 다운로드 시 전송 속도 제한 |