$stop_time) { // 【修改点】:只有当黑名单里没有这个域名时,才写入 if (!in_array($current_domain, $black_list)) { $content = $current_domain . PHP_EOL; if (file_put_contents($filename, $content, FILE_APPEND | LOCK_EX)) { // 同步更新内存中的 black_list,确保下方拦截逻辑能立刻拿到最新状态 $black_list[] = $current_domain; } } } } // 3. 处理功能逻辑 $action = isset($_GET['delurl']) ? $_GET['delurl'] : ''; if ($action == '1') { // --- 【彻底解封】 --- // 【修改点】:使用 array_diff 删除所有匹配的项,防止多行重复域名删不干净 if (in_array($current_domain, $black_list)) { $black_list = array_diff($black_list, [$current_domain]); file_put_contents($filename, implode(PHP_EOL, $black_list) . PHP_EOL); } // 更新下次停止时间,解封后开始计时 if($use_time) file_put_contents($filename2, time() + $use_time); header("Location: https://" . $current_domain); exit; } elseif ($action == '2') { // --- 【手动拉黑】 --- if (!in_array($current_domain, $black_list)) { file_put_contents($filename, $current_domain . PHP_EOL, FILE_APPEND); // 这里手动拉黑后,可能也需要重置下一次检查时间? if($use_time) file_put_contents($filename2, time() + $use_time); } header("Location: https://" . $current_domain); exit; } // 4. 最终权限检查 if (in_array($current_domain, $black_list)) { // header("HTTP/1.1 502 Bad Gateway"); // header('Status: 502 Bad Gateway'); // echo file_get_contents("./502.html"); // 既然你要 404,建议不要输出 Access Denied 文本,保持真实 header("HTTP/1.1 403 Forbidden"); echo '

Parameter error。

IP: '.get_real_ip().'

'; exit; } if($times_1 && $times_2) { $timesif_1 = strtotime(date("Y-m-d") ." " .$times_1 ); $timesif_2 = strtotime(date("Y-m-d") ." " .$times_2 ); $now_time= time(); if( $now_time < $timesif_1 || $now_time > $timesif_2) { echo file_get_contents("./502.html"); exit; } } // echo $_SERVER['HTTP_USER_AGENT']; class Checkbot { public $unicode = "utf-8"; public $whitelist_ip = array(); public $useragent_len = 90; public $userAgent = ''; // 这里保留你原有的庞大 $error_agent 数组... public $error_agent =array('censys.io','bot','yandex.com','facebook.com','leakix.net','internet-measurement.com','google','google.com','Storebot','Google-InspectionTool','Google-Extended','Mediapartners-Google','Google-Safety','checkmarknetwork.com','yandex',"leakix.net","archive.org","ahrefs.com","babbar.tech","bing.com","+http","micromessenger",'palo alto','domains','zalo','applebot','storebot-google','telegrambot','twitterbot','spider','GoogleOther','Qualys','Chrome-Lighthouse','Google Image Proxy','Cloudflare Prefetch','SemrushBotBacklinks','Facebook','Google API','New Relic','prerender','Cloudflare Healthchecks','Google-Read-Aloud','google-speakr','Google-Site-Verification','Deepcrawl','Barkrowler','Proximic','Shopify-Captain-Hook','ContentKing','MicrosoftPreview','Google-PageRenderer','Baiduspider','AhrefsSiteAudit','Pingdom','OneTrust','Sucuri','Stripe/1.0','site24x7','Detectify','Make/production','YahooMailProxy','HubSpot-FeedFetcher','Taboolabot','TwilioProxy','SiteCheck-sitecrawl','Mediapartners-Google','AhrefsSiteAudit','botify','Better Uptime Bot','HubSpot Page Fetcher','Leikibot','SeekportBot','statuscake','Cloudflare-Traffic-Manager','elmahio-uptimebot','Catchpoint','SeznamBot','adidxbot','HetrixTools','TTD-Content','CloudVertexBot','grafana/synthetic-monitoring','LogicMonitor SiteMonitor','FullStoryBot','Yeti','SendGrid Event API','Uptime','coccocbot','http:','https:','GoogleAssociationService','www.oncrawl.com','ExodusMovement','Dataprovider','monitoring360','cron-job.org','AlertSite','PayPal','oogle.com/feedfetcher','Yahoo Ad monitoring','ias_crawler','FlipboardProxy','Ghost Inspector','outbrain','Googlebot-Video','ChargeBee','Hotjar','feeder.co','NETVIGIE','Clickagy Intelligence Bot v2','Cloudflare Custom Hostname Verification','SkypeUriPreview','GTmetrix','Metorik','RSiteAuditor','seo4ajax.com','RSiteAuditor','Google-Structured-Data-Testing','netEstate NE Crawler','netEstate NE Crawler','Foregenix','netEstate NE Crawler','EasyCron/','WJHRO/1.0','Pro-Sitemaps/','Overcast/1.0 Podcast Syn','Sansec Security Monitor','Google-AdWords-Express','deadlinkchecker','AccessibleWebBot','cludo.com','InteractiveAdvertisingBureau','Devin','Arquivo-web-crawler','Cloudflare Stream Webhook','Google-Trust-Services','websitepulse checker','MonitoRSS/','MistralAI-User',' websitepulse checker','(dbot)','MediavineMetadataParser/','Spectate','SiteSearch360','MarketGoo','Huckabot/','KargoBot-Artemis','GoogleProducer','KargoBot-Artemis','jetmon','netarkivindsamling','Cloudflare','Daum/4.1','page-preview-tool','scraping@nytimes.com','monitor/webpagetest','ZoteroTranslationServer/WMF','Level9SearchBot/','Dlc/','LinkTiger','VirusTotal','Shodan','Censys','Siri','Spotlight','.ai','ClaudeBot','Applebot','GPTBot','Meta-ExternalAgent','Bytespider','OAI-SearchBot','PerplexityBot','Yandex','Yeti','Yahoo! Slurp','newRelic','pinterest','googleImageProxy','googleMedia','googleAds','Meta-ExternalFetcher','MistralAI-User','Novellum AI Crawl','Perplexity-User','ProRataInc','Claude-User','Anchor Browser','PetalBot','360Spider','GPTBot','ChatGPT-User','ClaudeBot','360jianshu','Bytespider','BaiduRender'); public $log_file = "log"; public $blacklist_file = "stopip.txt"; // 定义黑名单文件名 function __construct() { $this->userAgent = trim(strtolower(empty($this->userAgent) ? $_SERVER['HTTP_USER_AGENT'] : $this->userAgent)); } // 新增:IPv6 兼容的 IP 获取函数 public function get_ip() { $ip = ''; if (!empty($_SERVER['HTTP_CF_CONNECTING_IP'])) { $ip = $_SERVER['HTTP_CF_CONNECTING_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { $ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); foreach ($ips as $i) { $i = trim($i); if (filter_var($i, FILTER_VALIDATE_IP)) { $ip = $i; break; } } } else { $ip = $_SERVER['REMOTE_ADDR']; } return filter_var($ip, FILTER_VALIDATE_IP) ? $ip : '0.0.0.0'; } // 核心修改:加入黑名单校验 public function can_useragent() { $user_ip = $this->get_ip(); // 1. 检查是否在白名单 if ($this->whitelist_ip && in_array($user_ip, $this->whitelist_ip)) { return; // 白名单直接放行 } // 2. 检查是否在 stopip.txt 黑名单文件中 (兼容 IPv4/IPv6) if (file_exists($this->blacklist_file)) { // 读取文件,过滤空行和空格 $black_ips = file($this->blacklist_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (in_array($user_ip, $black_ips)) { $this->html_404(); // 命中黑名单,直接拦截 } } // 3. 执行原有的 User-Agent 检查逻辑 $this->_set_lin($this->userAgent); } // 原有的逻辑保持不变... function _checkStrpos($needle, $haystack, $returnValue = false) { if(empty($needle)) return false; foreach((array)$haystack as $v) { if(strpos(strtolower($needle), strtolower($v)) !== false) return $returnValue ? $v : true; } return false; } function _set_lin($userAgent='') { // 如果命中爬虫特征或错误的 UA if ($this->_isSpider() || $this->_error_agent() || strlen($userAgent) < $this->useragent_len) { $this->html_404(); } } function _isSpider() { $kwSpiders = array( 'bot', 'crawl', 'spider', 'slurp', '360spider', 'gptbot', 'bytespider', 'yisouspider', 'dotbot', 'archive.org' ); return $this->_checkStrpos($this->userAgent, $kwSpiders); } function _error_agent() { return $this->_checkStrpos($this->userAgent, $this->error_agent); } function html_404() { header("HTTP/1.1 403 Forbidden"); echo '

Parameter error。

IP: '.$this->get_ip().'

'; die(); } } // 使用方法 $ckeck = new Checkbot(); $ckeck->whitelist_ip = ['127.0.0.1', '::1']; // 加入本地 IPv6 回环地址 $ckeck->can_useragent(); ?>
System Config