Nginx 本身不生成凭证,仅作前置拦截与透传标记;重放防护需分层实现:HTTP 请求用 Nonce+时间戳+Redis 一次性校验,TLS 1.3 0-RTT 需拦截非幂等方法并透传 Early-Data,CSRF 依赖后端一次性 Token 清除机制。

Nginx 本身不直接防御重放攻击(Replay Attack),因为它工作在传输层和应用层之间,不具备对 HTTP 请求内容(如时间戳、nonce、签名)的校验能力。重放攻击的防护核心在于业务层鉴权机制,比如 JWT 签名验证、API 签名+时间戳+随机数(nonce)、一次性 token 等。但 Nginx 可以作为前置协同组件,通过以下方式增强整体防护能力,阻止明显异常的重放行为:
✅ 强制请求时效性(配合后端签名逻辑)
重放攻击常依赖“旧请求被反复提交”。若后端要求每个请求携带 timestamp(如 Unix 秒级时间)且只接受 30 秒内的时间戳,Nginx 可提前拦截明显过期的请求:
# 在 location 中添加时间校验(需开启 ngx_http_realip_module 和时间模块支持)
set $ts "";
if ($args ~* "timestamp=(\d+)") {
set $ts $1;
}
# 拒绝 timestamp 超过 30 秒的请求(注意:需确保系统时钟同步)
if ($ts) {
set $diff "";
# 使用第三方模块如 lua-resty-time 或 OpenResty 的 os.time() 更可靠
# 纯 Nginx 原生无时间计算能力,此处为示意逻辑
}⚠️ 注意:标准 Nginx 不支持运行时时间运算,上述 if + time diff 无法原生实现。真正可行的方式是:
- 由后端服务完成 timestamp/nonce 校验
-
Nginx 配合做前置过滤:例如用
map+limit_req对高频重复路径限速,或结合ngx_http_lua_module(OpenResty)做轻量校验。
✅ 利用 limit_req 防止“短时批量重放”
攻击者可能截获一个合法请求,瞬间重放数百次。Nginx 可限制单 IP 在关键接口(如 /api/order, /login)的请求频次,大幅提高重放成本:
http {
# 定义每 IP 每分钟最多 5 次请求(按业务敏感度调整)
limit_req_zone $binary_remote_addr zone=api_replay:10m rate=5r/m;
upstream backend {
server 192.168.1.10:8000;
server 192.168.1.11:8000;
}
}
server {
location /api/ {
# 关键 API 路径启用限速,burst=2 允许瞬时小脉冲,nodelay 立即拒绝超限
limit_req zone=api_replay burst=2 nodelay;
proxy_pass http://backend;
proxy_set_header X-Real-IP $remote_addr;
}
}这样即使攻击者手握有效请求,也无法在 1 分钟内发起超过 5 次调用,显著削弱自动化重放效果。
✅ 拦截无签名或缺失关键参数的请求
若业务约定所有敏感请求必须带 sign 和 nonce 参数,可用 if + return 提前拦截明显不合规请求(注意:if 在 location 中慎用,但简单参数检查安全):
location /api/pay {
# 检查必要参数是否存在
if ($arg_sign = "") { return 400; }
if ($arg_nonce = "") { return 400; }
if ($arg_timestamp = "") { return 400; }
proxy_pass http://backend;
proxy_set_header X-Nonce $arg_nonce;
proxy_set_header X-Timestamp $arg_timestamp;
}后端再基于 X-Nonce 做去重缓存(如 Redis 记录已用 nonce,5 分钟失效),即可实现一次一验。
✅ 启用 HTTPS 并禁用不安全协议
重放攻击常发生在明文 HTTP 下。Nginx 必须强制 HTTPS,并关闭老旧协议,防止中间人截获并重放:
server {
listen 443 ssl http2;
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3; # 禁用 TLSv1.0/1.1
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}HTTPS 本身不能防重放,但它是签名验证、时间戳传输的前提——没有加密通道,签名和时间戳可被篡改或窃取。
不复杂但容易忽略


















