NGINX Rewrite 규칙 만들기
이 블로그 포스트에서는 NGINX Rewrite 규칙을 만드는 방법에 대해 설명합니다(동일한 방법이 NGINX Plus와 NGINX Open Source 소프트웨어 모두에 적용됨). NGINX Rewrite 규칙은 일반적으로 다음 두 가지 목적 중 하나로 클라이언트 요청에서 URL의 일부 또는 전부를 변경합니다. 클라이언트의 요청(Request) URL을 수정할 수 없을 때 특히 유용합니다.
- 클라이언트에게 요청하는 리소스가 현재 다른 위치에 있음을 알리기 위해. 사용 사례의 예로는 웹 사이트의 도메인 이름이 변경된 경우, 클라이언트가 표준 URL 형식( www 접두사 가 있거나 없는 경우 )을 사용하기를 원하는 경우, 도메인 이름의 일반적인 철자 오류를 잡아서 수정하려는 경우가 있습니다.
return
및 지시문rewrite
은 이러한 목적에 적합합니다. - NGINX 및 NGINX Plus 내에서 처리 흐름을 제어하기 위해(예: 콘텐츠를 동적으로 생성해야 할 때 애플리케이션 서버에 요청을 전달하기 위해). 지시문
try_files
은 종종 이러한 목적으로 사용됩니다.
HTTP 응답 코드와 정규식(NGINX 및 NGINX Plus는 Perl 구문 사용) 에 익숙하다고 가정합니다.
목록
1.return
,nginx rewrite
및try_files
지시문 비교
1-1.return 디렉티브
1-2.rewrite 디렉티브
1-3.try_files 디렉티브
2. 도메인 이름 표준화
2-1. 이전 이름에서 현재 이름으로 리다이렉션
2-2. www 접두사 추가 및 제거
2-3. 모든 트래픽을 올바른 도메인 이름으로 리다이렉션
3. NGINX Rewirte 예시
3-1. 모든 요청이 SSL/TLS를 사용하도록 강제 예시
3-2. WordPress 웹사이트에 대한 Pretty 퍼머링크 활성화 예시
3-3. 지원되지 않는 파일 확장자에 대한 요청 삭제 예시
3-4. 사용자 지정 경로 NGINX Rewrite 구성 예시
1. return
, nginx rewrite
및 try_files
지시문 비교
범용 NGINX Rewrite 을 위한 두 가지 지시문은 return
및 rewrite
이며 try_files
지시문은 요청을 애플리케이션 서버로 보내는 편리한 방법입니다. 지시문이 수행하는 작업과 차이점을 검토해 보겠습니다.
1-1. return
디렉티브
디렉티브 return
은 두 가지 범용 디렉티브 중 더 간단하므로 rewrite
가능한 경우 대신 사용하는 것이 좋습니다(이유 및 시기에 대해서는 나중에 설명). NGINX Rewrite 할 URL을 지정하는 server 또는 location 컨텍스트에 return 을 묶고 클라이언트가 향후 리소스 요청에 사용할 수정된(재작성된) URL을 정의합니다.
다음은 클라이언트를 새 도메인 이름으로 리다이렉션하는 매우 간단한 예입니다.
server {
listen 80;
listen 443 ssl;
server_name www.old-name.com;
return 301 $scheme://www.new-name.com$request_uri;
}
listen 지시문은 server 블록이 HTTP 및 HTTPS 트래픽 모두에 적용된다는 것을 의미합니다. Server_name 지시문은 도메인 이름 http://www.old-name.com을 가진 URL을 요청합니다. Return Directive는 NGINX에게 요청 처리를 중지하고 즉시 코드 301 (영구적으로 이동)과 지정된 다시 작성된 URL을 클라이언트에 보내도록 지시합니다. 다시 작성된 URL은 원래 요청 URL에서 값을 캡처하고 복제하기 위해 두 개의 nginx 변수를 사용합니다. $ scheme은 프로토콜 (http 또는 https)이고 $ request_uri는 인수를 포함한 전체 URI입니다.
For a code in the 3xx
series, the url
parameter defines the new (rewritten) URL.
return (301 | 302 | 303 | 307) url;
다른 코드의 경우 응답 본문에 표시되는 텍스트 문자열을 선택적으로 정의합니다( NotFound
for 와 같은 HTTP 코드의 표준 텍스트 404
는 여전히 헤더에 포함됨). 텍스트는 NGINX 변수를 포함할 수 있습니다.
return (1xx | 2xx | 4xx | 5xx) ["text"];
예를 들어 이 지시문은 유효한 인증 토큰이 없는 요청을 거부할 때 적절할 수 있습니다.
return 401 "Access denied because token is expired or invalid";
또한 302인 경우 코드를 생략하는 것과 같이 사용할 수 있는 몇 가지 구문 바로가기가 있습니다. return 지시문에 대한 참조 문서를 확인하십시오.
(경우에 따라 텍스트 문자열에서 원하는 것보다 더 복잡하거나 미묘한 응답을 반환해야 할 수 있습니다. 지시문을 사용하면 error_page
각 HTTP 코드에 대한 완전한 사용자 정의 HTML 페이지를 반환할 수 있을 뿐만 아니라 응답을 변경할 수 있습니다. 코드를 작성하거나 리다이렉션을 수행합니다.)
따라서 return 지시문은 사용하기 간단하고, 리다이렉션이 두 가지 조건을 충족할 때 적합합니다. NGINX Rewrite 된 URL은 server 또는 location 블록과 일치하는 모든 요청에 적합하며 표준 NGINX 변수를 사용하여 NGINX Rewrite 된 URL을 빌드할 수 있습니다.
1-2. nginx rewrite
디렉티브
그러나 URL 간의 보다 복잡한 구분을 테스트해야 하거나, 해당 NGINX 변수가 없는 원래 URL의 요소를 캡처하거나, 경로의 요소를 변경 또는 추가해야 하는 경우에는 어떻게 해야 할까요? 이러한 경우 rewrite 지시문을 사용할 수 있습니다.
return 지시문 과 마찬가지로 rewrite 지시문을 다시 작성할 URL을 정의하는 server 또는 location 컨텍스트에 return 지시문을 묶습니다. 그렇지 않으면 두 지시문이 유사하기보다는 다소 다르며 지시문을 올바르게 사용하기가 더 복잡할 수 있습니다. 구문은 충분히 간단합니다.
rewrite regex URL [flag];
그러나 첫 번째 인수 regex
는 NGINX Plus 및 NGINX가 지정된 정규 표현식과 일치하는 경우에만 URL을 다시 작성함을 의미합니다( server 또는 location 지시문과 일치하는 것 외에도 ). 추가 테스트는 NGINX가 더 많은 처리를 수행해야 함을 의미합니다.
두 번째 차이점은 rewrite
지시문이 301 코드 또는 302
. 다른 return 코드를 반환하려면 지시 뒤에 rewrite 지시문를 포함해야 합니다. (아래 예 참조)
마지막으로 rewrite 지시문은 반환과 같이 NGINX의 요청 처리를 반드시 중단하지 않으며 반드시 클라이언트로 리다이렉션을 보내는 것은 아닙니다. NGINX가 처리를 중단하거나 리다이렉션을 보내려는 플래그 또는 URL의 구문 포함 (URL의 구문 포함)을 명시적으로 표시하지 않는 한, 재작성 모듈 (Break, if, return, Rewrite)을 찾는 전체 구성을 통해 실행됩니다.NGINX Rewrite 된 URL이 rewrite 모듈의 후속 지시문과 일치하는 경우 NGINX Rewrite 된 URL에서 표시된 작업을 수행합니다.
여기에서 상황이 복잡해질 수 있으며 원하는 결과를 얻기 위해 지시문을 주문하는 방법을 신중하게 계획해야 합니다. 예를 들어 원래 location
블록과 그 안의 NGINX rewrite 규칙이 재작성된 URL과 일치하는 경우 NGINX는 반복해서 재작성을 기본 제공 제한인 10회까지 적용하여 루프에 들어갈 수 있습니다. 모든 세부 사항을 알아보려면 Rewrite 모듈에 대한 설명서를 참조하십시오. 앞에서 언급한 것처럼 가능한 경우 return 지시문을 대신 사용하는 것이 좋습니다.
다음은 rewrite 지시문을 사용하는 샘플 NGINX Rewrite 규칙입니다. 문자열 /download로 시작하고 경로의 뒷부분에 /media/ 또는 /audio/ 디렉토리를 포함하는 URL과 일치합니다. 해당 요소를 /mp3/로 바꾸고 적절한 파일 확장자 .mp3 또는 .ra를 추가합니다. 및 변수 $1
는 $2
변경되지 않는 경로 요소를 캡처합니다. 예를 들어 /download/cdn-west/media/file1은 /download/cdn-west/mp3/file1.mp3이 됩니다. 파일 이름에 확장자가 있는 경우(예: .flv ) 표현식에서 확장자를 제거하고 .mp3로 바꿉니다..
server {
# ...
rewrite ^(/download/.*)/media/(\w+)\.?.*$ $1/mp3/$2.mp3 last;
rewrite ^(/download/.*)/audio/(\w+)\.?.*$ $1/mp3/$2.ra last;
return 403;
# ...
}
처리 흐름을 제어하기 위해 rewrite 지시문에 플래그를 추가할 수 있다고 위에서 언급했습니다. 예제의 마지막 플래그는 그 중 하나입니다. 현재 server 또는 location 블록에서 후속 Rewrite-module 지시문을 건너뛰고 다시 작성된 URL과 일치하는 새 위치 검색을 시작하도록 NGINX에 지시합니다.
이 예제의 최종 return 지시문은 URL이 두 rewrite 지시문과 일치하지 않으면 403 코드가 클라이언트에 반환됨을 의미합니다.
1-3. try_files
디렉티브
return
및 rewrite
지시문과 마찬가지로 try_files
지시문은 server 또는 location 블록에 배치됩니다. 매개변수로 하나 이상의 파일 및 디렉토리 목록과 최종 URI를 사용합니다.
try_files file ... uri;
NGINX는 파일과 디렉터리의 존재를 순서대로 확인하고(root 및 alias 지시문의 설정에서 각 파일의 전체 경로 구성) 찾은 첫 번째 파일을 제공합니다. 디렉터리를 나타내려면 요소 이름 끝에 슬래시를 추가합니다. 파일이나 디렉터리가 없으면 NGINX는 최종 요소(uri)에서 정의한 URI로 내부 리디렉션을 수행합니다.
지시문이 작동 하려면 다음 예제와 같이 내부 리다이렉션을 캡처하는 블록 try_files
도 정의해야 합니다. location
마지막 요소는 초기 at 기호( @
)로 표시되는 명명된 위치일 수 있습니다.
지시문 try_files
은 일반적으로 $uri
도메인 이름 뒤의 URL 부분을 나타내는 변수를 사용합니다.
다음 예에서 NGINX는 클라이언트가 요청한 파일이 존재하지 않는 경우 기본 GIF 파일을 제공합니다. 클라이언트가 (예를 들어) http://www.domain.com/images/image1.gif 를 요청하면 NGINX는 먼저 위치에 적용되는 root 또는 alias 지시문 에 의해 지정된 로컬 디렉토리에서 image1.gif를 찾습니다. 단편). image1.gif가 없으면 NGINX는 image1.gif/를 찾고 , 없으면 /images/default.gif 로 리다이렉션합니다. 이 값은 두 번째 location 지시문과 정확히 일치하므로 처리가 중지되고 NGINX는 해당 파일을 제공하고 30초 동안 캐시되도록 표시합니다.
location /images/ {
try_files $uri $uri/ /images/default.gif;
}
location = /images/default.gif {
expires 30s;
}
2. 예 – 도메인 이름 표준화
NGINX rewrite rules의 가장 일반적인 용도 중 하나는 더 이상 사용되지 않거나 비표준 버전의 웹 사이트 도메인 이름을 캡처하여 현재 이름으로 리다이렉션하는 것입니다. 몇 가지 관련 사용 사례가 있습니다.
2-1. 이전 이름에서 현재 이름으로 리다이렉션
이 샘플 NGINX rewrite rule은 원래 요청 URL에서 값을 캡처하기 위해 두 개의 NGINX 변수를 사용하여 http://www.old-name.com 및 old-name.com의 요청을 http://www.new-name.com으로 영구적으로 리다이렉션합니다. $scheme은 원래 프로토콜 입니다. (http 또는 https) 및 $request_uri는 다음 인수를 포함하는 전체 URI(도메인 이름 뒤) 입니다.
server {
listen 80;
listen 443 ssl;
server_name www.old-name.com old-name.com;
return 301 $scheme://www.new-name.com$request_uri;
}
도메인 이름 뒤에 오는 URL 부분을 캡처하기 때문에 $request_uri
이 NGINX Rewrite 이전 사이트와 새 사이트 간에 페이지가 일대일 대응하는 경우에 적합합니다(예: http://www.new‑name.com/about 은 http://www.old‑name.com/about 과 같은 기본 콘텐츠 ). 도메인 이름을 변경하는 것 외에도 사이트를 재구성한 경우 대신 $request_uri
를 생략하여 모든 요청을 홈 페이지로 리다이렉션하는 것이 더 안전할 수 있습니다.
server {
listen 80;
listen 443 ssl;
server_name www.old-name.com old-name.com;
return 301 $scheme://www.new-name.com;
}
NGINX에서 URL을 rewrite하는 방법에 대한 다른 블로그에서는 다음과 같이 이러한 사용 사례에 대해 rewrite 지시문을 사용합니다.
# NOT RECOMMENDED
rewrite ^ $scheme://www.new-name.com$request_uri permanent;
NGINX가 정규표현식을 처리해야 하기 때문에 동등한 return
지시어보다 덜 효율적입니다. 정규식은 단순하지만(완전한 원래 URL과 일치하는 캐럿[ ^]) 정규표현식을 처리해야 합니다. 해당 return
지시어는 또한 인간 독자가 해석하기 더 쉽습니다.
2-2. www 접두사 추가 및 제거
다음 예는 www 접두사를 추가하고 제거합니다.
# add 'www'
server {
listen 80;
listen 443 ssl;
server_name domain.com;
return 301 $scheme://www.domain.com$request_uri;
}
# remove 'www'
server {
listen 80;
listen 443 ssl;
server_name www.domain.com;
return 301 $scheme://domain.com$request_uri;
}
다시 말하지만, 뒤따르는 동일한 rewrite 보다 return이 더 좋습니다. 다시 작성하려면 정규표현식을 해석하고 실제로 기본 제공 $request_uri 변수와 동일한 사용자 정의 변수($1)를 생성해야 합니다.
# NOT RECOMMENDED
rewrite ^(.*)$ $scheme://www.domain.com$1 permanent;
2-3. 모든 트래픽을 올바른 도메인 이름으로 리다이렉션
다음은 요청 URL이 server 및 location이 일치하지 않고 차단될 때 들어오는 트래픽을 웹사이트의 홈페이지로 리다렉션하는 특별한 경우입니다. 아마도 도메인 이름의 철자가 틀렸기 때문일 수 있습니다. default_server 매개변수를 listen 지시문에 결합하고 밑줄을 server_name 지시문 매개변수로 결합하여 작동합니다.
server {
listen 80 default_server;
listen 443 ssl default_server;
server_name _;
return 301 $scheme://www.domain.com;
}
실수로 실제 도메인 이름과 일치하는 것을 방지하기 위해 밑줄을 매개변수로 사용합니다. 밑줄을 도메인 이름으로 사용하는 사이트는 없다고 가정하는 것이 안전합니다. 그러나 구성의 다른 블록과 일치하지 않는 요청은 여기에서 끝나며 default_server 파라미터는 NGINX에 이 블록을 사용하도록 지시합니다. NGINX Rewrite 된 URL에서 $request_uri 변수를 생략하여 모든 요청을 홈페이지로 리다이렉션합니다. 잘못된 도메인 이름을 가진 요청은 특히 웹사이트에 존재하지 않는 URI를 사용할 가능성이 높기 때문에 좋은 생각입니다.
3. NGINX Rewrite 예시
3-1. 모든 요청이 SSL/TLS를 사용하도록 강제 예시
이 server
차단은 모든 방문자가 사이트에 대한 보안(SSL/TLS) 연결을 사용하도록 강제합니다.
server {
listen 80;
server_name www.domain.com;
return 301 https://www.domain.com$request_uri;
}
NGINX rewrite 규칙에 대한 다른 블로그에서는 다음과 같이 이 사용 사례에 대한 if
테스트 및 rewrite 지시문을 사용합니다.
# NOT RECOMMENDED
if ($scheme != "https") {
rewrite ^ https://www.mydomain.com$uri permanent;
}
그러나 이 방법은 NGINX가 조건을 평가하고 지시문의 정규식을 처리 해야 하기 때문에 추가 처리가 필요합니다.
3-2. WordPress 웹사이트에 대한 Pretty 퍼머링크 활성화 예시 (NGINX Rewrite)
NGINX 및 NGINX Plus는 WordPress를 사용하는 웹사이트에서 매우 인기 있는 애플리케이션 제공 플랫폼입니다. 다음 try_files
지시문은 NGINX에 파일의 존재를 확인한 $uri
다음 디렉토리를 확인하도록 지시합니다 $uri/
. 파일이나 디렉터리가 모두 존재하지 않는 경우 NGINX는 /index.php 에 대한 리다이렉션을 return하고 매개변수에 의해 캡처된 쿼리 문자열 인수를 전달합니다.
location / {
try_files $uri $uri/ /index.php?$args;
}
3-3. 지원되지 않는 파일 확장자에 대한 요청 삭제 예시 (NGINX Rewrite)
여러 가지 이유로 사이트에서 실행하지 않는 애플리케이션 서버에 해당하는 파일 확장자로 끝나는 요청 URL을 수신할 수 있습니다. Engine Yard 블로그의 이 예에서 애플리케이션 서버는 Ruby on Rails이므로 다른 애플리케이션 서버(Active Server Pages, PHP, CGI 등)에서 처리하는 파일 유형의 요청은 처리할 수 없으며 거부해야 합니다. 동적으로 생성된 자산에 대한 요청을 앱에 전달하는 server 블록에서 이 location 지시문은 Rails 대기열에 도달하기 전에 비 Rails 파일 유형에 대한 요청을 삭제합니다.
location ~ .(aspx|php|jsp|cgi)$ {
return 410;
}
엄밀히 말하면 응답 코드 410(사라짐)은 요청된 리소스가 이 URL에서 사용할 수 있었지만 더 이상 존재하지 않고 server가 현재 location를 알지 못하는 상황을 위한 것입니다. 응답 코드 404에 비해 장점은 리소스를 영구적으로 사용할 수 없음을 명시적으로 나타내므로 클라이언트가 요청을 다시 보내지 않는다는 것입니다.
응답 코드 및 텍스트 문자열과 같은 403(Forbidden)
설명을 반환하여 클라이언트에게 실패 이유를 보다 정확하게 표시할 수 있습니다. 대안으로 모든 거부(deny all) 지시문은 설명 없이 403을 return합니다.
location ~ .(aspx|php|jsp|cgi)$ {
deny all;
}
코드 403은 요청된 리소스가 존재함을 암묵적으로 확인하므로 클라이언트에 가능한 한 적은 정보를 제공하여 “불명료를 통한 보안”을 달성하려는 경우 코드 404가 더 나은 선택일 수 있습니다. 단점은 404가 실패가 일시적인지 영구적인지를 나타내지 않기 때문에 클라이언트가 반복적으로 요청을 재시도할 수 있다는 것입니다.
3-4. 사용자 지정 경로 NGINX Rewrite 구성 예시
MODXCloud의 이 예에는 URL 집합에 대한 컨트롤러 역할을 하는 리소스가 있습니다. 사용자는 리소스에 대해 더 읽기 쉬운 이름을 사용할 수 있으며 list.html 에서 컨트롤러가 처리하도록 NGINX Rewrite (리다렉션 아님)합니다.
rewrite ^/listings/(.*)$ /listing.html?listing=$1 last;
예를 들어 사용자에게 친숙한 URL http://mysite.com/listings/123은 listing.html 컨트롤러가 처리하는 URL인 http://mysite.com/listing.html?listing=123으로 다시 작성됩니다.
프로덕션급 NGINX인 NGINX Plus를 사용해 보려면 지금 무료 30일 평가판을 시작하거나 당사에 연락하여 사용 사례에 대해 문의하십시오.
또한 NGINX에 대한 최신 소식을 빠르게 전달받고 싶으시면 아래 뉴스레터를 구독하세요.