EdgeOne 获取用户真实 IP 完整解决方案(Nginx 适配版)


在使用腾讯云 EdgeOne 海外节点加速海外业务时,很多开发者会遇到一个核心问题:Nginx 日志中记录的是 EdgeOne 节点 IP 而非用户真实 IP,导致无法进行用户行为分析、地域统计和异常访问拦截。本文将从「问题原理」「手动配置」「自动化更新」「故障排查」四个维度,提供一套适配 Nginx + 宝塔面板的完整解决方案,新手也能快速上手。 一、核...

在使用腾讯云 EdgeOne 海外节点加速海外业务时,很多开发者会遇到一个核心问题:Nginx 日志中记录的是 EdgeOne 节点 IP 而非用户真实 IP,导致无法进行用户行为分析、地域统计和异常访问拦截。本文将从「问题原理」「手动配置」「自动化更新」「故障排查」四个维度,提供一套适配 Nginx + 宝塔面板的完整解决方案,新手也能快速上手。

一、核心原理:为什么需要特殊配置?

当用户访问经过 EdgeOne 加速的网站时,请求会先经过 EdgeOne 海外节点(反向代理),再由节点转发到源站 Nginx。此时 Nginx 会默认将「直接连接的客户端 IP」(即 EdgeOne 节点 IP)识别为用户 IP,而非真实的用户公网 IP。
解决思路的核心是「信任代理」:
  1. EdgeOne 节点会在转发请求时,通过 X-Forwarded-For 头携带用户真实 IP(格式:用户真实IP, 节点IP1, 节点IP2);
  2. 配置 Nginx 信任所有 EdgeOne 节点 IP,让 Nginx 从 X-Forwarded-For 头中自动跳过节点 IP,提取最原始的用户真实 IP。
关键提示:本文以「海外业务场景」为例,适配 CentOS 系统 + Nginx + 宝塔面板,其他系统(如 Ubuntu)或 Web 服务器(如 Apache)可参考原理调整。

二、前置准备:确认 EdgeOne 基础配置

在配置 Nginx 前,需先确保 EdgeOne 已正确配置「回源透传」,否则节点不会携带用户真实 IP 信息:
  1. 登录 EdgeOne 控制台,进入目标站点的「回源配置」;
  2. 开启「HTTP 头配置」,确认已添加「透传 X-Forwarded-For 头」(默认开启,若未开启需手动添加);
  3. 关闭「源站保护」功能(重要!开启后无法获取完整节点 IP 段,配置完成后可重新开启)。

三、手动配置:快速实现真实 IP 解析

若业务规模较小,可先通过手动配置验证效果,步骤如下:

3.1 获取 EdgeOne 海外节点 IP 段

EdgeOne 提供官方接口用于获取最新节点 IP 段,海外 IPv4 段专属获取方式:
  1. 本地浏览器访问接口:https://api.edgeone.ai/ips?version=v4&area=overseas(仅返回海外节点 IP 段,精准适配海外业务);
  2. 复制页面中所有 IP 段(纯文本格式,如 43.174.0.0/15),保存到本地文档。
注意事项:接口返回的 IP 段会不定期更新,建议每 1-2 个月重新获取一次,避免因 IP 段过期导致解析失效。

3.2 配置 Nginx 信任节点 IP 段

通过宝塔面板修改 Nginx 配置(手动操作更直观,适合新手):
  1. 登录宝塔面板,进入「网站」→ 目标站点(如 music.686909.xyz)→ 「配置文件」;
  2. 在 server 块顶部添加「节点 IP 段信任配置」,完整配置示例如下(重点关注标记内内容):
server
{
    listen 80;
    listen 443 ssl;
    listen 443 quic;
    http2 on;
    server_name music.686909.xyz;

    # ====== EDGEONE_IP_START 标记(后续自动化需用到)======
    # EdgeOne 海外节点 IP 段(手动复制接口返回内容)
    set_real_ip_from 43.174.0.0/15;
    set_real_ip_from 45.12.0.0/16;
    set_real_ip_from 45.65.0.0/16;
    set_real_ip_from 45.113.0.0/16;
    set_real_ip_from 52.58.0.0/15;
    # ... 此处省略其他从接口获取的 IP 段,需完整粘贴 ...
    set_real_ip_from 217.160.0.0/16;
    # ====== EDGEONE_IP_END 标记(后续自动化需用到)======

    # 真实 IP 解析核心规则
    real_ip_header X-Forwarded-For;        # 从该头提取真实 IP
    real_ip_recursive on;                  # 递归跳过信任的节点 IP
    set_real_ip_from 127.0.0.1;            # 额外信任本地代理(避免干扰)

    # 以下为原有配置(SSL、反向代理等,无需修改)
    index index.html index.htm default.htm default.html;
    root /www/wwwroot/music;
    ssl_certificate    /www/server/panel/vhost/cert/music/fullchain.pem;
    ssl_certificate_key    /www/server/panel/vhost/cert/music/privkey.pem;
    # ... 其他配置省略 ...
}
  1. 点击「保存」,然后在宝塔面板「服务」中重启 Nginx,配置生效。

3.3 验证配置效果

配置完成后,通过以下步骤确认真实 IP 是否解析成功:
  1. 用海外网络访问目标网站(如通过海外 VPN 或在线代理工具);
  2. 在宝塔面板进入「网站」→ 目标站点 → 「日志」,查看访问日志(如 music.log);
  3. 日志中「IP」字段若显示为非 EdgeOne 网段的公网 IP(可通过 IP138 验证归属地),说明解析成功。

四、自动化方案:IP 段自动更新(运维必备)

手动更新 IP 段效率低且易遗漏,通过「Shell 脚本 + 定时任务」可实现全自动更新,核心逻辑:定期从官方接口获取最新 IP 段 → 自动替换 Nginx 配置 → 验证并重启 Nginx。

4.1 编写自动更新脚本

创建脚本 update_edgeone_ips.sh,上传到服务器 /root/ 目录,脚本已适配海外节点和宝塔面板,关键部分已加注释(需替换脚本中 NGINX_CONF 为你的站点配置路径):
#!/bin/bash
# ==============================================
# EdgeOne 海外节点 IP 段自动更新脚本(Nginx 适配版)
# 功能:接口获取IP段 → 替换配置 → 验证重启 → 备份回滚
# 适配:CentOS + 宝塔面板 + 海外业务
# ==============================================

# ---------------------- 核心参数(需根据实际调整)----------------------
NGINX_CONF="/www/server/panel/vhost/nginx/python_music.conf"  # 你的站点Nginx配置路径
IP_API="https://api.edgeone.ai/ips?version=v4&area=overseas"  # 海外IPv4专属接口
TIMEOUT=30  # 接口超时时间(秒)
RETRY=3     # 接口失败重试次数
# ---------------------------------------------------------------------------

# 临时文件(规避Sed长字符串语法问题)
TMP_IP_FILE=$(mktemp)
TMP_NGINX_CONF=$(mktemp)
BACKUP_CONF="${NGINX_CONF}.bak.$(date +%Y%m%d)"  # 带日期的配置备份文件

# 1. 接口获取IP段(适配海外网络,带重试+证书兼容)
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 从官方接口获取EdgeOne海外IP段(最多重试$RETRY次)..."
for ((i=1; i<=$RETRY; i++)); do
    # curl参数说明:跳过证书校验、设置超时、失败重试
    curl -s --connect-timeout 10 --max-time $TIMEOUT \
         --retry $RETRY --retry-delay 3 \
         --insecure \
         "$IP_API" > "$TMP_IP_FILE"

    # 验证获取结果:非空且包含标准IPv4网段格式
    if [ -s "$TMP_IP_FILE" ] && grep -qE '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$' "$TMP_IP_FILE"; then
        echo "[$(date +'%Y-%m-%d %H:%M:%S')] ✅ 第$i次尝试成功,获取到有效IP段"
        break
    else
        echo "[$(date +'%Y-%m-%d %H:%M:%S')] ❌ 第$i次尝试失败,正在重试..."
        if [ $i -eq $RETRY ]; then
            echo "[$(date +'%Y-%m-%d %H:%M:%S')] ❌ 所有重试失败,无法获取IP段,退出脚本"
            rm -f "$TMP_IP_FILE" "$TMP_NGINX_CONF"
            exit 1
        fi
    fi
done

# 2. 过滤无效IP段并生成Nginx格式配置
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 过滤无效IP段并生成配置..."
# 仅保留标准IPv4网段,剔除异常内容
grep -E '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}$' "$TMP_IP_FILE" > "$TMP_IP_FILE.tmp"
mv "$TMP_IP_FILE.tmp" "$TMP_IP_FILE"

# 检查过滤后是否有有效IP段
if [ ! -s "$TMP_IP_FILE" ]; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] ❌ 过滤后无有效IP段,退出脚本"
    rm -f "$TMP_IP_FILE" "$TMP_NGINX_CONF"
    exit 1
fi

# 生成带标记的完整IP配置(写入临时文件,避免Sed拼接过长)
IP_CONFIG_FILE=$(mktemp)
echo "# ====== EDGEONE_IP_START 自动更新标记(请勿删除)======" > "$IP_CONFIG_FILE"
echo "# 自动更新时间:$(date +'%Y-%m-%d %H:%M:%S')" >> "$IP_CONFIG_FILE"
echo "# EdgeOne 海外节点IP段(从官方接口获取)" >> "$IP_CONFIG_FILE"
# 将IP段转换为Nginx的set_real_ip_from格式
awk '{print "    set_real_ip_from " $0 ";"}' "$TMP_IP_FILE" >> "$IP_CONFIG_FILE"
echo "# ====== EDGEONE_IP_END 自动更新标记(请勿删除)======" >> "$IP_CONFIG_FILE"

# 3. 备份原Nginx配置(避免替换失败导致服务异常)
cp "$NGINX_CONF" "$BACKUP_CONF"
echo "[$(date +'%Y-%m-%d %H:%M:%S')] ✅ 原配置已备份至:$BACKUP_CONF"

# 4. 替换配置文件中的IP段(文件分段拼接,兼容长内容)
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 开始替换Nginx配置中的IP段..."
# 步骤1:提取标记前的内容
sed -n '/# ====== EDGEONE_IP_START 自动更新标记(请勿删除)======/q;p' "$NGINX_CONF" > "$TMP_NGINX_CONF"
# 步骤2:插入新生成的IP配置
cat "$IP_CONFIG_FILE" >> "$TMP_NGINX_CONF"
# 步骤3:提取标记后的内容(排除结束标记本身,避免重复)
sed -n '/# ====== EDGEONE_IP_END 自动更新标记(请勿删除)======/,$!d;/# ====== EDGEONE_IP_END 自动更新标记(请勿删除)======/!p' "$NGINX_CONF" >> "$TMP_NGINX_CONF"

# 覆盖原配置并保持文件权限(宝塔默认Nginx配置权限为644)
cp "$TMP_NGINX_CONF" "$NGINX_CONF"
chmod 644 "$NGINX_CONF"

# 5. 验证配置替换结果
if grep -q "set_real_ip_from 43.174.0.0/15;" "$NGINX_CONF"; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] ✅ IP段成功写入Nginx配置"
else
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] ❌ IP段写入失败,正在恢复原配置..."
    cp "$BACKUP_CONF" "$NGINX_CONF"
    rm -f "$TMP_IP_FILE" "$TMP_NGINX_CONF" "$IP_CONFIG_FILE"
    exit 1
fi

# 6. 测试Nginx配置并重启服务
echo "[$(date +'%Y-%m-%d %H:%M:%S')] 测试Nginx配置语法有效性..."
if /www/server/nginx/sbin/nginx -t; then
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] ✅ 配置语法正确,重启Nginx服务..."
    /www/server/nginx/sbin/nginx -s reload
    IP_COUNT=$(wc -l < "$TMP_IP_FILE")
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] 🎉 全部操作完成!本次共更新$IP_COUNT个海外IP段"
else
    echo "[$(date +'%Y-%m-%d %H:%M:%S')] ❌ 配置语法错误,正在恢复原配置..."
    cp "$BACKUP_CONF" "$NGINX_CONF"
    /www/server/nginx/sbin/nginx -s reload
    rm -f "$TMP_IP_FILE" "$TMP_NGINX_CONF" "$IP_CONFIG_FILE"
    exit 1
fi

# 清理临时文件
rm -f "$TMP_IP_FILE" "$TMP_NGINX_CONF" "$IP_CONFIG_FILE"

4.2 脚本授权与测试运行

通过 SSH 工具登录服务器(如 Xshell、FinalShell),执行以下命令完成脚本授权和手动测试,确保脚本可正常运行:
# 1. 给脚本添加可执行权限(仅需执行一次)
chmod +x /root/update_edgeone_ips.sh

# 2. 手动执行脚本,验证流程是否正常
/root/update_edgeone_ips.sh

成功运行的输出示例:

[2025-12-01 09:30:00] 从官方接口获取EdgeOne海外IP段(最多重试3次)...
[2025-12-01 09:30:02] ✅ 第1次尝试成功,获取到有效IP段
[2025-12-01 09:30:02] 过滤无效IP段并生成配置...
[2025-12-01 09:30:02] ✅ 原配置已备份至:/www/server/panel/vhost/nginx/python_music.conf.bak.20251201
[2025-12-01 09:30:03] 开始替换Nginx配置中的IP段...
[2025-12-01 09:30:03] ✅ IP段成功写入Nginx配置
[2025-12-01 09:30:04] 测试Nginx配置语法有效性...
nginx: the configuration file /www/server/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /www/server/nginx/conf/nginx.conf test is successful
[2025-12-01 09:30:04] ✅ 配置语法正确,重启Nginx服务...
[2025-12-01 09:30:05] 🎉 全部操作完成!本次共更新36个海外IP段

常见测试失败处理:

若提示 “接口访问失败”,可先执行 curl -v --insecure https://api.edgeone.ai/ips?version=v4&area=overseas 查看具体错误(如防火墙拦截、DNS 解析异常),针对性解决后再重新测试。

4.3 配置定时任务(实现每月自动更新)

手动执行脚本可验证效果,但为避免 IP 段过期,需配置定时任务每月自动更新,通过宝塔面板操作更直观:
  1. 登录宝塔面板,进入「计划任务」模块,点击「添加任务」;
  2. 任务类型:选择「Shell 脚本」(核心类型,执行服务器命令);
  3. 执行周期:选择「每月」,日期设为「1」,时间选凌晨空闲时段(如 03:00,避免影响业务);
  4. 脚本路径:填写 /root/update_edgeone_ips.sh(脚本实际存放路径);
  5. 日志设置:勾选「保存日志」,日志路径默认即可(便于后续排查执行情况);
  6. 点击「添加」,系统会自动生成定时任务,每月 1 号凌晨自动执行 IP 段更新。
⚠️ 注意事项:添加定时任务后,建议手动执行一次「测试」按钮,确认任务可正常触发脚本,避免因路径错误、权限问题导致定时执行失败。

五、常见问题与故障排查

配置过程中可能遇到接口访问失败、真实 IP 解析无效等问题,以下是高频问题的解决方案,按排查优先级排序:

5.1 接口无法获取 IP 段(脚本第一步失败)

错误现象 核心原因 解决方案
curl: (7) Connection timed out 服务器防火墙 / 安全组禁止 443 出站 1. 宝塔面板「安全」→「防火墙」→ 放行「443 出站」;2. 云厂商控制台(如腾讯云)安全组添加规则:允许 TCP:443 出站
curl: (6) Could not resolve host DNS 解析异常,无法识别 api.edgeone.ai 修改服务器 DNS 配置:编辑 /etc/resolv.conf,添加 nameserver 8.8.8.8(谷歌 DNS)或 nameserver 1.1.1.1(Cloudflare DNS),保存后执行 systemctl restart network
返回内容为空或非 IP 段 接口参数错误,未指定海外区域 确认脚本中 IP_API 为 https://api.edgeone.ai/ips?version=v4&area=overseas,而非默认的全球接口

5.2 真实 IP 解析不生效(日志仍为节点 IP)

这是最常见的问题,按以下步骤逐步排查,可覆盖 90% 以上场景:
  1. 检查 EdgeOne 透传配置:登录 EdgeOne 控制台,确认「回源配置」→「HTTP 头配置」中已开启「透传 X-Forwarded-For 头」,且未开启「源站保护」(开启后会隐藏节点 IP);
  2. 验证 Nginx 核心规则:确保 real_ip_header X-Forwarded-For; 和 real_ip_recursive on; 已配置,且位于所有 set_real_ip_from 规则之后(顺序错误会导致解析失效);
  3. 确认 IP 段完整性:在访问日志中复制记录的 “节点 IP”,通过 EdgeOne 控制台「工具」→「IP 归属查询」确认是否为 EdgeOne 节点 IP,若不在配置的 IP 段中,说明 IP 段未更新,需重新执行脚本;
  4. 重启 Nginx 服务:配置修改后未重启服务,执行 www/server/nginx/sbin/nginx -s reload 确保配置生效。

5.3 脚本替换配置后 Nginx 启动失败

主要原因是配置语法错误,脚本已内置回滚机制,会自动恢复原配置,可通过以下方式定位问题:
  1. 查看 Nginx 错误日志:执行 cat /www/server/nginx/logs/error.log,重点关注 “syntax error” 相关内容;
  2. 检查 IP 段格式:手动打开 Nginx 配置文件,确认标记内的 set_real_ip_from 规则是否均为 set_real_ip_from x.x.x.x/x; 格式,无多余空格、逗号;
  3. 恢复原配置:若脚本未自动回滚,执行 cp 备份文件路径 原配置路径(如 cp /www/server/panel/vhost/nginx/python_music.conf.bak.20251201 /www/server/panel/vhost/nginx/python_music.conf),重启 Nginx 即可恢复服务。

六、总结与扩展

本文提供的 EdgeOne 海外节点真实 IP 解析方案,核心是「信任代理节点 IP + 提取 X-Forwarded-For 头真实 IP」,通过 “手动配置验证 + 自动化脚本更新” 的组合,既保证了新手可快速上手,又解决了运维过程中 IP 段过期的痛点。

方案扩展场景

  1. 多站点适配:若服务器部署多个站点,可复制脚本并修改 NGINX_CONF 路径,或在脚本中添加多路径数组循环处理;
  2. IPv6 场景:将脚本中 IP_API 改为 https://api.edgeone.ai/ips?version=v6&area=overseas,同时在 Nginx 配置中添加 real_ip_header X-Forwarded-For;(IPv6 解析规则与 IPv4 一致);
  3. 非宝塔环境:修改脚本中 Nginx 启动命令(如 systemctl restart nginx)和配置路径(如 /etc/nginx/conf.d/your_site.conf)即可适配。
通过本文方案配置后,Nginx 日志将准确记录用户真实 IP,可正常开展地域访问统计、异常 IP 拦截等运维工作,且每月自动更新 IP 段,实现 “一次配置,长期稳定” 的效果。

推荐阅读:

数据库分页 vs 程序分页:核心决策指南与实践方案

Pymusic一款Flask框架开发的音乐网站

评 论
此页面未开启评论