自己搭好 Umami 统计之后,发现后台只能看到访客来自哪个国家,省市那一栏全是空的。后来查了一下才反应过来:前面套了腾讯云的 EdgeOne CDN,Umami 拿到的根本不是访客自己的 IP,而是 EdgeOne 边缘节点的 IP。拿 CDN 节点的 IP 去查自带的离线库,自然查不出具体省市。
改起来有两种路子:要么只把真实 IP 传过去让 Umami 自己查库,要么干脆让 EdgeOne 把查好的省市结果塞进请求头里喂给 Umami。
1. 先把真实客户端 IP 传回去(必做)
不管走哪种方案,都得先把真实 IP 透传打开。
先去腾讯云 EdgeOne 控制台:
1. 进你的站点,点左侧「站点加速 → 网络优化」。
2. 找到「真实客户端 IP 头部」,把开关打开。
3. 头部名称不用改,留着默认的 EO-Connecting-IP 保存就行。
接着去改服务器上的 Umami 容器配置。如果是 docker-compose.yml 跑的,在 environment 底下加一行:
environment:
# 原来的 DATABASE_URL 等保留别动
CLIENT_IP_HEADER: EO-Connecting-IP
改完 docker compose up -d 重启容器。如果没别的要求,光改完这步,Umami 就能拿自带的 GeoLite2 数据库解析出大部分城市了。
2. 顺手让 EdgeOne 直接把省市传过去(国内更准)
Umami 自带的国外离线库查国内小城市有时候不太准。其实 EdgeOne 自己在边缘节点就已经查好省市了,而 Umami 原生认 Cloudflare 格式的地理请求头(CF-IPCountry 那几个)。我们直接在 EdgeOne 里做个伪装,把它的地理变量塞进 CF 的头里传过去就行。
去 EdgeOne 控制台 → 站点加速 → 规则引擎,新建一条空白规则:
- 匹配条件:选 HOST 等于你的 Umami 域名。
- 执行操作:选「修改 HTTP 回源请求头」,挨个「增加」下面这三个头:
| 头部名称 | 填入的值 | 传的是啥 |
|---|---|---|
CF-IPCountry |
${http.request.ip.country} |
国家代码 |
CF-Region-Code |
${http.request.ip.region_code} |
省份代码(比如 CN-JX) |
CF-IPCity |
${http.request.ip.city} |
城市名 |
点保存发布,等个一两分钟就生效了。
3. 宝塔 Nginx 反代别忘了透传
如果你跟我一样,服务器外面还套了一层宝塔的 Nginx 反向代理,上面配的那些请求头到了 Nginx 会被默认吃掉,还得手动去站点配置里加上转发。
去宝塔面板 → 网站 → 找到 Umami 站点点「设置 → 配置文件」,找到反代用的 location / 那段,在 proxy_pass 下面加这几行:
# 转发 EdgeOne 传过来的真实客户端 IP
proxy_set_header EO-Connecting-IP $http_eo_connecting_ip;
# 转发伪装成 CF 格式的省市头
proxy_set_header CF-IPCountry $http_cf_ipcountry;
proxy_set_header CF-Region-Code $http_cf_region_code;
proxy_set_header CF-IPCity $http_cf_ipcity;
# 顺手补上常规转发头
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $http_eo_connecting_ip;
保存重载一下 Nginx,再去刷一下统计后台,省市归属地就正常跳出来了。
参考文献 - https://umami.is/docs - https://console.cloud.tencent.com/edgeone - https://cloud.tencent.com/document/product/1552