中间件不能直接防御DDOS,但能缓解应用层洪水;它运行在应用进程内,可压制CC攻击(如高频登录接口),需合理设计并配合Redis等后端避免多进程失效,且必须分层防护、避免自身成瓶颈。

中间件不能直接防御DDOS,但能缓解应用层洪水
Python Web 框架(如 Flask、Django、FastAPI)里的“中间件”本质是请求拦截器,它运行在应用进程内,只能处理已抵达的 HTTP 请求。真正的网络层 DDOS(如 SYN Flood、UDP 反射攻击)必须由 CDN、防火墙或云 WAF 拦截,中间件对此无能为力。但它对应用层 CC 攻击(比如高频 /api/login、/search?q=xxx)有实际压制作用——前提是设计合理、不拖垮自身。
用 slowapi 限流中间件防暴力扫接口
slowapi 是 FastAPI 生态中轻量、可嵌入的限流中间件,基于内存计数器(默认)或 Redis 后端,适合应对短时接口刷量。它不依赖全局锁,性能损耗小,但要注意:内存模式在多进程部署时失效(gunicorn 多 worker 会各自计数),必须配 Redis 才能跨进程生效。
实操建议:
- 安装:
pip install slowapi - 基础用法(单接口限流):
from slowapi import Limiter from slowapi.util import get_remote_address <p>limiter = Limiter(key_func=get_remote_address) app.state.limiter = limiter</p><p>@app.get("/api/data") @limiter.limit("5/minute") # 每分钟最多 5 次 async def get_data(): return {"result": "ok"} - 注意
@limiter.limit必须写在路由装饰器下方,否则不生效;get_remote_address默认取X-Forwarded-For,若没配反向代理,需改用request.client.host - 错误响应状态码默认是
429 Too Many Requests,返回头含Retry-After,前端可据此退避
Django 中用 django-ratelimit 做 IP + 用户级双控
Django 的中间件机制更成熟,django-ratelimit 支持按 IP、用户、视图函数甚至自定义键限流,且天然兼容多进程和缓存后端(Redis/Memcached)。它不修改请求生命周期,只在视图执行前检查,失败则直接返回 HttpResponseTooManyRequests(状态码 429)。
立即学习“Python免费学习笔记(深入)”;
常见配置要点:
- 安装:
pip install django-ratelimit - 在视图上加装饰器:
@ratelimit(key='ip', rate='10/m', method='ALL', block=True) def login_view(request): ... -
key='user'适用于登录后场景,但需确保request.user已认证;key='header:x-api-key'可用于 API Key 级限流 - 务必设置
CACHES配置指向 Redis,否则默认用本地内存缓存,多实例下限流失效 -
block=True表示直接拦截并返回 429;设为False则仅注入request.limited标志,需手动处理
别踩的坑:中间件本身成瓶颈或绕过点
限流中间件如果实现粗糙,反而会放大攻击面。最典型的是:用同步 Redis 客户端、在限流逻辑里做耗时 DB 查询、或把限流键设成高基数字段(如 user_id 却没索引支撑)。
- 避免在限流路径中调用
requests.get()或 ORM 查询——所有操作必须是异步或 O(1) 缓存读写 - 不要用
time.time()+ 字典手工计数:并发下计数错乱,且无法跨进程 - 攻击者可能伪造
X-Forwarded-For绕过 IP 限流,生产环境必须校验该头是否来自可信代理(如 Nginx 配置set_real_ip_from) - 限流规则要分层:登录接口用
3/minute,健康检查接口用60/minute,静态资源不限——统一硬限值反而伤正常流量
真正有效的防护永远是分层的:边缘(Cloudflare/WAF)挡掉 95% 流量,接入层(Nginx)做连接数和请求速率限制,应用层中间件只兜底处理漏网的、语义明确的恶意行为。中间件不是盾牌,而是最后一道闸门——开太小会误伤,开太大等于没关。


















