'danger', 'msg' => 'Pedido rejeitado (token CSRF inválido).']; header('Location: ' . $selfUrl, true, 303); exit; } $uid = isset($_SESSION['user']['id']) ? (int) $_SESSION['user']['id'] : null; $action = $_POST['action'] ?? ''; $ip = trim((string) ($_POST['ip'] ?? '')); if ($action === 'unban' && $ip !== '') { platform_ip_unban($pdo, $ip); if (function_exists('platform_audit')) platform_audit($pdo, 'ip.unban', ['target_type' => 'ip', 'target_label' => $ip]); $_SESSION['ipban_flash'] = ['type' => 'success', 'msg' => "Banimento de $ip levantado. O histórico de infracções mantém-se."]; } elseif ($action === 'ban') { if (!filter_var($ip, FILTER_VALIDATE_IP)) { $_SESSION['ipban_flash'] = ['type' => 'warning', 'msg' => 'Endereço IP inválido.']; } elseif (platform_ip_ban_exempt($ip)) { $_SESSION['ipban_flash'] = ['type' => 'warning', 'msg' => 'Endereços internos não podem ser banidos — o contentor fala consigo próprio para o cron e os health checks.']; } else { $dur = $_POST['duration'] ?? '60'; $mins = $dur === 'perm' ? null : max(1, (int) $dur); $reason = trim((string) ($_POST['reason'] ?? '')) ?: 'banido manualmente'; platform_ip_ban($pdo, $ip, $reason, $mins, 'manual', $uid); if (function_exists('platform_audit')) platform_audit($pdo, 'ip.ban', ['target_type' => 'ip', 'target_label' => $ip, 'summary' => $reason, 'changes' => ['minutes' => $mins]]); $_SESSION['ipban_flash'] = ['type' => 'success', 'msg' => "$ip banido."]; } } header('Location: ' . $selfUrl, true, 303); exit; } $flash = $_SESSION['ipban_flash'] ?? null; unset($_SESSION['ipban_flash']); $bans = platform_ip_ban_list($pdo); $offenders = platform_ip_offenders($pdo, 7); $activos = array_values(array_filter($bans, fn($b) => empty($b['expired']))); $layout_header = $platform_layout_header ?? ($repo_root . '/includes/header.php'); $layout_navbar = $platform_layout_navbar ?? ($repo_root . '/includes/navbar.php'); $layout_footer = $platform_layout_footer ?? ($repo_root . '/includes/footer.php'); $pageTitle = 'Bloqueio de IP'; if (is_file($layout_header)) include $layout_header; if (is_file($layout_navbar)) include $layout_navbar; $h = fn($s) => htmlspecialchars((string) $s, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); ?>

Bloqueio de IP

Endereços recusados à porta por atividade automatizada repetida.

Como a escalada funciona. Cada recusa do antispam, do portão de país ou do throttle de login conta como uma infracção. A partir de 3 infracções em 24 horas o endereço é banido 1 hora; às 5, um dia; às 8, uma semana; às 12, permanentemente. A subida é lenta de propósito: um IP é muitas vezes partilhado — uma escola, um escritório, o CGNAT de um operador móvel — e banir para sempre à terceira tentativa apanha pessoas a mais. Com o site emparelhado com o hub, os banimentos daqui passam aos outros sites da frota e os deles chegam cá com a origem frota. Levantar um banimento retira as cópias de todos os sites; o site onde ele nasceu mantém o seu até expirar ou ser levantado lá.
Banidos activo

Nenhum endereço banido até agora.

IPMotivoOrigemAtéInfr.Tentat.
> permanente expirou

Tentat. é quantas vezes o endereço voltou depois de banido — um número alto é o sinal mais claro de que não é uma pessoa.

A subir — infracções sem banimento (7 dias)

Nenhuma infracção registada no período.

IPInfracçõesTiposÚltima
Banir à mão