【PHP】简单的脚本/扫描器拦截与重要文件保护

【背景】

由于站点经常被脚本或扫描器探测,由于很多都是直接性的请求,所以写了个简单的脚本来调整一下,重要的是保护像.env database之类的文件不被拿到,但只是简单的挡一下,还是需要结合目录权限限制、防火墙等多种保护手段.

【主要功能】

  • 检测常见扫描器UA)

  • 防护敏感文件泄露

  • 拦截无UA请求

  • 基本的日志记录

【代码】

php 复制代码
$userAgent = $_SERVER['HTTP_USER_AGENT']??'';
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
$requestUrl = $_SERVER['REQUEST_URI'] ?? '';

//检测无User-agent或空User-agent
$noUserAgent = empty($userAgent);

$blockedKeywords = array(
    'python',       //Python 请求库 (requests, urllib, scrapy 等)
    'go-http-client', //Go 的标准库 net/http (最常见)
    'go/',          //其他可能包含 "go/" 的 Go 库 UA
    'curl',         //命令行 curl 工具
    'wget',         //命令行 wget 工具
    'scrapy',       //Scrapy
    'httrack',      //网站镜像工具
    'Keydrop.io',    //服务器扫描工具
    'zgrab',        //Zgrab 扫描器
    'nmap',         //Nmap 扫描器
    'nikto',        //Nikto 扫描器
    'sqlmap',       // SQL 注入工具
    'acunetix',     //Acunetix 扫描器
    'nessus',       //Nessus 扫描器
    'burpsuite',     //Burp Suite 扫描器
    'nvdorz',
    'l9explore'
);

//敏感路径关键词检测
$sensitivePaths = array(
    '.env',
    '.git',
    '.svn',
    'wp-config.php',
    'config.php',
    '.htaccess',
    'web.config',
    'dockerfile',
    'composer.json',
    'package.json',
    'admin',
    'backup',
    'sql',
    'dump',
    'credentials',
    'secret',
    'password',
);

$isBlocked = false;
$blockReason = '';


foreach ($sensitivePaths as $path){
    if(stripos($requestUrl,$path)!==false){
        $isBlocked = true;
        $blockReason = "访问敏感路径: $path";
        break;
    }
}

//如果没有敏感路径访问,检查User-Agent
if(!$isBlocked){
    
  //首先检查是否无User-agent
if($noUserAgent){
    $isBlocked = true;
    $blockReason = "空User-Agent";
}else {
    foreach ($blockedKeywords as $keyword) {
    if (stripos($userAgent, $keyword) !== false) {
        $isBlocked = true;
        $blockReason = "可疑的UA关键词: $keyword";
        break;
    }
}

}
    
}



//检测二进制或畸形请求
if(!$isBlocked){
     if (preg_match('/[\x00-\x1F\x7F]/', $requestUri . $userAgent)) {
        $isBlocked = true;
        $blockReason = "二进制/畸形请求";
    }
}



if($isBlocked){
    $logMessage = sprintf(
        "[%s] 可疑请求拦截: IP %s - 原因: %s - UA: %s\n",
        date('Y-m-d H:i:s'),
        $ip,
        $blockReason,
        $noUserAgent ? '[EMPTY]' : $userAgent
    );
    //日志名称随便写
    file_put_contents('log.log', $logMessage, FILE_APPEND);
    header('HTTP/1.1 403 Forbidden');
    echo '<!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <title>访问被拒绝</title>
        <style>
            body { font-family: Arial, sans-serif; text-align: center; padding: 50px; }
            h1 { color: #d9534f; }
            .detail { background: #f8f9fa; padding: 20px; margin: 20px auto; max-width: 600px; text-align: left; }
        </style>
    </head>
    <body>
        <h1>403 禁止访问</h1>
        <p>检测到可疑请求行为,您的访问已被拦截。</p>
        
        <div class="detail">
            <p><strong>拦截原因:</strong> '.'检测到可疑请求行为,或非正规请求途径'.'</p>
            <p><strong>客户端IP:</strong> '.htmlspecialchars($ip).'</p>
            '.($noUserAgent ? '<p><strong>User-Agent:</strong> [未提供]</p>' : '<p><strong>User-Agent:</strong> '.htmlspecialchars($userAgent).'</p>').'
        </div>
        
        <p>如有疑问,请联系网站管理员。</p>
    </body>
    </html>';
    exit;
}
相关推荐
GoWjw2 小时前
在C&C++中结构体的惯用方法
c语言·开发语言·c++
静心观复2 小时前
Java 中,`1 << 1`
java·开发语言
Bruce_kaizy2 小时前
c++单调数据结构————单调栈,单调队列
开发语言·数据结构·c++
阿坤带你走近大数据2 小时前
Python基础知识-数据结构篇
开发语言·数据结构·python
froginwe112 小时前
AJAX 实时搜索:技术原理与实现方法
开发语言
发光小北2 小时前
SG-CAN (FD) NET-210(双通道 CAN (FD) 转以太网网关)特点与功能介绍
开发语言·网络·php
liangshanbo12153 小时前
深入理解 Model Context Protocol (MCP):从原理到实践
开发语言·qt·microsoft
小尘要自信3 小时前
Bright Data AI Scraper Studio:企业级AI爬虫解决方案,让数据采集更智能
人工智能·爬虫·通过ai自动化爬虫·prompt生产爬虫·云端爬虫平台
于是我说3 小时前
前端JavaScript 项目中 获取当前页面滚动位置
开发语言·前端·javascript