NGINX에서 사용할 정규 표현식(regex)을 작성하던 중, 실제 NGINX 구성 내에서 정규 표현식을 손쉽게 테스트할 방법이 떠올랐습니다. (이 정규 표현식 테스터는 NGINX Open Source와 NGINX Plus에서 동일하게 작동하며, 읽기 쉽도록 이 글에서는 간단히 NGINX라고 부르겠습니다.)
정규 표현식 지원은 NGINX의 강력한 기능 중 하나이지만, 정규 표현식은 복잡하고 정확하게 작성하기 어려울 수 있으며, 특히 자주 사용하지 않는 경우에는 더욱 그렇습니다. NGINX에서는 location, map, rewrite, 서버 이름 등 구성의 여러 부분에 정규 표현식을 사용할 수 있습니다. 여기서 설명하는 테스터는 location과 map에 사용되는 정규 표현식을 위한 것입니다.
대부분의 정규식에 적합한 무료 온라인 정규식 테스터도 있지만, NGINX는 웹 애플리케이션에 최적화된 몇 가지 비표준 단축 표기법을 사용합니다. 예를 들어 표준 정규식에서와 달리 URI의 슬래시(/)를 이스케이프할 필요가 없습니다. 또한 map에서 정규식을 사용할 때는 일치 결과에 따라 설정할 값을 지정합니다. 다른 정규식 테스터를 사용하면 정규식을 수정해야 할 수도 있고, map의 경우에는 어떤 값이 설정될지 추론해야 할 수도 있습니다. 아울러 실제 환경에서 실제 정규식 엔진을 사용해 정규식을 테스트할 수 있으면 언제나 유용합니다.
참고:
- NGINX는 Perl 호환 정규 표현식(PCRE)을 사용하며, 이 글은 독자가 NGINX와 정규 표현식에 대한 기본적인 이해를 갖추고 있다고 가정합니다. 정규식을 작성하는 방법에 대한 설명은 이 글의 범위를 벗어나며, 댓글에서 이와 관련된 추가 질문에 답변해 드릴 수 없는 점 양해 부탁드립니다. 정규식 작성에 유용한 도구나 문서를 제공하는 웹사이트는 많습니다. 그중 유용하다고 생각하는 두 곳은 다음과 같습니다:
- 테스터는 다음 두 컨텍스트에서 정규식을 처리합니다. 바로
map{}블록과 HTTPlocation{}블록입니다. 아래에서는 각 경우에 정규식이 어떻게 작동하는지 간략히 설명합니다. NGINX가 모든 컨텍스트에서 정규식을 처리하는 방식을 설명하는 것은 이 게시물의 범위를 벗어나므로, 자세한 내용은 다음 문서를 참조하세요:- 상태 확인:
- HTTP – nginx.org 및 NGINX Plus 관리 가이드
- TCP – nginx.org 및 NGINX Plus 관리 가이드
- UDP – nginx.org 및 NGINX Plus 관리 가이드
location{}블록 – nginx.org 및 NGINX Plus 관리 가이드map{}블록 – nginx.org- URI 재작성 – nginx.org 및 NGINX Plus 관리 가이드
- 가상 서버 이름 – nginx.org 및 NGINX Plus 관리 가이드
- 상태 확인:
- 이 테스터는 의도적으로 최대한 단순하게 설계되었으며, 사용자가 작성한 정규식을 실제 NGINX 정규식 엔진을 사용하여 map 및 HTTP location에서 테스트한다는 한 가지 목적만을 수행합니다. 따라서 정상적으로 작동하는 NGINX 구성을 만들기 위해서는 최소한의 정보만 제공하면 됩니다. 테스트 전에 정규식의 유효성을 검사하는 기능과 같은 기능을 추가할 계획은 없습니다. 이는 단순성이라는 기본 원칙에 어긋나기 때문입니다. 물론 버그는 기꺼이 수정하겠습니다. 버그는 Issues 탭을 통해 GitHub 저장소에 제출해 주세요.
개요
정규식 테스터를 자세히 살펴보기에 앞서, 먼저 NGINX의 location과 map에서 정규식을 어떻게 사용할 수 있는지 알아보겠습니다.
로케이션
NGINX의 정규 표현식 location{} 블록은 다음과 같은 형식입니다:
location regex {
#...
}예를 들어, 다음 정규식을 사용하는 location{} 블록은 URI가 myapp/파일 이름.php로 끝나는 모든 PHP 요청을 처리합니다. 예를 들면 /test/myapp/hello.php 및 /myapp/hello.php가 있습니다. 물결표 뒤의 별표(~*)는 대소문자를 구분하지 않고 일치하도록 합니다.
location ~* /myapp/.+\.php$ {
#...
}NGINX와 정규식 테스터는 캡처 그룹의 위치 기반 참조를 location{} 블록에서 지원합니다. 다음 예시에서 첫 번째 그룹은 PHP 파일 이름 앞의 모든 내용을 캡처하고, 두 번째 그룹은 PHP 파일 이름을 캡처합니다:
location ~* (.*/myapp)/(.+\.php)$ {
#...
}URI /myapp/hello.php의 경우 변수 $1은(는) /myapp(으)로 설정되고, $2은(는) hello.php(으)로 설정됩니다.
NGINX는 명명된 캡처 그룹도 지원합니다:
location ~* (?<begin>.*myapp)/(?<end>.+\.php)$ {
#...
}이 경우 변수 $begin은 /myapp으로 설정되고, $end는 hello.php로 설정됩니다.
정규식 테스터는 이름이 지정된 캡처 그룹을 지원하지만, 출력에서는 이를 위치 기반 캡처 그룹처럼 처리하여 이름 대신 순번을 표시합니다.
맵
NGINX map{} 정규 표현식을 사용하는 블록의 형식은 다음과 같습니다:
map variable-to-test variable-to-set {
regex1 value-to-set-if-match;
regex2 value-to-set-if-match;
#...
regexN value-to-set-if-match;
default value-to-set-if-no-match;
}예를 들어, 이 map{} 블록은 URI($uri 변수에 기록된 값)가 .php로 끝나면 $isphp 변수를 1로 설정하고, 그렇지 않으면 0으로 설정합니다(대소문자를 구분함):
map $uri $isphp {
~\.php$ 1;
default 0;
}맵의 경우 NGINX와 정규식 테스터는 위치 기반 캡처 그룹과 명명된 캡처 그룹을 모두 지원합니다.
예를 들어 다음 두 map은 모두 변수 $fileext를 파일 확장자 값으로 설정하며, 이 예에서는 해당 값이 $1에도 캡처됩니다:
map $uri $fileext {
~*.+\.(.+)$ $1;
default '';
}그리고 이 예시에서 $ext는 다음과 같습니다:
map $uri $fileext {
~*.+\.(?<ext>.+)$ $ext;
default '';
}정규식 테스터는 map{} 블록이 http{} 및 stream{} 컨텍스트에서 구문과 동작이 동일하므로 두 컨텍스트 모두에서 사용할 수 있습니다. 단, 맵이 stream{} 컨텍스트에 있는 경우 테스터 출력에서 map{} 블록만 사용할 수 있습니다. 자세한 내용은 아래 참고 사항을 참조하세요.
정규식 테스터
정규식 테스터는 NGINX와 NGINX Unit이 설치된 Docker 컨테이너에 구현되어 있습니다. NGINX Unit은 두 가지 버전의 PHP 페이지를 제공합니다. 하나는 location{} 블록의 정규식을 위한 페이지이고, 다른 하나는 map{} 블록의 정규식을 위한 페이지입니다. 두 페이지에서 사용자에게 요구하는 입력은 서로 다릅니다:
- Location 페이지:
- 정규식
- 대소문자 구분
- URI
- 지도 페이지:
- 정규식
- 대소문자 구분
- 테스트할 값(
map지시문의 첫 번째 매개변수인 변수의 값) - The value to set in the variable specified as the second parameter to the
map지시문의 두 번째 매개변수로 지정된 변수에 설정할 값
정보를 입력한 후 테스트 버튼을 클릭합니다. 테스터가 필요한 NGINX 구성 파일을 생성하고 구성을 다시 로드한 다음, 정규식을 테스트하기 위한 요청을 전송합니다. 이후 결과가 표시되며 일치 항목이 발견되었는지 여부를 알려 줍니다. 일치 항목이 발견된 경우 위치 테스터 페이지에는 캡처 그룹의 값이 표시되고, 맵 테스터 페이지에는 맵에서 설정한 값이 표시됩니다.
Location 페이지 예시
이 예제는 정규식 (.*myapp)/(.+\.php)$을 URI /myapp/hello.php에 대해 대소문자를 구분하지 않고 테스트한 결과를 보여 줍니다:

지도 페이지 예시
이 예제는 정규식 .+\.(?<ext>.*)$을 값 /myapp/hello.php에 대해 대소문자를 구분하지 않고 테스트한 결과를 보여 주며, 명명된 캡처 그룹 $ext를 설정할 값으로 사용합니다:

참고: 맵이 stream{} 컨텍스트에 있는 경우, 출력에서 map{} 블록만 구성에 사용할 수 있습니다. server{} 블록에는 location{} 블록이 포함되어 있으며, 이 블록은 stream{} 컨텍스트에서 지원되지 않으므로 사용할 수 없습니다.
결론
보시다시피 NGINX 구성은 매우 짧고 간단합니다. 실제로 복잡한 작업은 PHP 페이지에서 처리합니다. 이 페이지는 사용자가 입력한 값을 바탕으로 필요한 NGINX 구성 파일을 생성하고, NGINX를 다시 로드한 다음 NGINX에 요청을 보내고 결과를 표시합니다.
정규식 테스터를 직접 사용해 볼 수 있습니다. 모든 코드는 GitHub 리포지토리(https://github.com/nginxinc/NGINX-Demos/tree/master/nginx-regex-tester)에서 확인할 수 있습니다.
정규식 테스터를 쉽게 실행할 수 있도록 필요한 모든 파일이 포함되어 있습니다. Docker 이미지를 빌드하고 컨테이너를 생성하려면 다음 명령을 실행하기만 하면 됩니다:
$ docker-compose up -d그런 다음 브라우저에서 http://Docker-host/regextester.php로 이동합니다.
정규 표현식을 사용할 때 이 테스터가 도움이 되고, NGINX의 강력함과 유연성, 간결함을 조금이나마 엿볼 수 있기를 바랍니다.
NGINX Plus에서 정규식 테스터를 사용해 보려면 지금 30일 무료 체험을 시작하거나 문의하여 사용 사례에 대해 상담해 보세요.
작성자 소개

관련 블로그 게시물
시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.
F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.
Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.
진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.
NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.
Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.