Kong Gateway Rate Limiting 설정 방법과 예제
이 포스트에서는 Kong Gateway Rate Limiting 플러그인을 통해서 rate limiting을 설정하는 방법에 대해 설명합니다. Rate limiting 설정을 통해 DoS 공격과 같은 과도한 요청으로 인한 문제를 방지할 수 있습니다.
Kong Gateway를 설치하고, Kong Manager 대시보드를 구성하는 방법은 Kong Gateway, Kong Manager 설치 및 구성하기를 참고하세요.
목차
1. 환경 구성
2. Rate Limiting이란?
3. Kong Gateway Rate Limiting 설정하기
3-1. Kong Manager 대시보드로 Rate Limiting 설정하기
3-2. Kong Admin API로 Rate Limiting 설정하기
4. Kong Gateway Rate Limiting 적용 확인하기
1. 환경 구성
- Kong Gateway 서버 : Ubuntu 24.04 LTS
- Kong Gateway 버전 : 3.6.1 (OSS)
- Kong Gateway 서버 IP: 192.168.200.132
- 엔드포인트 NGINX 서버 IP: 192.168.200.160
Kong Gateway 포트 정보
- 8000 : HTTP 트래픽 수신
- 8443 : HTTPS 트래픽 수신
- 8001 : Kong Admin API (HTTP)
- 8444 : Kong Admin API (HTTPS)
- 8002 : Kong Manager 대시보드 (HTTP)
- 8445 : Kong Manager 대시보드 (HTTPS)
Gateway Services 정보

Routes 정보


Consumers 정보

2. Rate Limiting 이란?

Rate limiting은 엔드포인트 서비스로 전달되는 요청의 횟수를 제한하는 기능입니다. Rate limiting은 특정 시간 동안 허용되는 요청의 수를 제한하는 방식으로 동작합니다. 요청이 제한을 초과하면 클라이언트는 지정된 오류 메시지와 HTTP 상태 코드를 수신합니다.
Rate limiting 설정을 통해 DoS와 같은 공격 및 과도한 요청을 방지하거나 웹 스크래핑을 제한할 수 있습니다. 이를 통해 특정 사용자가 리소스를 독점하는 것을 방지하고 서비스의 안정성을 유지할 수 있습니다.
3. Kong Gateway Rate Limiting 설정하기
3-1. Kong Manager 대시보드로 Rate Limiting 설정하기

Kong Gateway의 rate limiting은 플러그인을 통해 설정할 수 있습니다. Kong Manager 대시보드의 plugins 메뉴에서 Rate Limiting 플러그인을 활성화하여 구성할 수 있습니다.

혹은 위와 같이 특정 gateway service, route, consumer의 plugins 메뉴에서 구성할 수 있습니다.
1. 플러그인을 활성화하여 해당 플러그인이 적용될 범위를 설정합니다.
global, gateway service, route, consumer 범위로 설정할 수 있습니다.

플러그인을 적용할 gateway service, route, consumer의 plugins 메뉴에서 구성할 경우 자동으로 설정됩니다.
2. 해당 플러그인의 이름과 분류를 위한 태그, 플러그인이 적용될 통신 프로토콜을 설정합니다.


설정 가능한 통신 프로토콜은 grpc, grpcs, http, https 4가지로, 기본값으로 모두 설정되어있습니다.
3. 요청 횟수 제한을 설정합니다.

요청 횟수 제한은 초, 분, 시간, 일, 월, 년 단위로 설정할 수 있습니다. 최소 1개의 단위를 설정해야 하며, 여러 단위를 동시에 설정할 수도 있습니다. 단, 하위 단위의 요청 횟수가 상위 단위의 요청 횟수를 초과할 수는 없습니다.
(예: second: 6, minute: 2 와 같은 설정은 불가능합니다.)
4. 추가 옵션들을 설정할 수 있습니다. 사진의 설정값들은 기본값들입니다.

- Error Code : 요청 횟수 제한을 초과할 시 반환할 응답 코드를 설정합니다
- Error Message : 요청 횟수 제한을 초과할 시 반환할 메시지를 설정합니다
- Fault Tolerant : Kong Gateway가 요청 정보를 기록하는 데이터 저장소와의 연결에 문제가 있을 경우의 작동 방식을 설정합니다.
- True로 설정하면 문제가 발생해도 요청을 전달합니다. 이 경우 rate limit가 적용되지 않습니다.
- False로 설정하면 요청을 전달하지 않고 500 에러를 반환합니다.

- Hide Client Headers : rate limit 설정 관련 응답 헤더의 숨김 여부를 설정합니다. False로 설정 시 다음과 같이 rate limit 정보를 사용자에게 반환합니다.


- Limit By : 제한을 적용할 기준을 설정할 수 있습니다.


header name, path와 같이 limit by 관련 설정을 지정할 수 있습니다.

- Policy : rate limit 설정을 나타냅니다. 설정하지 않으면 500 에러를 반환합니다.
- local : 단일 Kong Gateway에서 요청 정보를 저장합니다.
- cluster : 클러스터의 모든 Kong Gateway가 요청 정보를 공유합니다.
- redis : redis DB와 연동하여 요청 정보를 공유합니다.

Redis policy 적용을 위한 Redis DB 연동 옵션입니다.

- Sync Rate : 요청 정보를 데이터 저장소와 연동할 주기를 초 단위로 설정합니다. -1로 설정되면 동기 방식으로 작동하며, 요청이 들어올 때마다 동기화가 이루어집니다. Redis policy 적용 시 사용할 수 있습니다.
5. 설정이 완료된 플러그인을 생성하고, 설정을 확인합니다.

route/gateway service/consumer 범위로 설정 시 해당 ID가 표기되며, global 범위로 설정 시 모두 비어있습니다.



추가 설정값들도 확인할 수 있습니다.
3-2. Kong Admin API로 Rate Limiting 설정하기
Kong Admin API로 POST 메서드 요청을 전송하여 rate limiting 플러그인을 적용할 수 있습니다.
1. global 범위 플러그인 적용
다음과 같이 Kong Admin API의 /plugins 경로로 요청을 전송하여 생성할 수 있습니다.
global 범위의 rate limiting 플러그인은 2개 이상 존재할 수 없기 때문에 기존에 대시보드에서 생성한 플러그인은 제거 후 새로 생성했습니다.
$ curl -i -X POST http://192.168.200.132:8001/plugins \ # global 범위 적용 시
--data name=rate-limiting \ # 적용할 플러그인 이름 (필수)
--data config.minute=5 \ # rate limiting 설정 (필수)
--data instance_name=global-rate-limit # 플러그인 instance name 설정 (선택)
생성 성공 시 다음과 같이 플러그인 설정 내용 전체를 반환합니다.
{"id":"2e3a7e4b-68f2-4144-87d5-745cd4e14447","enabled":true,"route":null,"name":"rate-limiting","config":{"path":null,"policy":"local","redis_port":6379,"fault_tolerant":true,"redis_password":null,"hide_client_headers":false,"redis":{"ssl":false,"ssl_verify":false,"username":null,"host":null,"port":6379,"timeout":2000,"password":null,"database":0,"server_name":null},"redis_ssl":false,"limit_by":"consumer","redis_ssl_verify":false,"error_code":429,"error_message":"API rate limit exceeded","sync_rate":-1,"redis_timeout":2000,"redis_database":0,"redis_server_name":null,"redis_username":null,"redis_host":null,"second":null,"minute":5,"hour":null,"day":null,"month":null,"year":null,"header_name":null},"service":null,"updated_at":1718092513,"created_at":1718092513,"tags":null,"consumer":null,"protocols":["grpc","grpcs","http","https"],"instance_name":"global-rate-limit"}
대시보드의 plugins 메뉴에서 생성된 것을 확인할 수 있습니다.

2. gateway service 범위 플러그인 적용
gateway service 범위 적용의 경우 /services/<gateway service 명 혹은 ID>/plugins 경로로 요청을 전송하여 생성할 수 있습니다. 생성 성공 시 플러그인 설정 내용 전체를 반환합니다.
$ curl -i -X POST http://192.168.200.132:8001/services/NGINX-API/plugins \
--data name=rate-limiting \
--data config.minute=2 \
--data instance_name=service-rate-limit
대시보드에서 지정한 gateway service에 생성된 것을 확인할 수 있습니다.

3. route 범위 플러그인 적용
route 범위 적용의 경우 /routes/<route 명 혹은 ID>/plugins 경로로 요청을 전송하여 생성할 수 있습니다. 생성 성공 시 플러그인 설정 내용 전체를 반환합니다.
$ curl -i -X POST http://192.168.200.132:8001/routes/NGINX-API-route/plugins \
--data name=rate-limiting \
--data config.year=5 \
--data instance_name=route-rate-limit
대시보드에서 지정한 route에 생성된 것을 확인할 수 있습니다.

4. consumer 범위 플러그인 적용
consumer 범위 적용의 경우 /consumers/<consumer 명 혹은 ID>/plugins 경로로 요청을 전송하여 생성할 수 있습니다. 생성 성공 시 플러그인 설정 내용 전체를 반환합니다.
$ curl -i -X POST http://192.168.200.132:8001/consumers/nginxstore/plugins \
--data name=rate-limiting \
--data config.year=5 \
--data instance_name=consumer-rate-limit
대시보드에서 지정한 consumer에 생성된 것을 확인할 수 있습니다.

4. Kong Gateway Rate Limiting 적용 확인하기

앞서 설정한 rate limiting 플러그인 중 NGINX-API gateway service에 대한 rate limit 설정을 적용해서 확인해 보겠습니다. 해당 설정은 분당 2회까지의 요청을 허용하고 있습니다.
1. 192.168.200.132:8000/nginxapi 경로로 요청을 보내 응답을 확인합니다.
응답의 헤더를 통해 rate limit 관련 정보를 확인할 수 있습니다.
$ curl 192.168.200.132:8000/nginxapi -I
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 621
Connection: keep-alive
X-RateLimit-Limit-Minute: 2 # 분당 요청 설정 횟수
RateLimit-Remaining: 1 # 잔여 요청 횟수
RateLimit-Reset: 42 # 요청 횟수 초기화까지 남은 시간
RateLimit-Limit: 2
X-RateLimit-Remaining-Minute: 1
Server: nginx/1.25.3
Date: Mon, 03 Jun 2024 14:18:08 GMT
Last-Modified: Mon, 03 Jun 2024 12:53:49 GMT
ETag: "665dbcdd-26d"
Accept-Ranges: bytes
X-Kong-Upstream-Latency: 1
X-Kong-Proxy-Latency: 1
Via: kong/3.6.1
X-Kong-Request-Id: 2e05207705c44a2a238eee138b40b821
Hide Client Headers 옵션을 True로 설정 시, rate limit 설정 관련 헤더는 반환되지 않습니다.
2. 동일 요청을 2번 더 보내 응답을 확인합니다.
$ curl 192.168.200.132:8000/nginxapi -I && curl 192.168.200.132:8000/nginxapi -I
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 621
Connection: keep-alive
X-RateLimit-Limit-Minute: 2
RateLimit-Remaining: 0
RateLimit-Reset: 40
RateLimit-Limit: 2
X-RateLimit-Remaining-Minute: 0
Server: nginx/1.25.3
Date: Mon, 03 Jun 2024 14:18:10 GMT
Last-Modified: Mon, 03 Jun 2024 12:53:49 GMT
ETag: "665dbcdd-26d"
Accept-Ranges: bytes
X-Kong-Upstream-Latency: 2
X-Kong-Proxy-Latency: 0
Via: kong/3.6.1
X-Kong-Request-Id: f9fde649a4d187435d7250574e0a4d6f
HTTP/1.1 429 Too Many Requests
Date: Tue, 11 Jun 2024 08:41:20 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
X-RateLimit-Limit-Minute: 2
RateLimit-Remaining: 0
RateLimit-Reset: 40
Retry-After: 40 # 다시 연결 가능한 시간
RateLimit-Limit: 2
X-RateLimit-Remaining-Minute: 0
Content-Length: 92
X-Kong-Response-Latency: 0
Server: kong/3.6.1
X-Kong-Request-Id: 68332578d7af226104b9ac6df107b543
2번의 요청을 추가로 전송하자, 분당 2회의 rate limit 설정이 적용되어 첫 요청은 200 상태 코드를 반환하고, 두 번째 요청은 rate limit 설정에 따라 429 상태 코드를 반환합니다.
댓글을 달려면 로그인해야 합니다.