你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
文章可能会比较长,主要解析的非常详解,或涉及一些底层知识,供面试高阶难度用。可以根据自己实际理解情况合理取舍阅读
在Nginx中实现限流和黑名单拦截是保障服务稳定的重要手段,以下是 4种核心方案 的详细实现步骤和配置示例:
# http块定义限流规则
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
# 触发限流时的响应(默认返回503)
limit_req_status 429;
}
}
}
参数解析:
zone=api_limit:10m:定义10MB内存区存储访问状态
rate=10r/s:每秒允许10个请求(实际按毫秒平滑处理)
burst=20:允许突发20个请求排队
nodelay:不延迟处理突发请求
http {
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
location /download/ {
limit_conn conn_limit 5; # 单IP最大5并发连接
limit_rate_after 10m; # 下载10MB后限速
limit_rate 100k; # 限速到100KB/s
}
}
}
# 在http/server/location块中添加
deny 192.168.1.100; # 拒绝单个IP
deny 10.0.0.0/8; # 拒绝整个网段
allow 172.16.0.0/16; # 白名单优先于黑名单
allow all; # 允许其他所有IP
http {
lua_shared_dict blacklist 10m; # 共享内存存储黑名单
server {
location / {
access_by_lua_block {
local blacklist = ngx.shared.blacklist
local client_ip = ngx.var.remote_addr
if blacklist:get(client_ip) then
ngx.exit(ngx.HTTP_FORBIDDEN) # 返回403
end
}
}
# 动态添加黑名单的接口(需做权限控制)
location /admin/blacklist {
content_by_lua_block {
local ip = ngx.req.get_uri_args()["ip"]
ngx.shared.blacklist:set(ip, true, 3600) # 封禁1小时
ngx.say("已封禁IP: "..ip)
}
}
}
}
http {
limit_req_zone $binary_remote_addr zone=auto_block:10m rate=100r/m;
server {
location / {
limit_req zone=auto_block burst=150;
error_page 503 @blacklist;
}
location @blacklist {
# 触发限流时记录到黑名单
access_by_lua_block {
local blacklist = ngx.shared.blacklist
local client_ip = ngx.var.remote_addr
blacklist:set(client_ip, true, 600) # 封禁10分钟
ngx.exit(503)
}
}
}
}
1. 安装配置fail2ban:
# 安装
sudo apt-get install fail2ban
# 创建Nginx规则配置文件
/etc/fail2ban/jail.d/nginx.conf
2.配置监控规则:
[nginx-limit-req]
enabled = true
filter = nginx-limit-req
action = iptables[name=HTTP, port=http, protocol=tcp]
logpath = /var/log/nginx/error.log
maxretry = 3 # 触发阈值
findtime = 300 # 5分钟内
bantime = 3600 # 封禁1小时
3.创建过滤规则:
# /etc/fail2ban/filter.d/nginx-limit-req.conf
[Definition]
failregex = limiting requests, excess:.*client: <HOST>
1.压力测试工具:
# 测试并发请求
ab -n 1000 -c 50 http://your-domain.com/api/
# 测试单IP高频访问
siege -c 10 -t 1M http://your-domain.com/login
2.查看黑名单状态:
# 查看Nginx共享内存中的黑名单
nginx -c /path/to/nginx.conf -t 2>&1 | grep blacklist
# 查看iptables封禁列表
iptables -L -n
# 黑名单管理
geo $blacklist {
default 0;
include /etc/nginx/conf.d/blacklist.conf; # IP列表文件
}
# 限流配置
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=100r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
server {
listen 80;
# 黑名单拦截
if ($blacklist) {
return 444; # 直接关闭连接
}
location /api/ {
limit_req zone=api_limit burst=200 nodelay;
limit_conn conn_limit 50;
proxy_pass http://api_backend;
}
location /admin/ {
allow 192.168.1.0/24; # 只允许内网访问
deny all;
}
}
灰度发布:新规则应先在小流量环境验证
监控报警:配合Prometheus + Grafana监控限流触发情况
防御穿透:针对代理IP(X-Forwarded-For)需特殊处理
性能影响:共享内存大小需根据业务规模调整(1MB≈8000个IP)
以上方案可根据实际业务需求组合使用,建议从简单静态规则开始逐步升级到动态智能防护。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!