Nginx反向代理GA4时访客地理位置识别为ALB所在地问题排查
Nginx反向代理GA4后访客地理位置全部显示为ALB部署位置故障
问题现象
我已搭建一套基本可正常运行的Nginx反向代理用于对接GA4,目前遇到故障:站点所有访客的地理位置数据均显示为美国弗吉尼亚州阿什本,即我所用ALB的部署位置。
当前GA4事件上报、页面浏览统计均正常触发,仅地理位置识别异常。
补充环境说明:出于性能考虑,我将Google Analytics JS库随Web应用本地部署加载,未纳入本次代理范围,仅修改了库配置,将所有Google Analytics API调用指向自有域名的/workaround-ga4/路径。
现有配置
已移除站点专属信息的Nginx配置如下:
events { worker_connections 4096; } http { set_real_ip_from 10.1.20.0/24; set_real_ip_from 10.1.30.0/24; real_ip_header X-Forwarded-For; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referrer" ' '"$http_user_agent" "$http_x_forwarded_for" '; access_log /var/log/nginx/access.log main; error_log /var/log/nginx/error.log notice; rewrite_log on; server { listen 80; server_name _; client_max_body_size 500M; location / { include uwsgi_params; uwsgi_pass 0.0.0.0:8000; } location /workaround-ga4/ { resolver 8.8.8.8; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; rewrite /workaround-ga4/([^/]+) /g/collect?$args&uip=$remote_addr break; proxy_pass https://www.google-analytics.com; } } }
观测日志
开启rewrite_log后,在Nginx error_log中观测到如下相关日志:
2022/06/21 22:03:36 [notice] 528#528: *1165 "/workaround-ga4/([^/]+)" matches "/workaround-ga4/g/collect", client: 555.555.555.555, server: _, request: "POST /workaround-ga4/g/collect?v=2&tid=G-MYGOOGLEANALYTICSCODE>m=555555&_p=555555555&_z=55555&cid=555555555.5555555555&ul=en-us&sr=5555x555&sid=5555555555&sct=55&seg=5&dl=https%3A%2F%2Fmy.site.com%2F&dt=my%20site%20which%20%7C%20is%20having%20trouble%20with%20googleanalytics&_s=1 HTTP/1.1", host: "my-site.com", referrer: "https://my-site.com/"
2022/06/21 22:03:36 [notice] 528#528: *1165 rewritten data: "/g/collect", args: "v=2&tid=G-MYGOOGLEANALYTICSCODE>m=555555&_p=555555555&_z=5555555&cid=555555555.5555555555&ul=en-us&sr=5555x555&sid=5555555555&sct=55&seg=5&dl=https%3A%2F%2Fmy-site.com%2F&dt=my%20site%20is%20%7C%20having%20problems%20with%20google%20analytics&_s=1&uip=my.real.ip/&v=2&tid=G-MYGOOGLEANALYTICSCODE>m=555555&_p=5555555555&_z=555555&cid=5555555555.5555555555&ul=en-us&sr=5555x555&sid=5555555555&sct=55&seg=5&dl=https%3A%2F%2Fmy-site.com%2F&dt=my%20site%20is%20%7C%20having%20trouble%20with%20google%20analytics&_s=1", client: my.actual.ip, server: _, request: "POST /workaround-ga4/g/collect?v=2&tid=G-MYGOOGLECODE>m=555555&_p=5555555555&_z=555555&cid=5555555555.5555555555&ul=en-us&sr=5555x555&sid=5555555555&sct=55&seg=5&dl=https%3A%2F%2Fmy-site.com%2F&dt=my%20site%20is%20%7C%20having%20trouble%20with%20google%20analytics&_s=1 HTTP/1.1", host: "my-site.com", referrer: "https://my-site.com/"
从日志初步判断重写规则似乎符合预期:uip参数已被设置为访客真实IP,而非ALB的10.1.x网段内网IP。
故障原因
你的配置存在三个核心问题,导致GA4无法读取到正确的用户IP,最终回退使用请求来源IP(即ALB/Nginx的公网出口IP)做地理定位:
- rewrite规则导致查询参数重复
Nginx的rewrite规则默认行为是:如果替换串中包含?(即带查询参数),会自动将原请求的查询字符串追加到你写的查询参数末尾,除非你在替换串末尾加?禁止该行为。你当前的规则手动拼接了?$args&uip=$remote_addr,Nginx又自动追加了一遍原参数,从日志可以看到所有v/tid/cid等参数全部重复了两遍,GA4解析参数时会出现覆盖,无法正确读取到uip值。 - uip参数格式非法
从日志可以看到你拼接的uip=my.real.ip/末尾多了一个斜杠,属于非法IP格式,GA4遇到格式非法的uip参数会直接忽略,不会用它做地理定位。多余斜杠来自你写的正则匹配逻辑缺陷:原正则/workaround-ga4/([^/]+)未加路径锚定,只能匹配不含斜杠的单段路径,匹配/workaround-ga4/g/collect时会出现捕获异常,把路径斜杠带入了参数值。 - 未处理POST请求体参数
本地部署的gtag.js默认会用POST方式发送数据到/g/collect端点,所有上报参数都存放在x-www-form-urlencoded格式的请求体中。你仅在URL上拼接了uip参数,GA4的POST端点会优先读取请求体中的参数,当请求体中无uip、URL参数又解析异常时,会直接使用TCP连接的对端IP做定位。
修复方案
按以下步骤修改配置即可解决问题:
- 替换
/workaround-ga4/路径下的rewrite规则,修正正则、解决参数重复问题,修改后的location配置参考:location /workaround-ga4/ { resolver 8.8.8.8; # 开启real_ip递归,确保多层代理下能拿到正确的用户IP real_ip_recursive on; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 正确正则匹配路径,末尾加?禁止Nginx自动追加原参数,避免重复 rewrite ^/workaround-ga4/(.*)$ /g/collect?uip=$remote_addr&$args? break; # 兼容POST请求,把uip写入请求体 if ($request_method = POST) { proxy_set_body "$request_body&uip=$remote_addr"; } proxy_pass https://www.google-analytics.com; } - 重载Nginx配置后,触发测试请求查看rewrite日志,确认:
- 查询参数无重复
- uip参数值为纯用户IP,无斜杠、端口、多余字符
- 等待1-2小时后查看GA4地理位置报告,数据即可恢复正常。
内容的提问来源于stack exchange,提问作者Taliesin
相关产品推荐
相关产品推荐

