Rate Limiting

Jeetkune

Administrator
Select the domain from your Cloudflare account where you want to apply the rules.
In the left menu, click:
1. Security,
2. WAF, which is the sub-button under Security.
On the page that appears, click the Rate Limiting Rules button.
1736440777197.png

Follow the steps shown in the first image to complete this section.
If you are hosting your chat site under a subfolder of the main domain, such as example.com/chat, example.com/blabla, or example.com/abc, you must specify the subfolder name instead of just /.

For example, if your chat site is hosted under the /chat/ folder, use /chat/. Similarly, if it's in a folder named /blabla/, use /blabla/. Always remember to include the correct folder name to ensure proper functionality.

and

Additionally, for specific paths such as /recovery.php hosted under a subfolder, you need to include the entire path only if the file is inside a subfolder.

For example:
  • If the recovery file is located at example.com/chat/recovery.php, specify /chat/recovery.php.
  • If it’s under example.com/blabla/recovery.php, specify /blabla/recovery.php.
However, if the /recovery.php file is located directly in the root (e.g., example.com/recovery.php), leave it as /recovery.php without any changes.

Also, even if your chat site is located in a subfolder, still keep / attached to protect your main domain.
This adjustment is crucial for correctly accessing your chat site when it’s not hosted directly under the root domain.
Code:
(http.request.uri.path in {"/"}) or (http.request.uri.path contains "/recovery.php")
1736440975295.png3.PNG4.PNG


The following is very important. Please read carefully.

With these rules, you have blocked everything after the yourdomain.com/ (or anything after the slash) from external attacks, including all PHP, CSS, JS, or anything else. However, for attacks targeting only your your_domain.com address, to avoid impacting users and server resources, you have applied the most effective rate limit provided by Cloudflare. You may wonder: "Could users get caught by the rate limit protection when they log in, and would chats be blocked?" No! Since the cookies of logged-in users are set to skip in the Known Bot step, logged-in users are never affected by file restrictions or rate limit rules.


Now, we move on to the final step. Whether you use Redis for Codychat or not, make sure that Redis server is installed on your server and also ensure that the PHP Redis extension is properly installed.. Even if you have disabled the Redis option from the Codychat admin panel, these rules work independently of Codychat and are only connected to the Redis installed on the server. If the Redis server is installed on your server, place the code at the very beginning of your index.php file, as shown in the example in the image below.

Important Note: You should add the code on top of the existing code that starts with <?php at the very beginning of your index.php file.
Make sure to replace the your_cookie in the code with the cookie name you have previously defined. This way, the Redis rate limit will never affect your logged-in users.

In the code, configure lines 5 and 6 to connect Redis to your setup:

  • For $redis->connect('');, replace the empty string with your Redis host or IP address (e.g., 'localhost' or the server’s IP).
  • For $redis->auth('');, if you have set a password in your redis.conf, place it between the single quotes. If no password is set, remove this line entirely.
Code:
$redis->connect('127.0.0.1', 6379);  // Use your Redis server's host/IP and port
$redis->auth('your_password');       // Replace 'your_password' with the password if set, or leave empty if not

Here are the Redis rate limit codes that you need to add to your index.php file.

Make sure to carefully add the code and replace 'your_cookie' with the cookie name you have previously defined.
Code:
<?php
// Error handling (optional, but recommended for production use)
try {
  $redis = new Redis();
  $redis->connect('');
  $redis->auth(''); // Store sensitive information securely (e.g., environment variables)
} catch (RedisException $e) {
  // Handle Redis connection errors gracefully (e.g., log the error)
  // Consider returning a user-friendly error message or retrying the connection
  echo "Error connecting to Redis: " . $e->getMessage();
  exit(1);
}

$max_calls_limit  = 2;
$time_period     = 3;
$blocking_time   = 180; // Blocking time in seconds (e.g., 60 seconds)

// Kullanıcı IP adresini almak için
if (!empty($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP)) {
    $user_ip_address = $_SERVER['HTTP_CF_CONNECTING_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
    // X-Forwarded-For başlığından ilk IP adresini al
    $forwarded_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
    $user_ip_address = trim($forwarded_ips[0]);

    // IP adresinin geçerli formatta olup olmadığını kontrol et
    if (!filter_var($user_ip_address, FILTER_VALIDATE_IP) ||
        (filter_var($user_ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) && preg_match("/^(192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)/", $user_ip_address))) {
        $user_ip_address = $_SERVER['REMOTE_ADDR']; // Geçerli değilse veya özel IP ise remote_addr kullan
    }
} else {
    // Eğer yukarıdaki başlıklar yoksa, doğrudan remote_addr kullan
    $user_ip_address = $_SERVER['REMOTE_ADDR'];
}

// IPv6 için özel IP kontrolü
if (filter_var($user_ip_address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && preg_match("/^fd00:/", $user_ip_address)) {
    // ULA (Unique Local Address) için, remote_addr kullan
    $user_ip_address = $_SERVER['REMOTE_ADDR'];
}

// Cache temizleme fonksiyonu
function cleanCache($redis) {
    $iterator = 0; // 0 ile başlat
    while ($keys = $redis->scan($iterator)) {
        foreach ($keys as $key) {
            // Eğer anahtar 'blocked_ip:' ile başlamıyorsa ve süre dolmuşsa, sil
            if (strpos($key, 'blocked_ip:') !== 0) {
                $redis->del($key); // Engellenmiş IP değilse sil
            } elseif (strpos($key, 'blocked_ip:') === 0) {
                // Engellenmiş IP anahtarları için süre kontrolü
                $expirationTime = $redis->get($key);
                if ($expirationTime && $expirationTime < time()) {
                    $redis->del($key); // Süresi dolmuşsa sil
                }
            }
        }
    }
}
if (!isset($_COOKIE['your_cookie'])) {
     cleanCache($redis); // Cache temizleme fonksiyonunu çağır
    // Eğer IP adresi Redis'te yoksa, ilk kez gelen istek
    if (!$redis->exists($user_ip_address)) {
        $redis->set($user_ip_address, 1);
        $redis->expire($user_ip_address, $time_period);
        $total_user_calls = 1;
    } else {
        // IP adresi Redis'te mevcut, istek sayısını artır
        $total_user_calls = $redis->INCR($user_ip_address);

        // Blocking mekanizması
        if ($total_user_calls > $max_calls_limit) {
            $blocking_key = "blocked_ip:{$user_ip_address}";

            // Eğer IP adresi daha önce engellenmemişse
            if (!$redis->exists($blocking_key)) {
                // IP adresini engelle
                $redis->set($blocking_key, time() + $blocking_time);
                $redis->expire($blocking_key, $blocking_time);
            }

            // Hemen yönlendir
            header("Location: https://yandex.com");
            exit();
        }
    }

    // Engellenmiş IP adresinin kontrolü
    $blocking_key = "blocked_ip:{$user_ip_address}";
    if ($redis->exists($blocking_key)) {
        // Eğer IP adresi engelliyse, yönlendirme yap
        if ($redis->get($blocking_key) > time()) {
            header("Location: https://yandex.com");
            exit();
        } else {
            // Engellenme süresi dolduysa, engeli kaldır
            $redis->del($blocking_key);
        }
    }
}

// Rest of your application logic here
?>

Based on these settings, if there is any suspicious activity (e.g., bots or threats), the system will redirect the traffic to a different site (such as yandex.com) for 3 minutes, and during this time, access to your site will be blocked for 3 minutes. Do not redirect to google.com, as this could result in your site being blacklisted. You can adjust the redirect site as needed.

If you have completed everything up to this step, these rules will work correctly. However, it is important to remember that in order for Redis server and these rules (Cloudflare rate limit and Redis server rate limit rules) to work more effectively, it is strongly recommended to use a VPS with at least 2 CPU cores. For users who do not use a VPS and rely on shared hosting, I will provide a separate guide on DDoS protection in another section.

[ Now, let's move on to the fourth step. ] 👈 click
 
Last edited:
Back
Top