Nginx - http, server, location 관련 지시어 예제 및 정리 (3)

박민준·2025년 5월 14일

Nginx

목록 보기
3/3

HTTP 핵심 모듈

HTTP 핵심 모듈이란 HTTP 서버의 모든 기반 블록, 지시어, 변수를 포함하는 구성 요소입니다.
해당 모듈을 통해서 Nginx를 컴파일하면 기능들이 활성화됩니다.
또한, Nginx의 모듈 중 가장 규모가 크며, 주 블록인 http, server, location의 논리적 구조를 이해하는 것이 중요합니다.

논리 구조 블록

  • http
    구성 파일의 최상위에 삽입되며, http와 관련된 사항들이 담깁니다.
    만약 http 블록이 여러 번 추가된다면, 가장 마지막 블록에 담긴 사항이 적용됩니다.

  • server
    웹 사이트 하나를 선언할 수 있습니다. 즉, Nginx가 특정 웹 사이트를 인식하고 해당 요소에 필요한 구성들이 담깁니다.

  • location
    웹 사이트의 특정 위치(경로)에만 적용되는 설정을 정의하는 데 사용됩니다.
    해당 블록은 server 및 다른 location 블록 안에 중첩으로 사용 가능합니다.

논리 구조 블록 3개를 활용한 예시를 살펴보겠습니다.

  1. http 블록에 gzip을 통해 압축 기능을 활성화함
  2. server 블록에 서버 명(접근 도메인) 및, 접근 port를 명시하고 상위 http 블록을 통해서 gzip을 상속받음
  3. location 블록에 특정 URI 패턴인 /downloads/에 대한 요청을 처리하는 방법을 정의했으며,
    /downloads/ 경로로 들어오는 요청에 대해서는 gzip 압축을 비활성화함
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요청을 처리할 도메인 이름 지정
sslSSL을 사용한 HTTPS 통신 설정
default_server기본 가상 서버로 지정 (선택적 listen 옵션)
resolverDNS 해석에 사용할 네임서버 지정
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_keySSL 인증서 및 키 파일 경로
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는 클라이언트(브라우저 등)에게 "이 리소스는 영구적으로 다른 위치로 이동되었으니, 앞으로는 새 주소를 사용하라"고 알려주는 영구 리디렉션 코드입니다.
  1. 사용자가 http://example.com으로 접속하면,
  2. 서버는 클라이언트에게 301 응답을 주며,
  3. 클라이언트는 https://example.com으로 자동 이동하게 됩니다.

⁉️ Note: 301 vs 302

코드이름설명
301Moved Permanently영구 이동, 검색엔진도 새 URL을 인식
302Found (Temporary)임시 이동, 원래 URL 유지 권장

경로 & 문서 구성

예제 및 사용된 지시어 설명)

1. root vs alias

  • root
    클라이언트에게 제공하고자 하는 파일을 담고 있는 최상위 문서 위치를 정의합니다.

/img/logo.png 요청 시 → 실제 경로: /var/www/img/logo.png

location /img/ {
    root /var/www;
}
  • alias
    alias는 location 블록 안에만 사용 가능하며, Nginx가 특정 요청에서 별도 경로의 문서를 읽도록 할당합니다.

localhost/admin 요청 시 → 실제 경로: /var/www/locked/

server{
	server_name localhost;
    root /var/www/website.com/html;
	location /admin {
    	alias /var/www/locked/;
    }
}

2. index

요청에 아무런 파일명도 지정되지 않았을 때, Nginx가 default로 제공할 페이지를 정의합니다.
index 지시어에 여러 파일 명을 지정하면 발견되는 첫 파일이 요청자에게 제공됩니다.

/ 요청 시 /var/www/html/index.html을 먼저 찾고, 없으면 index.htm을 찾음

location / {
    root /var/www/html;
    index index.html index.htm;
}

3. try_files

지정한 순서대로 파일이나 디렉토리의 존재 여부를 확인하여, 처음으로 존재하는 항목을 반환합니다.
마지막 인자는 "fallback 동작" (예: 오류 코드, 내부 리디렉션 등)으로 사용됩니다.

실제 요청 파일이 없으면 /fallback.html로 대신 응답

location / {
    root /var/www/html;
    try_files $uri $uri/ $uri.html $ uri.xml /fallback.html;
}
  1. /var/www/html 기준으로 $uri 경로의 파일이 있는지 확인 (예: /index.html)
  2. 없으면 $uri/, $uri.html, $ uri.xml 디렉토리가 있는지 순차적으로 확인
  3. 모두 다 없으면 /fallback.html을 대신 반환

아래와 같이 모든 파일이 없는 경우 http 404 에러를 반환하도록 설정도 가능합니다.

try_files $uri $uri/ =404;

4. autoindex

요청한 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/ { ... }
rootURI 경로를 실제 파일 경로에 매핑root /var/www/html;
aliasURI 경로를 지정된 경로로 직접 대체alias /data/images/;
index디렉토리 요청 시 반환할 기본 문서index index.html index.htm;
try_files요청한 파일이 없을 때 대체할 파일 시도try_files $uri $uri/ =404;
autoindex디렉토리 목록 출력 여부autoindex on;

클라이언트 요청

KeepAlive 예제 및 사용된 지시어 설명)

  • keepalive가 왜 중요할까요?
    ✅ 성능 향상: TCP 연결을 재사용하므로 커넥션 설정 비용 감소
    ✅ 지연 감소: 클라이언트 요청 간의 속도 향상
    ⚠️ 주의할 점: 연결이 너무 오래 유지되면 자원 낭비 가능 → 적절한 제한 필요

예제)

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_timeouthttp, server, location클라이언트 연결 유지 시간 설정
keepalive_requestshttp, server, location하나의 keepalive 연결에서 처리할 최대 요청 수
keepalive_disablehttp, server, location특정 브라우저에 대해 keepalive 비활성화
keepaliveupstream백엔드(upstream) 서버와의 연결을 재사용하도록 설정
keepalive_timehttp, server, location연결 풀에서 사용되지 않은 TCP 연결의 유효 시간 (Nginx 1.15.3+)
  • keepalive 외에도 클라이언트 요청 관련 지시어들이 존재합니다.
지시어설명
limit_except특정 HTTP 메서드만 허용
client_max_body_size클라이언트 요청 본문(파일 업로드 등)의 최대 크기 제한
allow / denyIP 기반 접근 제어
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;
    }
}

제한과 제약

  • 클라이언트가 서버의 특정 위치나 문서에 접근하고자 할 때, 적용할 제약 사항을 추가가 가능합니다.

예제 및 사용된 지시어 설명)

예제)

1. limit_except

  • 특정 HTTP 메서드만 허용하고, 나머지는 모두 차단합니다.

예제에서는 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;
}

4. limit_req_zone + limit_req

  • 단위 시간당 요청 수를 제한합니다. (DoS 완화용)

클라이언트(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;
        }
    }
}

5. limit_conn_zone + limit_conn

  • IP당 또는 키당 동시 연결 수를 제한합니다.

같은 IP는 /download/에 한 번에 하나의 연결만 허용

http {
    limit_conn_zone $binary_remote_addr zone=conn_zone:10m;
    server {
        location /download/ {
            limit_conn conn_zone 1;
        }
    }
}

6. limit_rate + limit_rate_after

  • 응답 속도를 제한해서 대역폭 과다 사용을 방지합니다.

다운로드 시 처음 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_connIP당 동시 연결 수 제한
응답 속도 제한limit_rate, limit_rate_after파일 다운로드 시 전송 속도 제한
profile
바교망

0개의 댓글