巧用“分流”规则:给我看看你的真实IP
本文最后更新于 11 天前。

前言:你们怎么都开了梯子

最近在开发一个 IP 地址查询工具,核心功能很简单:用户访问网页,显示用户当前的 IP 地址以及推断其所在地(开盒)。

看起来很简单,对吧?后端的 PHP 代码里写一句 $_SERVER['REMOTE_ADDR'] 不就完事了吗?

但在实际测试中,我遇到了一个典型的场景:目标用户群体大多开启了代理软件(如 Clash、v2ray 等)

  • 如果你开的是“全局模式”,你厉害,我没办法。
  • 但大部分用户使用的是 “规则模式(分流)”

难点出现了: 我希望获取到用户本地的真实 IP(如家里的宽带 IP),但我的服务器看到的却是他的 代理IP

弯路:浏览器的拦路虎 —— CORS 跨域

最初的思路很简单:既然后端获取到的是代理 IP,那就让前端浏览器通过 JS 去请求第三方 IP 接口,拿到结果后再传回后端。

我首先尝试了 fetch('https://ipplus360.com/getIP')。结果控制台直接飘红:

Access to fetch at ‘…’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

原因分析
这是浏览器同源策略的限制。我所请求的这个第三方接口并没有在其响应头中允许跨域访问。无论我在前端怎么折腾,浏览器都会无情拦截。

破局:核心原理——利用“分流规则”

在分析了多个同类网站的网络请求后,我发现一些老牌 IP 查询网站(如 iplarkip.skk.moe)竟然能同时显示“本地 IP”和“代理 IP”。但在调试过程中,我发现了一个更有趣的现象,这才是解决问题的核心。

为什么换成国内接口后,就能取到真实 IP 了?

这不仅仅是因为它允许跨域,更是因为代理软件的“分流策略”(Split Routing)

1. 代理软件的工作逻辑

绝大多数国内用户的代理软件(开启规则模式时)都遵循一套基本逻辑:

  • 国外域名 →→ 匹配规则 →→ 走代理隧道 →→ 暴露代理 IP。
  • 国内域名(CN Direct) →→ 匹配规则 →→ 直连(Direct) →→ 暴露本地真实 IP

2. 顺水推舟的解决方案

既然代理软件会自动区分流量,我们完全可以利用这一点:

  1. 前端发起请求:JS 强制浏览器请求一个国内的 IP 查询接口(该接口必须支持 CORS)。
  2. 触发分流规则:用户的代理软件拦截到这个请求,发现目标域名是国内的(如 .cn 后缀)。
  3. 建立直连:代理软件判定该请求不走代理,直接通过用户的本地网卡/路由器发出。
  4. 获取真实 IP:目标服务器收到的请求来源是用户的家庭宽带 IP,并将其返回。
  5. 回传后端:前端拿到这个真实 IP 后,再传给我的后端 PHP 进行地理位置解析。

代码实现

虽然逻辑通了,但在解析 my.ip.cn 返回的数据时,还遇到了页面结构变更的坑。由于该接口返回的是 HTML 而非 JSON,我们需要用正则表达式去提取。

以下是最终的实现代码:

async function getInitialIp() {
    try {
        // 1. 请求国内接口
        // 关键点:该接口支持 CORS,且能触发代理软件的“国内直连”规则
        const response = await fetch('https://my.ip.cn/', { cache: 'no-cache' });
        
        if (!response.ok) {
            throw new Error('网络响应异常');
        }
        
        const text = await response.text();
        
        // 2. 解析 HTML 提取 IP
        // 坑点:对方页面结构可能会变(如全角冒号、空格等),正则需要灵活
        // 匹配格式示例:"ip:112.10.10.10 归属地:..."
        const ipRegex = /ip:(.*?) 归属地/; 
        const match = text.match(ipRegex);
        
        if (match && match[1]) {
            const realIp = match[1].trim();
            console.log("利用分流规则成功获取真实IP:", realIp);
            
            // 3. 将真实 IP 传给后端 PHP 进行后续业务处理(如查询经纬度)
            fetchGeoData(realIp);
        } else {
            throw new Error('IP解析失败,页面结构可能已变更');
        }
    } catch (error) {
        console.error("获取IP流程中断:", error);
    }
}

最后

首先,要特别感谢 iplarkip.skk.moe 等IP检测网站,正是研究它们的工作原理,才让我找到了问题的解决方案。

其次,即使你使用了代理,利用“分流规则”依然可能暴露你的真实IP。所以在访问任何网站时,请务必保持对个人网络 IP 安全的警惕。

我没有绕过代理,我只是让代理软件帮我做出了正确的路由选择。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇