Saturday, September 7, 2024

PHP Ban IP to Cloudflare API Script

Usage:
Run the script periodically using a cron job (Linux) or Task Scheduler (Windows) to handle blocking and removal of expired blocks.

Ensure paths to logs and other configurations are updated to reflect your actual setup.

<?php
// Cloudflare API settings
$apiKey = "your_cloudflare_api_key"; // Global API Key
$authEmail = "your_cloudflare_email"; // Cloudflare account email
$zoneID = "your_zone_id"; // Zone ID
$logPath = "C:pathtoaccess.log"; // Path to Apache access log
$blockLogPath = "C:pathtoblock.log"; // Path to log block actions
$blockRemoveLogPath = "C:pathtoblock_remove.log"; // Path to log block removal actions
$threshold = 10; // Number of 404s to trigger a block
$timeWindowMinutes = 10; // Time window in minutes for analysis
$blockDurationHours = 1; // Duration to block IP in hours

// Current timestamp minus time window (in seconds)
$timeWindow = time() - ($timeWindowMinutes * 60);

// Function to log messages to a file
function logMessage($message, $logFilePath) {
    $timestamp = date('Y-m-d H:i:s');
    file_put_contents($logFilePath, "[$timestamp] $message" . PHP_EOL, FILE_APPEND);
}

// Function to check if an IP is already blocked
function isIPBlocked($ip, $apiKey, $authEmail, $zoneID) {
    $url = "https://api.cloudflare.com/client/v4/zones/$zoneID/firewall/access_rules/rules?configuration[target]=ip&configuration[value]=$ip";

    $headers = [
        "Content-Type: application/json",
        "X-Auth-Key: $apiKey",
        "X-Auth-Email: $authEmail"
    ];

    $options = [
        'http' => [
            'header' => implode("rn", $headers),
            'method' => 'GET'
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    if ($result === FALSE) {
        $error = "Failed to check if IP $ip is blocked";
        logMessage($error, $logFilePath);
        echo "$errorn";
        return false;
    }

    $response = json_decode($result, true);

    if (isset($response['result']) && count($response['result']) > 0) {
        return true;
    }

    return false;
}

// Function to send block request to Cloudflare
function blockIPInCloudflare($ip, $apiKey, $authEmail, $zoneID, $blockLogPath) {
    $url = "https://api.cloudflare.com/client/v4/zones/$zoneID/firewall/access_rules/rules";

    $data = [
        "mode" => "block",
        "configuration" => [
            "target" => "ip",
            "value" => $ip
        ],
        "notes" => "Fail2ban block"
    ];

    $headers = [
        "Content-Type: application/json",
        "X-Auth-Key: $apiKey",
        "X-Auth-Email: $authEmail"
    ];

    $options = [
        'http' => [
            'header' => implode("rn", $headers),
            'method' => 'POST',
            'content' => json_encode($data)
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    if ($result === FALSE) {
        $error = "Failed to block IP $ip";
        logMessage($error, $blockLogPath);
        echo "$errorn";
        return null;
    }

    $response = json_decode($result, true);

    if (isset($response['result']['id'])) {
        $success = "Successfully blocked IP $ip";
        logMessage($success, $blockLogPath);
        // Save block rule ID and expiration time
        file_put_contents("C:pathtoblocked_ips.log", "$ip|{$response['result']['id']}|".(time() + ($blockDurationHours * 3600)).PHP_EOL, FILE_APPEND);
        return $response['result']['id'];
    } else {
        $error = "Failed to retrieve rule ID for IP $ip";
        logMessage($error, $blockLogPath);
        echo "$errorn";
        return null;
    }
}

// Function to remove block request from Cloudflare
function removeIPFromCloudflare($blockRuleID, $apiKey, $authEmail, $zoneID, $blockRemoveLogPath) {
    $url = "https://api.cloudflare.com/client/v4/zones/$zoneID/firewall/access_rules/rules/$blockRuleID";

    $headers = [
        "Content-Type: application/json",
        "X-Auth-Key: $apiKey",
        "X-Auth-Email: $authEmail"
    ];

    $options = [
        'http' => [
            'header' => implode("rn", $headers),
            'method' => 'DELETE'
        ]
    ];

    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);

    if ($result === FALSE) {
        $error = "Failed to remove block rule $blockRuleID";
        logMessage($error, $blockRemoveLogPath);
        echo "$errorn";
    } else {
        $success = "Successfully removed block rule $blockRuleID";
        logMessage($success, $blockRemoveLogPath);
        echo "$successn";
    }
}

// Function to process access log and block IPs if necessary
function processAccessLog($logPath, $apiKey, $authEmail, $zoneID, $blockLogPath) {
    global $timeWindow, $threshold;

    $ipCounts = [];

    if (($handle = fopen($logPath, "r")) !== FALSE) {
        while (($line = fgets($handle)) !== FALSE) {
            preg_match('/[(.*?)] "(.*?)" (d{3})/', $line, $matches);

            if (count($matches) > 0) {
                $logTimestamp = strtotime($matches[1]);
                $statusCode = $matches[3];

                if ($statusCode == '404' && $logTimestamp > $timeWindow) {
                    $ip = preg_split('/s+/', $line)[0];

                    if (!isset($ipCounts[$ip])) {
                        $ipCounts[$ip] = 1;
                    } else {
                        $ipCounts[$ip]++;
                    }
                }
            }
        }
        fclose($handle);
    }

    foreach ($ipCounts as $ip => $count) {
        if ($count >= $threshold) {
            if (!isIPBlocked($ip, $apiKey, $authEmail, $zoneID)) {
                blockIPInCloudflare($ip, $apiKey, $authEmail, $zoneID, $blockLogPath);
            } else {
                logMessage("IP $ip is already blocked.", $blockLogPath);
            }
        }
    }
}

// Function to remove expired block rules
function removeExpiredBlocks($blockLogPath, $apiKey, $authEmail, $zoneID, $blockRemoveLogPath) {
    $currentTime = time();

    if (file_exists($blockLogPath)) {
        $lines = file($blockLogPath);

        foreach ($lines as $line) {
            list($ip, $blockRuleID, $expireTime) = explode('|', trim($line));

            if ($currentTime >= $expireTime) {
                removeIPFromCloudflare($blockRuleID, $apiKey, $authEmail, $zoneID, $blockRemoveLogPath);
                // Remove or comment out the line from the log file
                file_put_contents($blockLogPath, str_replace($line, '', file_get_contents($blockLogPath)));
            }
        }
    }
}

// Execute the functions
processAccessLog($logPath, $apiKey, $authEmail, $zoneID, $blockLogPath);
removeExpiredBlocks("C:pathtoblocked_ips.log", $apiKey, $authEmail, $zoneID, $blockRemoveLogPath);
?>

Subscribe

  • RSS Atom

ອອນລາຍ: 1 | ມື້ນີ້: 11 | ວານນີ້: 25 | ທິດນີ້: 91 | ເດືອນນີ້: 870 | ປີນີ້: 11830 | ລວມ: 78933