Sfoglia il codice sorgente

Make it possible to exempt ips from the rate-limiter

LinQhost Managed hosting 5 anni fa
parent
commit
7d82c82fd9
5 ha cambiato i file con 128 aggiunte e 3 eliminazioni
  1. 4 0
      cfg/conf.sample.php
  2. 3 2
      composer.json
  3. 69 1
      composer.lock
  4. 1 0
      lib/Configuration.php
  5. 51 0
      lib/Persistence/TrafficLimiter.php

+ 4 - 0
cfg/conf.sample.php

@@ -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"

+ 3 - 2
composer.json

@@ -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"
@@ -39,4 +40,4 @@
 	"config" : {
 	"config" : {
 		"autoloader-suffix" : "DontChange"
 		"autoloader-suffix" : "DontChange"
 	}
 	}
-}
+}

+ 69 - 1
composer.lock

@@ -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",

+ 1 - 0
lib/Configuration.php

@@ -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,

+ 51 - 0
lib/Persistence/TrafficLimiter.php

@@ -1,4 +1,5 @@
 <?php
 <?php
+
 /**
 /**
  * PrivateBin
  * PrivateBin
  *
  *
@@ -29,6 +30,15 @@ class TrafficLimiter extends AbstractPersistence
      * @var    int
      * @var    int
      */
      */
     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])) {
@@ -99,6 +124,32 @@ class TrafficLimiter extends AbstractPersistence
         if (self::$_limit < 1) {
         if (self::$_limit < 1) {
             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)) {