Ubuntu 20.04에서 PHP와 함께 Redis®를 사용하여 Rate Limiter로 사용하기
목차
소개
Rate limiting은 서버에서 자원 사용을 제한하는 방법입니다. 예를 들어, API (응용 프로그램 프로그래밍 인터페이스)를 실행하는 경우, 특정 시간 내에 사용자가 서버에 요청 할 수있는 횟수를 제한하는 캡을 설정할 수 있습니다. 웹 애플리케이션의 요청 속도를 제어하면 DoS (서비스 거부) 공격의 위험을 줄일 수 있습니다. 이를 통해 애플리케이션에 공정한 사용 정책을 적용할 수 있습니다. 대규모 웹 애플리케이션에서 특정 제약을 초과하지 않도록 작업을 제한하면 대역폭 및 리소스 사용에 대한 큰 비용을 절약할 수 있습니다.
이 가이드에서는 Vultr Ubuntu 20.04 서버에서 PHP를 사용하여 웹 리소스에 대한 요청을 제한하는 데 Redis® 서버를 사용합니다.
사전요구사항
이 가이드를 따르려면 다음 사항이 필요합니다:
- Ubuntu 20.04 서버
- sudo 사용자
- Lamp Stack
- Redis® 서버
Redis® 확장 설치
Vultr Ubuntu 클라우드 서버에 로그인하고 php-redis
확장을 설치하세요. 이 모듈을 사용하면 PHP 코드에서 Redis® 라이브러리를 사용할 수 있습니다.
$ sudo apt install -y php-redis
새 구성을 로드하기 위해 Apache 서버를 다시 시작하세요.
$ sudo systemctl restart apache2
PHP 리소스 생성
서버의 루트 디렉토리에 PHP 리소스를 만드세요.
$ sudo nano /var/www/html/resource.php
그런 다음 아래 정보를 파일에 추가하세요.
<?php
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
$key = $username;
$allowed_requests_per_period = 3;
$time_frame_in_seconds = 10;
$total_requests = 0;
if ($redis->exists($key)) {
$redis->INCR($key);
$total_requests = $redis->get($key);
if ($total_requests > $allowed_requests_per_period) {
echo "Hey, " . $username . ", You've already reached your requests limit. Total requests "
. $total_requests . " Allowed requests " . $allowed_requests_per_period;
exit();
}
} else {
$redis->set($key, 1);
$redis->expire($key, $time_frame_in_seconds);
$total_requests = 1;
}
echo "ok, total requests " . $total_requests;
} catch (Exception $e) {
echo $e->getMessage();
}
?>
파일 편집을 마치면 Ctrl + X, Y를 누르고 Enter를 눌러 저장하고 닫으세요.
/var/www/html/resource.php
코드 설명:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
위의 코드를 사용하여 로컬호스트의 포트 6379를 통해 Redis® 서버에 연결합니다.
$username = $_SERVER['PHP_AUTH_USER'];
$password = $_SERVER['PHP_AUTH_PW'];
PHP를 Apache 모듈로 실행하도록 구성한 경우, $_SERVER['PHP_AUTH_USER']
및 $_SERVER['PHP_AUTH_PW']
변수는 HTTP 기본 인증 자격 증명을 각각 $username
및 $password
변수에 할당합니다.
$key = $username;
웹 리소스에 액세스하는 여러 사용자가 있을 수 있으므로 $_SERVER['PHP_AUTH_USER']
변수에서 검색한 $username
변수로 Redis® 키를 생성하여 각 사용자의 트래픽을 독립적으로 추적할 수 있습니다.
$allowed_requests_per_period = 3;
$time_frame_in_seconds = 10;
위의 두 변수는 애플리케이션의 설정 사용 정책에 따라 웹 리소스 요청을 제한할 수 있게합니다. 이 예제에서는 사용자를 10초 동안 3회로 제한합니다. 필요에 따라 이 값을 조정하세요.
$total_requests = 0;
$total_requests
변수를 사용하여 사용자가 요청한 총 횟수를 초기화합니다.
if ($redis->exists($key)) {
$redis->INCR($key);
$total_requests = $redis->get($key);
if ($total_requests > $allowed_requests_per_period) {
echo "You've already reached your requests limit. Total requests "
. $total_requests . " Allowed requests " . $allowed_requests_per_period;
exit();
}
} else {
$redis->set($key, 1);
$redis->expire($key, $time_frame_in_seconds);
$total_requests = 1;
}
위의 코드는 Redis® 서버에서 $key
변수의 존재 여부를 확인합니다. 키가 존재하는 경우 $redis->INCR($key)
명령을 사용하여 1을 증가시킵니다. 키가 존재하지 않는 경우 $key
값을 1로 설정하고 $time_frame_in_seconds
변수로 정의된 만료 기간으로 새 키를 설정합니다. 그런 다음 $redis->get($key)
를 사용하여 $key
키의 현재 수를 가져옵니다. 값을 가져온 후, $total_requests
변수에 할당합니다.
다음으로 PHP의 if...else
구문을 사용하여 클라이언트가 정의된 기간 동안 허용된 총 요청을 초과하는지 평가합니다. 제한을 초과하면 사용자에게 오류를 반환합니다.
echo "ok, total requests " . $total_requests;
파일 아래쪽에는 사용자가 제한을 초과하지 않은 경우 사용자가 한 요청의 수를 출력합니다.
Redis® Rate Limiter 테스트
서버의 명령 프롬프트를 열고, curl 명령을 사용하여 위에서 생성한 /var/www/html/resource.php 웹 리소스를 조회합니다. 'http://localhost/resource.php?[1-20]'의 더미 쿼리 문자열은 스크립트가 Redis® 서버에 의해 제한되는지 확인하기 위해 리소스에 20번 액세스할 수 있도록 합니다.
$ curl --user john:SAMPLE_PASSWORD
-H "Accept: text/plain"
-H "Content-Type: text/plain"
-X GET http://localhost/resource.php?[1-20]
위 코드를 실행한후, 아래 출력을 받을 수 있어야 합니다.
[1/20]: http://localhost/resource.php?1 --> stdout
--_curl_--http://localhost/resource.php?1
ok, total requests 1
[2/20]: http://localhost/resource.php?2 --> stdout
--_curl_--http://localhost/resource.php?2
ok, total requests 2
[3/20]: http://localhost/resource.php?3 --> stdout
--_curl_--http://localhost/resource.php?3
ok, total requests 3
[4/20]: http://localhost/resource.php?4 --> stdout
--_curl_--http://localhost/resource.php?4
Hey, john, You've already reached your requests limit. Total requests 4 Allowed requests 3
[5/20]: http://localhost/resource.php?5 --> stdout
--_curl_--http://localhost/resource.php?5
Hey, john, You've already reached your requests limit. Total requests 5 Allowed requests 3
[6/20]: http://localhost/resource.php?6 --> stdout
...
첫 세 개의 요청이 수락되는 것을 확인할 수 있습니다. 그러나 네 번째 요청부터 PHP 스크립트가 비율 제한 오류를 발생시키기 시작했습니다.
결론
이 튜토리얼에서 Redis® 서버를 사용하여 Ubuntu 20.04에서 PHP로 리소스 사용을 제한하는 방법을 알아보았습니다. 이 가이드는 Redis®와 함께 소비자가 리소스를 제한하는 방법의 예시에 불과합니다. 이를 확장하여 웹 애플리케이션의 요구 사항에 맞게 조정 할 수 있습니다.
출처: https://docs.vultr.com/use-redis-as-a-rate-limiter-with-php-on-ubuntu-20-04
안정적이고 저렴한 가상 서버(VPS) 안내
안정적인 서버 호스팅을 찾고 계신가요? 지금 Vultr 호스팅을 한번 이용 해 보세요. 지금 보고 계신 HaruLogs 사이트도 Vultr에서 VPS 호스팅 하고 있습니다. 한국, 일본, 미국등 다양한 국가에 클릭 몇번으로 안정적이고 저렴한 VPS를 운영 할 수 있습니다.
아래 배너를 통해 회원 가입을 하시면 100달러의 무료 크레딧을 받을 수 있습니다. 100달러의 무료 크레딧은 Vultr의 최소 사양 VPS를 20대 동시 운영가능한 크레딧입니다.
Vultr 서비스 요약
- VPS
- 인스턴스
- AMD 또는 Intel High Performance 인스턴스 최저 $6 - 1vCPU, 1GB Memory, 2TB Bandwidth, 25GB NVMe
- 엣지
- 인스턴스
- Block Storage
- Object Storage (AWS S3 호환)
- Firewall
- Network
- Load Balancers
- Kubernetes
- Databases