你是否遇到过这种情况:
top,发现 CPU 占用率飙升到 100%,PHP-FPM 进程多得吓人。为什么资源会紧张?
WordPress 是动态网站,每一次页面访问都需要 PHP 解析和 MySQL 查询。如果一个爬虫每秒发起 10 个请求,对于一台配置较低(如 1核2G)的 VPS 来说,这就足以让数据库崩溃。
今天,我们不装臃肿的防火墙插件,而是用 Python 这种轻量级武器,从日志中揪出这些"资源吸血鬼",并在服务器层面直接封杀。
首先,你需要找到 Web 服务器的访问日志(Access Log)。
/var/log/nginx/access.log/var/log/apache2/access.log我们将编写一个 Python 脚本,完成以下任务:解析日志、统计访问频率、生成封禁名单。
analyze_bot.pyimport re
from collections import Counter
# --- 配置区域 ---
LOG_FILE = 'access.log'
THRESHOLD = 500
OUTPUT_BAN_FILE = 'nginx_deny_list.conf'
# Nginx日志正则匹配模式 (请根据实际日志格式调整)
LOG_PATTERN = re.compile(r'(?P<ip>\d+\.\d+\.\d+\.\d+).*?"(?P<method>\w+) (?P<path>.*?) HTTP.*?" (?P<status>\d+) .*?"(?P<agent>.*?)"')
def analyze_logs():
ip_counter = Counter()
suspicious_ips = {}
with open(LOG_FILE, 'r', encoding='utf-8', errors='ignore') as f:
for line in f:
match = LOG_PATTERN.search(line)
if match:
data = match.groupdict()
ip = data['ip']
ua = data['agent']
ip_counter[ip] += 1
suspicious_ips[ip] = ua # 记录最后一次该IP使用的UA
return ip_counter, suspicious_ips
def generate_report(ip_counts, suspicious_data):
# 生成 Nginx 封禁列表
print(f"\n--- 🚫 生成封禁建议 (超过 {THRESHOLD} 次访问) ---")
banned_count = 0
with open(OUTPUT_BAN_FILE, 'w') as f:
f.write("# Auto-generated block list\n")
for ip, count in ip_counts.items():
if count > THRESHOLD:
if ip.startswith('127.0.0'): continue
# 写入 Nginx 格式: deny 1.2.3.4;
f.write(f"deny {ip};\n")
banned_count += 1
print(f"✅ 已生成配置文件: {OUTPUT_BAN_FILE}")
print(f"🔨 建议封禁的 IP 数量: {banned_count}")
print("\n--- 📊 访问量 Top 10 IP 摘要 ---")
for ip, count in ip_counts.most_common(10):
print(f"IP: {ip} | 次数: {count} | UA摘要: {suspicious_data[ip][:30]}...")
if __name__ == '__main__':
try:
ip_counts, suspicious_data = analyze_logs()
generate_report(ip_counts, suspicious_data)
except FileNotFoundError:
print("❌ 错误:找不到日志文件,请检查路径。")脚本输出示例:
IP: 45.132.xx.xx | 次数: 5000 | UA摘要: Python-urllib/3.8...分析:单个 IP 在短时间内访问 5000 次,且 User-Agent 为简陋的 Python-urllib。
对策:直接封杀 IP。
日志特征示例:
次数: 2000 | UA: Mozilla/5.0 (compatible; MJ12bot/v1.4.8; ...)
次数: 1500 | UA: Mozilla/5.0 (compatible; SemrushBot/7~bl; ...)分析:这些工具抓取频率高,消耗资源大。
对策:通过 User-Agent 屏蔽。
Python 脚本生成了封禁列表,现在要在服务器层面进行拦截。
Python 脚本生成的 nginx_deny_list.conf 内容大致如下:
deny 45.132.11.22;
deny 103.21.33.44;部署方法:
server 块内)引入它:server {
listen 80;
server_name example.com;
# 引入封禁列表
include /etc/nginx/conf.d/nginx_deny_list.conf;
location / {
# ... 其他配置
}
}sudo nginx -s reload。针对那些换 IP 很勤快,但 UA 固定的爬虫,直接在 Nginx 配置文件中添加判断:
server {
# ... 其他配置
# 禁止特定的 User-Agent
if ($http_user_agent ~* (MJ12bot|AhrefsBot|SemrushBot|DotBot|PetalBot|Bytespider)) {
return 403;
}
}对于恶意扫描(如爆破 wp-login.php),手动处理效率低下,可以考虑使用 Fail2Ban 实现自动化:
简单的 WordPress 防爆破配置思路:
/wp-login.php 返回非 200 状态码超过 5 次,封禁 IP 1小时。通过 Python 的日志分析能力,我们可以精准定位资源消耗者,并通过 Nginx/Apache 的配置在 Web 服务器最前端进行拦截,从而大幅降低服务器的负载压力。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。