Make it possible to exempt ips from the rate-limiter
This commit is contained in:
parent
d65bf02d78
commit
7d82c82fd9
5 changed files with 128 additions and 3 deletions
|
@ -135,6 +135,10 @@ markdown = "Markdown"
|
||||||
; Set this to 0 to disable rate limiting.
|
; Set this to 0 to disable rate limiting.
|
||||||
limit = 10
|
limit = 10
|
||||||
|
|
||||||
|
; Set ips (v4|v6) which should be exempted for the rate-limit. CIDR also supported. Needed to be comma separated.
|
||||||
|
; Unset for enabling and invalid values will be ignored
|
||||||
|
; eg: exemptedIp = '1.2.3.4,10.10.10/24'
|
||||||
|
|
||||||
; (optional) if your website runs behind a reverse proxy or load balancer,
|
; (optional) if your website runs behind a reverse proxy or load balancer,
|
||||||
; set the HTTP header containing the visitors IP address, i.e. X_FORWARDED_FOR
|
; set the HTTP header containing the visitors IP address, i.e. X_FORWARDED_FOR
|
||||||
; header = "X_FORWARDED_FOR"
|
; header = "X_FORWARDED_FOR"
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
"require" : {
|
"require" : {
|
||||||
"php" : "^5.6.0 || ^7.0 || ^8.0",
|
"php" : "^5.6.0 || ^7.0 || ^8.0",
|
||||||
"paragonie/random_compat" : "2.0.19",
|
"paragonie/random_compat" : "2.0.19",
|
||||||
"yzalis/identicon" : "2.0.0"
|
"yzalis/identicon" : "2.0.0",
|
||||||
|
"mlocati/ip-lib": "^1.14"
|
||||||
},
|
},
|
||||||
"require-dev" : {
|
"require-dev" : {
|
||||||
"phpunit/phpunit" : "^4.6 || ^5.0"
|
"phpunit/phpunit" : "^4.6 || ^5.0"
|
||||||
|
|
70
composer.lock
generated
70
composer.lock
generated
|
@ -4,8 +4,76 @@
|
||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "9d110873bf15a6abd66734e8a818134c",
|
"content-hash": "8138b0e4bb3fcaab9ca4c02bbe35d891",
|
||||||
"packages": [
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "mlocati/ip-lib",
|
||||||
|
"version": "1.14.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/mlocati/ip-lib.git",
|
||||||
|
"reference": "882bc0e115970a536b13bcfa59f312783fce08c8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/882bc0e115970a536b13bcfa59f312783fce08c8",
|
||||||
|
"reference": "882bc0e115970a536b13bcfa59f312783fce08c8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.3"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"ext-pdo_sqlite": "*",
|
||||||
|
"phpunit/dbunit": "^1.4 || ^2 || ^3 || ^4",
|
||||||
|
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"IPLib\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Michele Locati",
|
||||||
|
"email": "mlocati@gmail.com",
|
||||||
|
"homepage": "https://github.com/mlocati",
|
||||||
|
"role": "Author"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Handle IPv4, IPv6 addresses and ranges",
|
||||||
|
"homepage": "https://github.com/mlocati/ip-lib",
|
||||||
|
"keywords": [
|
||||||
|
"IP",
|
||||||
|
"address",
|
||||||
|
"addresses",
|
||||||
|
"ipv4",
|
||||||
|
"ipv6",
|
||||||
|
"manage",
|
||||||
|
"managing",
|
||||||
|
"matching",
|
||||||
|
"network",
|
||||||
|
"networking",
|
||||||
|
"range",
|
||||||
|
"subnet"
|
||||||
|
],
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/sponsors/mlocati",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://paypal.me/mlocati",
|
||||||
|
"type": "other"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2020-12-31T11:30:02+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "paragonie/random_compat",
|
"name": "paragonie/random_compat",
|
||||||
"version": "v2.0.19",
|
"version": "v2.0.19",
|
||||||
|
|
|
@ -82,6 +82,7 @@ class Configuration
|
||||||
'limit' => 10,
|
'limit' => 10,
|
||||||
'header' => null,
|
'header' => null,
|
||||||
'dir' => 'data',
|
'dir' => 'data',
|
||||||
|
'exemptedIp' => null,
|
||||||
),
|
),
|
||||||
'purge' => array(
|
'purge' => array(
|
||||||
'limit' => 300,
|
'limit' => 300,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PrivateBin
|
* PrivateBin
|
||||||
*
|
*
|
||||||
|
@ -30,6 +31,15 @@ class TrafficLimiter extends AbstractPersistence
|
||||||
*/
|
*/
|
||||||
private static $_limit = 10;
|
private static $_limit = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* listed ips are exempted from limits, defaults to null
|
||||||
|
*
|
||||||
|
* @access private
|
||||||
|
* @static
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $_exemptedIp = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* key to fetch IP address
|
* key to fetch IP address
|
||||||
*
|
*
|
||||||
|
@ -51,6 +61,18 @@ class TrafficLimiter extends AbstractPersistence
|
||||||
self::$_limit = $limit;
|
self::$_limit = $limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set a list of ip(ranges) as array
|
||||||
|
*
|
||||||
|
* @access public
|
||||||
|
* @static
|
||||||
|
* @param array $exemptedIps
|
||||||
|
*/
|
||||||
|
public static function setExemptedIp($exemptedIp)
|
||||||
|
{
|
||||||
|
self::$_exemptedIp = $exemptedIp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set configuration options of the traffic limiter
|
* set configuration options of the traffic limiter
|
||||||
*
|
*
|
||||||
|
@ -60,8 +82,11 @@ class TrafficLimiter extends AbstractPersistence
|
||||||
*/
|
*/
|
||||||
public static function setConfiguration(Configuration $conf)
|
public static function setConfiguration(Configuration $conf)
|
||||||
{
|
{
|
||||||
|
|
||||||
self::setLimit($conf->getKey('limit', 'traffic'));
|
self::setLimit($conf->getKey('limit', 'traffic'));
|
||||||
self::setPath($conf->getKey('dir', 'traffic'));
|
self::setPath($conf->getKey('dir', 'traffic'));
|
||||||
|
self::setExemptedIp($conf->getKey('exemptedIp', 'traffic'));
|
||||||
|
|
||||||
if (($option = $conf->getKey('header', 'traffic')) !== null) {
|
if (($option = $conf->getKey('header', 'traffic')) !== null) {
|
||||||
$httpHeader = 'HTTP_' . $option;
|
$httpHeader = 'HTTP_' . $option;
|
||||||
if (array_key_exists($httpHeader, $_SERVER) && !empty($_SERVER[$httpHeader])) {
|
if (array_key_exists($httpHeader, $_SERVER) && !empty($_SERVER[$httpHeader])) {
|
||||||
|
@ -100,6 +125,32 @@ class TrafficLimiter extends AbstractPersistence
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if $_ipKey is exempted from ratelimiting
|
||||||
|
if (!is_null(self::$_exemptedIp)) {
|
||||||
|
$exIp_array = explode(",", self::$_exemptedIp);
|
||||||
|
foreach ($exIp_array as $ipRange) {
|
||||||
|
// Match $_ipKey to $ipRange and if it matches it will return with a true
|
||||||
|
$address = \IPLib\Factory::addressFromString($_SERVER[self::$_ipKey]);
|
||||||
|
$range = \IPLib\Factory::rangeFromString(trim($ipRange));
|
||||||
|
// If $range is null something went wrong (possible invalid ip given in config)
|
||||||
|
if ($range == null) {
|
||||||
|
$contained = false;
|
||||||
|
} else {
|
||||||
|
// Ip-lib does throws and exception when something goes wrong, if so we want to catch it and set contained to false
|
||||||
|
try {
|
||||||
|
$contained = $address->matches($range);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// If something is wrong with matching the ip, we set $contained to false
|
||||||
|
$contained = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Matches return true!
|
||||||
|
if ($contained == true) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$file = 'traffic_limiter.php';
|
$file = 'traffic_limiter.php';
|
||||||
if (self::_exists($file)) {
|
if (self::_exists($file)) {
|
||||||
require self::getPath($file);
|
require self::getPath($file);
|
||||||
|
|
Loading…
Reference in a new issue