最近一个图床服务总是打开特别慢,查看了下后台日志,发现在被频繁的攻击,而且获取到了我的管理员账号,一直在尝试登录管理员账号。
但是因为请求主要以 Bot
为主,就判断对方为正常的爬虫吧,这种情况一般 Nginx 就可以拦截。
在 Nginx 配置中,我们可以使用 map
规则、limit_conn
并发限制、limit_req
速率限制、IP 黑名单、User-Agent 屏蔽、Referer 过滤、防火墙规则 等方法来有效防止 恶意爬虫、DDoS 攻击、暴力扫描、垃圾流量 等问题。
1. 屏蔽恶意请求的核心手段
1.1. 屏蔽恶意 User-Agent
爬虫、自动化工具经常使用特定的 User-Agent,可以通过 map
规则屏蔽:
http {
map $http_user_agent $block_user_agent {
default 0;
"~*semrush" 1;
"~*AhrefsBot" 1;
"~*MJ12bot" 1;
}
server {
listen 80;
server_name shejibiji.com;
location / {
if ($block_user_agent) { return 444; }
}
}
}
📌 解释
~*
不区分大小写匹配 User-Agent。return 444;
直接丢弃请求,不返回任何响应,防止恶意爬虫绕过。
1.2. 屏蔽恶意 Referer
防止垃圾外链、盗链、SEO 垃圾流量:
http {
map $http_referer $block_referrer {
default 0;
"~*viagra" 1;
"~*casino" 1;
"~*porn" 1;
}
server {
listen 80;
server_name she ji bi ji;
location / {
if ($block_referrer) { return 403; }
}
}
}
📌 解释
- 过滤 Referer 中包含违禁词的请求,防止垃圾外链流量。
1.3. 屏蔽特定 URL 访问
可以限制某些敏感路径,如 /admin
、/phpmyadmin
、/shejibiji
:
http {
map $request_uri $block_url {
default 0;
"~*^/admin" 1;
"~*^/phpmyadmin" 1;
"~*^/shejibiji" 1;
}
server {
listen 80;
server_name shejibiji.com;
location / {
if ($block_url) { return 444; }
}
}
}
📌 解释
^/admin
拦截所有访问/admin
及其子路径的请求。return 444;
直接丢弃请求,防止探测扫描。
1.4. 屏蔽特定 IP
如果你发现某些 IP 频繁访问网站、攻击服务器,可以直接屏蔽:
http {
map $remote_addr $block_ip {
default 0;
"192.168.1.100" 1;
"203.0.113.50" 1;
}
server {
listen 80;
server_name shejibiji.com;
location / {
if ($block_ip) { return 444; }
}
}
}
📌 解释
- 可以使用
map
集中管理 IP 黑名单,比deny
更直观。
1.5. 屏蔽 Headers 伪造攻击
有些攻击者会伪造 HTTP 头部请求,我们可以拦截:
if ($http_content_type ~* "(?:multipart/mixed|application/x-shellscript)") {
return 403;
}
📌 解释
- 阻止伪造
Content-Type
的恶意请求(如 shell 上传)。
2. 限制并发连接 & 速率
2.1. 限制 IP 并发连接
限制 单个 IP 允许的最大连接数,防止占用服务器资源:
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
server_name shejibiji.com;
location / {
limit_conn conn_limit 50;
}
}
}
📌 解释
limit_conn_zone $binary_remote_addr
按 IP 计算连接数。limit_conn conn_limit 50;
单个 IP 最多 50 个并发连接。
2.2. 限制请求速率
防止 DDoS 攻击、爬虫短时间内过多请求:
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
server {
listen 80;
server_name shejibiji.com;
location / {
limit_req zone=req_limit burst=20 nodelay;
}
}
}
📌 解释
rate=10r/s
→ 每个 IP 每秒最多 10 个请求。burst=20
→ 允许突发 20 个请求(超出会被拒绝)。nodelay
→ 立即丢弃超限请求,而不是排队执行。
3. 使用 Nginx 特殊状态码
状态码 | 作用 | 用途 |
---|---|---|
444 |
直接丢弃请求,不返回任何响应 | 屏蔽爬虫、攻击者 |
495 |
SSL 证书错误 | 阻止无效 SSL 证书 |
496 |
需要 SSL 证书 | 只允许可信客户端访问 |
497 |
HTTP 访问 HTTPS 端口 | 自动跳转到 HTTPS |
499 |
客户端提前关闭连接 | 日志记录 |
📌 示例
error_page 495 =444;
error_page 496 =403;
4. 服务器端安全防护
4.1. 隐藏服务器信息
默认情况下,Nginx 会在 Server
头部暴露服务器信息:
server_tokens off;
📌 作用
- 隐藏 Nginx 版本号,防止黑客利用已知漏洞攻击。
4.2. 防止 clickjacking
add_header X-Frame-Options DENY;
📌 作用
- 防止网站被嵌套到 iframe 内,防止点击劫持。
4.3. 防止 XSS
攻击
add_header X-XSS-Protection "1; mode=block";
📌 作用
- 启用浏览器 XSS 过滤,防止跨站脚本攻击。
5. 结合 Fail2Ban 动态封禁
如果某些 IP 频繁攻击服务器,我们可以用 fail2ban
进行动态封禁:
-
创建过滤规则
sudo nano /etc/fail2ban/filter.d/nginx-badbot.conf
规则内容
[Definition] failregex = .*"(GET|POST).*HTTP/.*" 403
-
添加到
jail.local
sudo nano /etc/fail2ban/jail.local
配置
[nginx-badbot] enabled = true filter = nginx-badbot logpath = /var/log/nginx/access.log maxretry = 5 findtime = 60 bantime = 3600
-
启动
fail2ban
sudo systemctl restart fail2ban
🎯 结论
✅ 屏蔽 User-Agent、Referer、IP、URL,防止恶意爬虫。
✅ 限制并发连接、请求速率,防止 DDoS 攻击。
✅ 使用 return 444
直接丢弃恶意请求。
✅ 开启 Nginx 安全头、隐藏服务器信息,防止信息泄露。
✅ 结合 fail2ban
进行动态封禁,自动屏蔽攻击 IP。
🚀 通过这些方法,可以大幅提升 Nginx 服务器的安全性和稳定性!