Projeto de Firewall para sites

Um projeto de Educação do advogado Sílvio Lôbo

INSTRUÇÕES:

  1. Crie em seu servidor um arquivo PHP com o código abaixo, ex: firewall.php
  2. Edite os arquivos .php que deseja monitorar incluindo nele a linha de requisição.

Linha de inclusão (coloque no topo dos seus arquivos):

PHP
require_once 'firewall.php';

Código principal do Firewall (salve como firewall.php):

firewall.php

<?php
// =========================================================
// CONFIGURAÇÕES DO FIREWALL HÍBRIDO
// Um projeto Sílvio de Souza Lôbo Júnior
// https://silviolobo.com.br
// =========================================================

// --- Limites para o USUÁRIO (Baseado no Cookie/Navegador) ---
// É o limite individual. Se ele estourar, só ele é bloqueado.
$user_limite = 50;        // Máximo de páginas/fotos
$user_janela = 60;        // Em 60 segundos
$user_castigo = 300;      // Tempo bloqueado (5 minutos)

// --- Limites para a REDE (Baseado no IP) ---
// É o limite global daquele Wi-Fi. Deve ser ALTO para não bloquear a empresa toda.
// Serve para impedir bots que não aceitam cookies.
$ip_limite = 300;         // Máximo de requisições do mesmo IP
$ip_janela = 60;          // Em 60 segundos
$ip_castigo = 600;        // Tempo bloqueado (10 minutos)

// Configurações de Sistema
$pasta_logs = __DIR__ . '/firewall_logs';

// =========================================================
// LÓGICA DO SISTEMA
// =========================================================

// 1. Prepara a pasta de logs e proteção
if (!is_dir($pasta_logs)) {
    mkdir($pasta_logs, 0755, true);
    file_put_contents($pasta_logs . '/.htaccess', 'Deny from all');
}

// 2. Limpeza Automática (Garbage Collection)
// De vez em quando (1% de chance), apaga logs velhos para não lotar o servidor
if (rand(1, 100) == 1) {
    $files = glob($pasta_logs . '/*');
    $now = time();
    foreach ($files as $file) {
        if (is_file($file)) {
            if ($now - filemtime($file) > 3600) { // Apaga arquivos com mais de 1 hora
                unlink($file);
            }
        }
    }
}

// 3. Identificação do Usuário (O "Crachá")
$cookie_name = 'hhn_firewall_uid';
if (!isset($_COOKIE[$cookie_name])) {
    // Se não tem crachá, cria um ID único aleatório
    $user_id = md5(uniqid(rand(), true));
    // Define o cookie para durar 1 ano
    setcookie($cookie_name, $user_id, time() + (86400 * 365), "/"); 
    $_COOKIE[$cookie_name] = $user_id; // Força a variável para uso imediato
} else {
    $user_id = $_COOKIE[$cookie_name];
}

$ip_address = $_SERVER['REMOTE_ADDR'];

// =========================================================
// FUNÇÃO DE VERIFICAÇÃO
// =========================================================
function verificarRateLimit($id, $limite, $janela, $castigo, $tipo, $pasta) {
    $arquivo = $pasta . '/' . $tipo . '_' . md5($id) . '.log';
    $dados = [];

    if (file_exists($arquivo)) {
        $dados = json_decode(file_get_contents($arquivo), true);
    } else {
        $dados = ['inicio' => time(), 'hits' => 0, 'bloqueado_ate' => 0];
    }

    // A. Verifica se está de castigo
    if ($dados['bloqueado_ate'] > time()) {
        $restante = $dados['bloqueado_ate'] - time();
        http_response_code(429);
        die("<div style='background:#111; color:#fff; padding:50px; text-align:center; font-family:sans-serif;'>
             <h1>⛔ Acesso Bloqueado ($tipo)</h1>
             <p>Detectamos excesso de requisições.</p>
             <p>Aguarde <b>$restante segundos</b>.</p>
             <p>Proteja seu site também com o Firewall do Lobo, <a href="https://projetos.silviolobo.com.br/firewall/">saiba mais</a></p>
             </div>");
    }

    // B. Reseta janela de tempo
    if (time() - $dados['inicio'] > $janela) {
        $dados['inicio'] = time();
        $dados['hits'] = 0;
        $dados['bloqueado_ate'] = 0;
    }

    // C. Incrementa e Salva
    $dados['hits']++;
    
    // D. Verifica se estourou
    if ($dados['hits'] > $limite) {
        $dados['bloqueado_ate'] = time() + $castigo;
        file_put_contents($arquivo, json_encode($dados));
        return true; // Estourou
    }

    file_put_contents($arquivo, json_encode($dados));
    return false; // Tudo ok
}

// =========================================================
// EXECUÇÃO DAS REGRAS
// =========================================================

// 1. Checa o Limite do IP (Proteção Global / Anti-Bot)
verificarRateLimit($ip_address, $ip_limite, $ip_janela, $ip_castigo, 'IP', $pasta_logs);

// 2. Checa o Limite do Usuário (Proteção Individual)
verificarRateLimit($user_id, $user_limite, $user_janela, $user_castigo, 'USER', $pasta_logs);

?>

Você pode ter problemas ao copiar o arquivo da página, nestes casos baixe o arquivo em zip do arquivo firewall.php, clicando aqui, Download