V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
myqoo
V2EX  ›  程序员

判断 IP 是否为境内,有什么推荐的方案

  •  
  •   myqoo · 334 天前 · 6697 次点击
    这是一个创建于 334 天前的主题,其中的信息可能已经有所发展或是发生改变。

    要考虑两点,第一是网段的准确性 /实时性,第二是判断性能。

    简单搜了下公开的数据,发现 github 有个 china_ip_list 的项目:

    https://github.com/17mon/china_ip_list/blob/master/china_ip_list.txt

    不过实时性好像不是很高(写着季度更新),不知质量如何。是否还有其他更好的推荐?


    第二个是判断性能。之前用过 nodejs 自带的 BlockList,虽然用起来很简单,但后来发现性能并不好,看了下源码才知道它居然是逐条匹配的,没有任何算法优化。

    之前也有人反馈过这个问题: https://github.com/nodejs/node/issues/46070

    看来目前还是得用 C 写一个 node addon 扩展。

    此外,这个算法只用于查询,并没有增删改,并且 CIDR 的范围也是 2 的次方数,是否可进一步优化?

    43 条回复    2023-05-05 10:22:03 +08:00
    pagxir
        1
    pagxir  
       334 天前 via Android
    IPv4 的可以用我这个,https://gist.github.com/pagxir/b4552da41207749a7cce6c5512aef692
    二分查找。
    XIU2
        2
    XIU2  
       334 天前
    @pagxir 问下,
    我以前见到论坛里有个人分享过类似的 PAC 脚本,但和你的写法不一样,哪个效率性能更高一些呢?
    https://gist.github.com/weijarz/a76641504c97f0c3e48e207ec4df7db5
    greatbody
        3
    greatbody  
       334 天前
    如果你是想屏蔽境内的访问,直接套 Cloudflare ,设置一个禁止访问的区域就可以了。ChatGPT 就是这么做的。
    Xianmua
        4
    Xianmua  
       334 天前 via iPhone   ❤️ 5
    咳咳,判断能不能访问 google
    NoOneNoBody
        5
    NoOneNoBody  
       334 天前
    ip 特质就是字符串记录整数,转整数位运算肯定快一点
    cnbatch
        6
    cnbatch  
       334 天前
    如果单纯想查是否国内,那么 ipip net 就有。
    “宽带症候群”节点那边经常用 ipip 的 BestTrace 工具查中间设备的 IP 归属。有时候稍有偏差,不过都是省市级的偏差(尤其是运营商新增设备时,IP 库记录更新没那么快),放宽到国家范围的话基本都是准确的。

    但可供下载的每日更新的 IP 库并不免费。或者也可以用他们的免费 API 查 IP 。
    star7th
        7
    star7th  
       334 天前
    如果不考虑实时性的,则很多开源方案。要考虑实时性的,肯定要人家不断付出时间精力成本去维护,基本上不用想着能免费获得。你这属于既要又要。
    开源方案的话,推荐 nodejs 库 geoip-lite ,性能很快的,因为它是预加载所有数据到内存。内存占用一百多 M 吧。
    HawkinsSherpherd
        8
    HawkinsSherpherd  
       333 天前
    在支持免费 bgp 会话的服务商上搞个 vps 建立 bgp 会话,实时获取全球路由表。
    如果用的是小内存的机型,记得把 bgp 路由灌进系统路由表的功能关掉,具体操作视使用的软件而定。
    用正则表达式过滤出经过特定 AS 的 bgp 路由,然后将输出结果重定向到文件中,再将输出结果格式化。
    lcy630409
        9
    lcy630409  
       333 天前   ❤️ 1
    不是有 geoip 么?离线版本 快得很
    thevita
        10
    thevita  
       333 天前
    就是用 ip 库啊,看你需求(准确, 更新, 粒度) 有免费的和收费的企业服务可选
    csrocks
        11
    csrocks  
       333 天前
    在客户端 curl google.com , 结果提供给服务端😅
    salmon5
        12
    salmon5  
       333 天前
    @csrocks #11 很多年前 360 浏览器客户端是这么弄的
    leido
        13
    leido  
       333 天前 via Android
    @salmon5 所以装一个 360 就得被诬陷翻墙
    bug123
        14
    bug123  
       333 天前
    @Xianmua 谁说境内 IP 不能访问 Google 的
    zictos
        15
    zictos  
       333 天前
    Xianmua
        16
    Xianmua  
       333 天前
    @bug123 玩笑,而已。大多数应该访问不了吧,配合其他信息当免费 api 用 虽然不太严谨也不是不行。ip-api#com 这个免费的查询 api 也可用,至于高性能上面就都不满足要求了,看上面几位说的吧
    yolooo
        17
    yolooo  
       333 天前
    @Xianmua #4 你是懂 IP 的
    VYSE
        18
    VYSE  
       333 天前   ❤️ 1
    自己 proxy 里写的二叉代码,逻辑可以参考

    def init_chn_list():
    global CHN_IP, KEYS_CHN_IP
    t = requests.get("https://cdn.jsdelivr.net/gh/17mon/china_ip_list@master/china_ip_list.txt", proxies=proxies, stream=True)
    for l in t.iter_lines():
    ip, sub = l.split(b'/')
    ip = ip.decode('ascii')
    ip = struct.unpack("!I", inet_aton(ip))[0]
    ip_end = ip + 2 ** (32 - int(sub))
    CHN_IP.append((ip, ip_end))

    CHN_IP.sort(key=lambda key: key[0])
    INDEX_CHN_IP = [i[0] for i in CHN_IP]
    logger.info('init done')

    def is_chn_ip(ip):
    start, end = CHN_IP[bisect.bisect_right(INDEX_CHN_IP, ip) - 1]
    if end > ip >= start:
    return True
    else:
    return False
    estk
        19
    estk  
       333 天前 via iPhone
    如果用 cloudflare 的话,header 里就有国家代码
    serafin
        20
    serafin  
       333 天前
    ipinfo.io
    50k lookups per month.
    Actrace
        21
    Actrace  
       333 天前
    jsq2627
        22
    jsq2627  
       333 天前   ❤️ 1
    如果只是想要判断境内,不需要更详细的地理位置,可以用 APNIC 公开的数据,免费,准确,实时
    http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest

    关于性能,可以尝试自己用:
    https://github.com/metowolf/ipdb-packer/blob/master/index.js
    把上面数据打包成 ipdb 格式,用 https://www.npmjs.com/package/ipdb 解析
    kernelpanic
        23
    kernelpanic  
       333 天前
    ipv4 早就分配完了,已经分给哪个国家的就是哪个国家了,没有实时性一说
    chinafeng
        24
    chinafeng  
       333 天前
    @kernelpanic #23 IP 地址虽然在 RIR 那几乎分配完毕,但是在二级市场的交易和租用相当活跃
    zelin44913
        25
    zelin44913  
       333 天前
    http://ip.bczs.net/country/CN
    一直用的这里的数据,实时性挺高的
    realpg
        27
    realpg  
       333 天前
    世界加钱可及
    JensenQian
        28
    JensenQian  
       333 天前
    https://ispip.clang.cn/
    这个试下
    每日更新
    xw
        30
    xw  
       333 天前 via Android
    alamak76
        31
    alamak76  
       333 天前
    myqoo
        32
    myqoo  
    OP
       333 天前
    @pagxir
    @jsq2627 这个不错!有点不明白的是既然 APNIC 都提供数据了,为什么还有 china_ip_list 这样的项目,不知这类项目有什么特殊的地方,还有这么多人用。
    myqoo
        33
    myqoo  
    OP
       333 天前
    @pagxir 上一条回复 @错了。本来想说你这个代码还可以精简下,把_net_list 变成一个 uint32array + uint8array 看起来可以美观些,初始化和运行性能也可以高一点点。
    Kinnice
        34
    Kinnice  
       333 天前 via Android
    @myqoo 更准
    Kinnice
        35
    Kinnice  
       333 天前 via Android
    eg: 202.95.9.1 实际为 hkip ,你看有多少个 ip 库将其识别为内地 ip
    Greatshu
        36
    Greatshu  
       333 天前   ❤️ 1
    判断能否访问大,纪,元,这个比谷歌更准确
    jsq2627
        37
    jsq2627  
       333 天前
    @myqoo APNIC 只是按照属地原则分配了 IP 所属国家,比如楼上提到的 202.95.9.1 按照 APNIC 是分配到了 SG ,SGNIC 再分配到本地一家 ISP ,但是这家 ISP 在 HK 也有数据中心,把这个 IP 实际用在了 HK 。再比如 Apple 拥有整个 17.0.0.0/8 段,服务器遍布全球各地,但是这段 IP 都不在 APNIC 的分配列表里,因为它都不属于 APNIC 管辖。

    但是如果你的需求只是判断大陆 IP ,用 APNIC 的列表是相对准确的,因为 CNNIC 强制要求各大 ISP 只能广播 CNNIC 分配的 IP 。
    SteveLi77
        38
    SteveLi77  
       333 天前
    所有套了 cloudflare 的网站都可以在 hostname/cdn-cgi/trace 中找到 loc
    rozbo
        39
    rozbo  
       332 天前
    套个 cloudflare ,可以直接 block area ,如果还想更细粒度的控制,就开启下 addon header ,不但能获取到国家,城市,连经纬度都可以获取。
    miaomiao888
        40
    miaomiao888  
       332 天前
    @xw 点进去看到 CF 的中文名原来叫“科赋锐”...
    UnknoownUser
        41
    UnknoownUser  
       332 天前 via iPhone
    判断 ip 是否在前缀内部可以用 trie tree 搜索
    xzysaber
        42
    xzysaber  
       332 天前
    不知道实时是需要多实时。
    https://github.com/Loyalsoldier/v2ray-rules-dat ,这个可以参考下。
    cosmain
        43
    cosmain  
       329 天前
    性能应该是调用 ipset 性能会搞不少吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5414 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 07:52 · PVG 15:52 · LAX 00:52 · JFK 03:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.