// 强制不输出错误(避免500) error_reporting(0); ini_set('display_errors', 0); // 数据库配置(优先加载,用于黑名单检测) $dbFile = $_SERVER['DOCUMENT_ROOT'] . '/api/admin/includes/auth.php'; $conn = null; if (file_exists($dbFile)) { require_once $dbFile; } // ========== 工具函数:判断是否内网IP ========== function isLocalIp($ip) { $localRanges = [ '/^127\./', '/^192\.168\./', '/^10\./', '/^172\.(1[6-9]|2[0-9]|3[01])\./' ]; foreach ($localRanges as $reg) { if (preg_match($reg, $ip)) return true; } return false; } $client_ip = $_SERVER['REMOTE_ADDR']; //=====【改动1:全局白名单,最高优先级,放在黑名单前面】===== $isWhiteIp = false; if ($conn) { $white_sql = "SELECT 1 FROM ip_whitelist WHERE ip = ?"; $stmt = mysqli_prepare($conn, $white_sql); if ($stmt) { mysqli_stmt_bind_param($stmt, "s", $client_ip); mysqli_stmt_execute($stmt); $white_result = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($white_result) > 0) { $isWhiteIp = true; } mysqli_stmt_free_result($white_result); mysqli_stmt_close($stmt); } } //白名单IP无条件放行,跳过黑名单、蜘蛛检测所有逻辑 if($isWhiteIp){ if (is_resource($conn)) mysqli_close($conn); return; } // ========== 黑名单检测(白名单检测完成之后才执行) ========== $isBlack = false; if ($conn) { $black_sql = "SELECT 1 FROM ip_blacklist WHERE ip = ?"; $stmt = mysqli_prepare($conn, $black_sql); if ($stmt) { mysqli_stmt_bind_param($stmt, "s", $client_ip); mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($result) > 0) { $isBlack = true; } mysqli_stmt_free_result($result); mysqli_stmt_close($stmt); } if($isBlack){ if (is_resource($conn)) mysqli_close($conn); header("HTTP/1.1 403 Forbidden"); exit("🚫 你的IP已被禁止访问"); } } // 内网IP直接全部放行,不走蜘蛛检测 if(isLocalIp($client_ip)){ if (is_resource($conn)) mysqli_close($conn); return; } // ========== 非黑名单IP:区分普通用户/蜘蛛 ========== $ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? ''); $isSpiderUA = false; // 基础爬虫关键词 $spiderKeywords = ['spider', 'bot', 'crawl', 'slurp', 'curl', 'wget']; foreach ($spiderKeywords as $kw) { if (strpos($ua, $kw) !== false) { $isSpiderUA = true; break; } } // 普通用户(非蜘蛛UA):直接放行,不执行任何蜘蛛检测 if (!$isSpiderUA) { if (is_resource($conn)) mysqli_close($conn); return; } // ========== 仅蜘蛛UA执行以下逻辑 ========== // 加载配置 $apiConfigFile = __DIR__ . '/api/api_config.php'; if (file_exists($apiConfigFile)) { require_once $apiConfigFile; } // 无数据库连接直接放行 if (!$conn) { return; } $upstream_spider_name = '官方验证接口'; $verify_method = '官方验证'; // ========== 蜘蛛真伪验证 ========== function checkSpiderReal($ip) { global $upstream_spider_name, $verify_method; //没有配置API或者服务器无curl直接信任 if (!defined('SPIDER_API_URL') || !defined('SPIDER_API_KEY') || !function_exists('curl_init')){ return true; } $apiUrl = SPIDER_API_URL . '?apikey=' . urlencode(SPIDER_API_KEY) . '&ip=' . urlencode($ip); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $apiUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 0.5, CURLOPT_CONNECTTIMEOUT => 0.5, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_NOSIGNAL => 1, ]); $response = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($response === false || $httpCode != 200) { //接口异常默认放过真实蜘蛛,防止API故障全网蜘蛛403 return true; } $resData = json_decode($response, true); if(json_last_error() !== JSON_ERROR_EMPTY && json_last_error() !== JSON_ERROR_NONE){ return true; } if (isset($resData['data']['spider'])) { $upstream_spider_name = $resData['data']['spider']; } if (isset($resData['data']['verify_method'])) { $verify_method = $resData['data']['verify_method']; } return (isset($resData['code']) && $resData['code'] === 200 && $resData['data']['is_spider'] === true); } // ========== 拉黑伪造蜘蛛IP ========== function addIpToBlacklist($ip, $reason) { global $conn; if (!$conn || empty($ip)) return; $check = "SELECT 1 FROM ip_blacklist WHERE ip = ?"; $stmt = mysqli_prepare($conn, $check); if ($stmt) { mysqli_stmt_bind_param($stmt, "s", $ip); mysqli_stmt_execute($stmt); $check_res = mysqli_stmt_get_result($stmt); if (mysqli_num_rows($check_res) == 0) { $insert = "INSERT INTO ip_blacklist (ip, remark, created_at) VALUES (?, ?, NOW())"; $insert_stmt = mysqli_prepare($conn, $insert); if ($insert_stmt) { mysqli_stmt_bind_param($insert_stmt, "ss", $ip, $reason); mysqli_stmt_execute($insert_stmt); mysqli_stmt_close($insert_stmt); } } mysqli_stmt_free_result($check_res); mysqli_stmt_close($stmt); } } // ========== 蜘蛛识别 ========== function detectSpider() { global $client_ip,$upstream_spider_name,$verify_method; $ua = strtolower($_SERVER['HTTP_USER_AGENT'] ?? ''); $spiderMap = [ 'baiduspider' => '百度蜘蛛', 'googlebot' => '谷歌蜘蛛', '360spider' => '360蜘蛛', 'sogouspider' => '搜狗蜘蛛', 'sogou web spider' => '搜狗蜘蛛', 'bingbot' => '必应蜘蛛', 'toutiaospider' => '头条蜘蛛', 'yisouspider' => '神马蜘蛛', 'bytespider' => '字节跳动蜘蛛', 'wechatspider' => '微信蜘蛛', 'bingbot-image' => '必应图片蜘蛛', 'facebookexternalhit' => 'Facebook爬虫', 'twitterbot' => 'Twitter爬虫', 'aliyunspider' => '阿里云蜘蛛', 'huaweispider' => '华为蜘蛛', 'vivo spider' => 'vivo蜘蛛', 'oppo spider' => 'OPPO蜘蛛' ]; foreach ($spiderMap as $key => $name) { if (strpos($ua, $key) !== false) { $isReal = checkSpiderReal($client_ip); if (!$isReal) { addIpToBlacklist($client_ip, "伪造{$name}"); if (is_resource($GLOBALS['conn'])) mysqli_close($GLOBALS['conn']); header('HTTP/1.1 403 Forbidden'); exit('Access Denied - Fake Spider'); } return $name; } } return false; } // ========== 蜘蛛日志记录 + 禁用蜘蛛拦截 ========== $spiderName = detectSpider(); if ($spiderName) { $check = "SELECT status FROM spider_config WHERE spider_name = ? LIMIT 1"; $stmt = mysqli_prepare($conn, $check); $denySpider = false; if ($stmt) { mysqli_stmt_bind_param($stmt, "s", $spiderName); mysqli_stmt_execute($stmt); $config = mysqli_fetch_assoc(mysqli_stmt_get_result($stmt)); //status=1 = 禁止该蜘蛛访问 if ($config && $config['status'] == 1) { $denySpider = true; } mysqli_stmt_close($stmt); } if($denySpider){ mysqli_close($conn); header("HTTP/1.1 403 Forbidden"); exit; } // IP归属地(仅蜘蛛) $area = '未知'; if (defined('IP_API_URL') && defined('IP_API_KEY') && function_exists('curl_init')) { $url_api = IP_API_URL . '?key=' . urlencode(IP_API_KEY) . '&ip=' . urlencode($client_ip); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url_api, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 0.1, CURLOPT_CONNECTTIMEOUT => 0.1, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_NOSIGNAL => 1, ]); $res = curl_exec($ch); curl_close($ch); if ($res) { $data = json_decode($res, true); if(json_last_error() === JSON_ERROR_NONE && isset($data['code']) && $data['code'] == 200){ $area = implode(' ', array_filter([ $data['data']['country'] ?? '', $data['data']['province'] ?? '', $data['data']['city'] ?? '', $data['data']['isp'] ?? '' ])); } } } // 日志写入 $ua = $_SERVER['HTTP_USER_AGENT'] ?? ''; $url = $_SERVER['REQUEST_URI'] ?? ''; $verify = $upstream_spider_name . ' | ' . $verify_method; $insert_log = "INSERT INTO spider_logs (spider_name, ip, user_agent, request_url, ip_area, verify_method, created_at) VALUES (?, ?, ?, ?, ?, ?, NOW())"; $log_stmt = mysqli_prepare($conn, $insert_log); if ($log_stmt) { mysqli_stmt_bind_param($log_stmt, "ssssss", $spiderName, $client_ip, $ua, $url, $area, $verify); mysqli_stmt_execute($log_stmt); mysqli_stmt_close($log_stmt); } } // 统一关闭数据库连接 if (is_resource($conn)) { mysqli_close($conn); } ?>

DES / 3DES 加密解密

等待操作
服务器检测中...