【背景】
由于站点经常被脚本或扫描器探测,由于很多都是直接性的请求,所以写了个简单的脚本来调整一下,重要的是保护像.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;
}