核心是利用nginx变量+map模块+条件日志构建身份上下文:先通过set_real_ip_from和real_ip_header还原真实ip,再用map按cidr归类为internal/external,最后通过if条件分离审计日志并支持细粒度标记。

要实现内网访客与外网访客的隔离审计,核心不是“映射 IP”,而是利用 Nginx 的 变量(Variables)+ map 模块 + 条件日志 构建可区分、可过滤、可告警的身份上下文。Nginx 本身不提供“IP 映射表”式的数据转换,但通过 map 指令可将客户端真实 IP($realip_remote_addr)动态归类为 internal / external 标签,并驱动后续日志分离、访问控制或响应头标记。
一、准确识别真实来源 IP
直接用 $remote_addr 会拿到代理或 CDN 的 IP,必须先还原用户真实地址:
- 在
http块顶部启用真实 IP 解析:set_real_ip_from 192.168.0.0/16;set_real_ip_from 10.0.0.0/8;set_real_ip_from 172.16.0.0/12;real_ip_header X-Forwarded-For; - 之后所有逻辑都基于
$realip_remote_addr(Nginx 内置变量,已解析后的结果)
二、用 map 实现 IP 归属分类
在 http 块中定义分类变量,不写死列表,支持 CIDR 和单 IP:
map $realip_remote_addr $client_zone {
default "external";
~^192\.168\. "internal";
~^10\. "internal";
~^172\.(1[6-9]|2[0-9]|3[0-1])\. "internal";
127.0.0.1 "internal";
::1 "internal";
}
该变量值可直接用于:
– 日志格式字段
– location 条件判断
– 响应头注入(如 add_header X-Client-Zone $client_zone;)
三、按归属分离审计日志
避免混杂在通用 access.log 中,为不同来源创建独立日志流:
- 定义专用日志格式(含归属标签):
log_format audit '[$time_local] $client_zone|$remote_addr|$http_x_forwarded_for|$request|$status|$body_bytes_sent|$http_user_agent'; - 在关键 location(如
/admin/、/api/v1/)中启用条件日志:access_log /var/log/nginx/internal_audit.log audit if=$client_zone="internal";access_log /var/log/nginx/external_audit.log audit if=$client_zone="external"; - 日志权限设为
640,属组限定为安全审计团队
四、延伸:结合身份做细粒度审计
仅靠 IP 分类不够——内网员工也可能越权,外网攻击者也可能伪造内网头。需叠加业务身份字段:
- 从请求头提取用户标识:
map $http_x_user_id $audit_user_id { default "-"; } - 标记高危操作路径:
map "$request_method:$uri" $is_admin_op {~^(POST|PUT|DELETE):/admin/|/sys/|/api/v1/(users|roles)" "1"; default "0";} - 组合写入日志:
log_format audit_full '$client_zone|$audit_user_id|$is_admin_op|$request|$http_referer'; - 用简单命令快速筛查异常:
grep '|internal|1|' /var/log/nginx/internal_audit.log | awk -F'|' '{print $2}' | sort | uniq -c | sort -nr→ 查看哪些内网用户高频触发管理操作











