NGINX 에서 경로별 최대 연결수 지정하기
NGINX 에서 경로 별 최대 연결수를 지정하는 이유는 클라이언트가 서버에 과도한 요청을 보내는 경우 ngx_http_limit_conn_module 을 사용하여 공격자가 서버 자원을 소모하는 것을 제한할 수 있습니다. DoS공격과 서버의 리소스와 정상적인 사용자에게 서비스를 계속 제공할 수 있습니다.
목차
1. ngx_http_limit_conn_module이란?
2. 테스트 환경 구성
3. NGINX 최대 연결 수 구성
1. ngx_http_limit_conn_module
ngx_http_limit_conn_module은 NGINX 에서 http block에 사용할 수 있는 모듈입니다.
해당 모듈은 클라이언트의 연결 수를 제한하여 서버의 리소스를 보호하고 부하를 관리하는 데 사용됩니다. 이 모듈은 클라이언트 IP 주소나 NGINX 변수를 지정 or 사용하거나 특정 서버 블록에 대해 동시 연결 수를 제어할 수 있습니다. (해당 모듈은 NGINX OSS, Plus 모두 사용가능합니다.)
NGINX에서 연결 수 제한은 모든 연결이 계산되지 않고 서버에서 처리 중인 요청이 있고 헤더가 읽은 경우에 계산됩니다.
2. 테스트 환경 구성
NGINX를 구성하기 전에 먼저 테스트를 위해 용량 응답이 큰 백엔드 서버를 배포합니다.
테스트 용도로 제작한 서버를 사용하였습니다. (github[app.py])
테스트 서버는 현재 실행 중인 서버 파일의 폴더에 있는 uploads 폴더 안에 있는 파일들을 다운로드 할 수 있습니다. (테스트에서 사용할 파일은 약 7.8GB 파일을 사용하였습니다.)해

NGINX를 준비합니다. 포스트에서는 NGINX Plus 1.25.5를 사용하였습니다.

3. NGINX 최대 연결 수 구성
NGINX에서 최대 연결 수를 구성합니다.
# /etc/nginx/conf.d/default.conf
1 limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
2
3 server {
4 listen 81;
5 server_name localhost;
6
7 location /{
8
9 proxy_pass http://localhost:5000/;
10 limit_conn conn_limit_per_ip 1;
11 }
12 }
1 : limit_conn_zone를 지정한 후 Key를 IP로 지정하여 IP별 최대 연결 수를 지정합니다. zone을 이용하여 Key에 대한 상태를 공유 할 zone을 지정합니다.
4~9 : 81번 포트를 사용하여 루트경로에 5000번 포트의 서버를 프록시합니다.
10 : 위에서 지정한 zone을 사용하고 최대 연결 수를 지정합니다. (예시에선 최대 연결 수가 1입니다.)
구성한 후 nginx -s reload를 이용하여 중단 없이 재시작합니다.
브라우저에서 구성한 포트로 접속한 후 파일(Downloads.zip약 7.8GB)을 다운로드하여 연결을 유지합니다.

다운로드가 진행되는 중에 동일한 NGINX 서버로 요청합니다.
위에서 구성한 것과 같이 최대 연결 수를 1개로 지정했으므로 다운로드를 진행하는 창 때문에 아래와 같이 503 에러가 뜨는 것을 볼 수 있습니다.

각 엔드포인트 별 최대 연결 수도 지정할 수 있습니다.
다음와 같이 구성합니다.
1 server {
2 listen 81;
3 server_name localhost;
3 location /one/{
4 proxy_pass http://localhost:1231/;
5 limit_conn conn_limit_per_ip 1;
6 }
7 location /two/{
8 proxy_pass http://localhost:1231/;
9 limit_conn conn_limit_per_ip 2;
10 }
11 }
5 : one 엔드포인트에 최대 연결 수를 1로 지정합니다.
9 : two 엔드포인트에 최대 연결 수를 2로 지정합니다.
one 엔드포인트는 최대 연결 수를 1로 지정했기 때문에 다운로드를 하고있는 창을 제외한 다른 창에서는 접속이 불가능합니다.


최대 연결 수를 2로 설정한 two 엔드 포인트에서는 최대 연결 수를 2로 지정하였기 때문에 다운로드가 진행중인 상태에서도 추가로 하나의 창에서 추가 다운로드가 가능합니다.


연결 수 초과에 대한 로그도 확인할 수 있습니다.
아래와 같이 로그 포멧과 access 로그를 추가합니다.
log_format limit_conn_l '$remote_addr - "$http_referer" '
'"$http_x_forwarded_for" - "$limit_conn_status"';
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
server {
listen 81;
server_name localhost;
access_log /var/log/nginx/testing/limit_conn.log limit_conn_l;
location /{
proxy_pass http://localhost:1231/;
limit_conn conn_limit_per_ip 1;
}
}
$limit_conn_status를 통해 연결 수 초과의 상태를 확인할 수 있습니다.
PASSED-통과됨
REJECTED-거절됨

위 사진과 같이 다운로드 이후 같은 IP에서 접속 시 요청이 거절되는 것을 볼 수 있습니다.
4. 결론
NGINX에서 ngx_http_limit_conn_module을 사용하여 경로별로 최대 연결 수를 제한하는 것은 서버 자원의 효율적 사용과 보안을 강화하는 중요한 방법입니다. 이를 통해 DoS 공격을 예방하고, 과도한 트래픽으로 인한 서버 과부하를 방지할 수 있습니다. 테스트 환경에서 백엔드 서버와 함께 구성한 후, 특정 경로에 대해 연결 수를 제한하고, 로그를 통해 상태를 확인할 수 있었습니다. 이러한 설정은 NGINX Plus와 같은 상용 버전뿐만 아니라 오픈소스 버전에서도 유용하게 사용될 수 있으며, 시스템의 성능과 안정성을 크게 향상시킬 수 있습니다.
NGINX Plus를 직접 사용해 보시려면 30일 무료 평가판을 신청하거나 NGINX STORE에 연락하여 논의하십시오.
댓글을 달려면 로그인해야 합니다.