需在nginx的listen 80 server块中,于return 301前用自定义log_format记录$remote_addr、$http_user_agent、$request_uri等字段,并通过set_real_ip_from校验x-forwarded-for,添加redirected=1标识及$status、$sent_http_location,日志单独输出、禁用缓冲以保障审计完整性。

要记录所有从 HTTP 入口进入、并被重定向到 HTTPS 的请求指纹,核心不是“拦截”或“阻止”,而是“可观测”——在重定向发生前,把原始 HTTP 请求的关键上下文完整捕获下来,写入日志供审计分析。
在 HTTP server 块中提前采集指纹并记录
不能依赖 HTTPS server 块的日志,因为重定向发生在 HTTP 端口(80),用户尚未到达加密通道。必须在 listen 80 的 server 块里完成日志记录:
- 使用自定义
log_format包含能反映客户端行为的变量,例如:$remote_addr(真实 IP 或经$http_x_forwarded_for补充后的源地址)、$http_user_agent(识别爬虫/工具链)、$http_accept_language(辅助判断一致性)、$request_uri(含参数,可发现扫描路径如/wp-login.php?log=admin)、$time_local(精确到秒,支持时间维度聚类) - 避免在重定向指令(如
return 301)之后写日志——Nginx 不会执行后续语句。日志指令必须放在return或rewrite ... permanent之前
区分真实客户端与代理穿透场景
仅用 $remote_addr 可能记录的是负载均衡或 CDN 的 IP。需结合 $http_x_forwarded_for 提取原始来源,但必须做可信校验:
- 只信任来自已知可信代理(如内网 LB 的 IP 段)的
X-Forwarded-For头 - 配置
set_real_ip_from+real_ip_header X-Forwarded-For,让 Nginx 把可信代理传来的第一个非私有地址设为$remote_addr - 若未启用 real_ip 模块,可单独记录
$http_x_forwarded_for字段,但需在日志中明确标注“未经校验”,避免误判
标记重定向行为本身作为审计线索
单纯记录 HTTP 请求还不够,要明确标识“该请求最终被重定向”,便于后续筛选和统计:
- 在日志格式中加入固定字段,如
redirected=1,直观表明此条日志对应一次重定向触发事件 - 配合
map指令打标:例如定义map $scheme $is_http_redirect { "http" "1"; default "0"; },再注入日志,比硬编码更灵活 - 可额外记录
$status(重定向返回码,应为 301 或 302)和$sent_http_location(重定向目标 URL),验证跳转逻辑是否符合预期
防止日志污染与性能干扰
安全审计日志需长期保留、高频写入,要兼顾完整性与稳定性:
- 将这类指纹日志单独输出到专用文件(如
/var/log/nginx/http-redirect-audit.log),不混入常规 access 日志,便于归档与权限隔离 - 关闭
buffer和flush参数(即不启用日志缓冲),确保每条记录实时落盘,避免进程崩溃时丢失关键审计事件 - 若流量极大,可考虑用
limit_req对日志写入做轻量限频(如 per-ip 每秒最多记 5 条),防止日志风暴,但需评估漏记风险











