V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
dndx
V2EX  ›  分享创造

uip - 获取公网 IP 的小程序

  •  4
     
  •   dndx ·
    dndx · 2023-04-11 03:14:10 +08:00 · 6236 次点击
    这是一个创建于 575 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用 Rust 写了一个获取公网 IP 的小程序。

    其实本来不想造这个轮子的,但是发现国内能稳定提供获取 IP 的服务少之又少,要么不稳定,要么会有各种限流。

    今天突发奇想,NAT 打洞用的 STUN 服务本身就会返回客户端的 IP 地址,国内有不少大厂维护的 STUN 服务器,直接用肯定是最稳定的(因为大厂本身自己的服务也需要用到)。这些 STUN 服务器的稳定性应该不是个人搭建的 IP 查询服务能比的,跑路被打的风险也小很多。

    简单 Google 了一下,竟然还没有人做过专门用来做这个的程序。我就基于 Rust 的 stun Crate example 改了一个。

    用起来非常简单,直接到 Release 页面下载自己架构的可执行文件 chmox +x uip 或者 cargo install uip 即可。编译的二进制大小也进行了优化,只有 1 MB 多点,也没有别的运行时依赖。

    不带参数默认使用 Google 的 STUN 服务器,但是也可以使用国内的服务器,比如:

    $ uip
    203.0.113.1
    
    $ uip stun.qq.com
    203.0.113.1
    
    $ uip stun.miwifi.com
    203.0.113.1
    

    通过返回值是否为 0 可以判断是否成功获得 IP 地址。

    也欢迎大家分享可以使用的公开 STUN 服务器地址,可以在项目 README.md 里提 PR 。

    项目地址: https://github.com/dndx/uip

    第 1 条附言  ·  2023-04-11 10:03:29 +08:00

    更多能用的 STUN 服务器:

    CF:

    $ uip stun.cloudflare.com
    
    $ uip -4 stun.cloudflare.com # IPv4 only
    

    国内 B 站的:

    $ uip stun.chat.bilibili.com
    
    第 2 条附言  ·  2023-04-11 18:30:19 +08:00

    统一回复一下,写这个工具主要是因为我需要国内能稳定长期使用且不限流的 IP 查询服务。别的不说,就 ip.sb 这个因为在 Cloudflare 上,不止一次遇到过 IP 连不上去的情况,稳定性达不到我的需求。

    如果说觉得 curl ip.sb 就可以满足自己要求的,那的确不要再下载一个二进制来做这件事情。

    53 条回复    2023-07-07 03:10:18 +08:00
    Aloento
        1
    Aloento  
       2023-04-11 03:28:25 +08:00 via iPhone
    这个好
    Ricky123
        2
    Ricky123  
       2023-04-11 09:00:52 +08:00
    支持+1, 作者要不要发布到 brew
    patrickyoung
        3
    patrickyoung  
       2023-04-11 09:03:19 +08:00 via iPhone
    molezznet
        4
    molezznet  
       2023-04-11 09:03:52 +08:00
    我把默认的改成 stun.syncthing.net 。 这样内外都能用了
    否则出现 `Error: ErrTransactionTimeOut`
    OutOfMemoryError
        5
    OutOfMemoryError  
       2023-04-11 09:06:16 +08:00
    我用的 4.ipw.cn
    rbe
        6
    rbe  
       2023-04-11 09:10:04 +08:00   ❤️ 1
    curl cip.cc
    8355
        7
    8355  
       2023-04-11 09:18:12 +08:00
    curl ip.gs
    asmoker
        8
    asmoker  
       2023-04-11 09:21:35 +08:00 via Android
    kenvix
        9
    kenvix  
       2023-04-11 09:32:17 +08:00
    可以做到 KB 级吗,路由器上 1MB 还是太紧张了
    NSAgold
        10
    NSAgold  
       2023-04-11 09:39:12 +08:00 via Android
    我用的是 curl 4.ipw.cn 或 curl 6.ipw.cn
    0o0O0o0O0o
        11
    0o0O0o0O0o  
       2023-04-11 09:49:27 +08:00   ❤️ 1
    还有 telnet 方式和 DNS 方式:

    例如
    dig -t txt o-o.myaddr.l.google.com @ns1.google.com +short
    dig myip.opendns.com @resolver1.opendns.com +short
    dig whoami.akamai.net. @ns1-1.akamaitech.net. +short

    telnet telnetmyip.com

    它们协议基础简单,也许真的能达到如 #9 所说的 KB 级?不过不清楚国内大厂有没有这类公益服务器。
    blankmiss
        12
    blankmiss  
       2023-04-11 10:00:43 +08:00
    curl ip.sb
    Routeros
        13
    Routeros  
       2023-04-11 10:34:01 +08:00
    @blankmiss 哈哈哈 我也就能记住这个。
    internelp
        14
    internelp  
       2023-04-11 10:44:50 +08:00   ❤️ 1
    @blankmiss 我也用这个,以前用 ip.cn
    cq65617875
        15
    cq65617875  
       2023-04-11 13:53:08 +08:00
    yinmin
        16
    yinmin  
       2023-04-11 15:34:47 +08:00
    curl -4 ip.gs
    curl -6 ip.gs
    yinmin
        17
    yinmin  
       2023-04-11 15:40:29 +08:00   ❤️ 1
    还有 1 个地址能获取 IP 地址的: https://www.cloudflare.com/cdn-cgi/trace

    给 1 段 python 函数,给需要做 ddns 的参考
    ```
    import re
    import requests
    import socket


    def find_my_ip():
    url = 'https://www.cloudflare.com/cdn-cgi/trace'
    requests.packages.urllib3.util.connection.HAS_IPV6 = False
    match = re.search(
    r'ip=(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', requests.get(url).text)
    if match:
    return match.group(1)
    else:
    return None


    print(find_my_ip())
    ```
    1423
        18
    1423  
       2023-04-11 15:59:13 +08:00   ❤️ 1
    为什么之前没有这种工具
    因为从 stun 获取 IP 是 stun 套件的其中一个示例功能,少有人单独掏出来 show 的

    举例如
    https://github.com/pion/stun/tree/master/cmd/stun-client

    ./stun_client
    1.1.1.1:10101
    1423
        19
    1423  
       2023-04-11 16:08:32 +08:00   ❤️ 2
    telnet netgeartec.ga 8080
    Connected to netgeartec.ga.
    Escape character is '^]'.
    HI
    HELLO 2.9 (2.9.2) 2021-11-30.2159.ffae0e0
    GETIP
    YOURIP 1.1.1.1

    speedtest.net 提供的 8080 端口上的服务器也都支持 GETIP 指令返回 IP
    UnknoownUser
        20
    UnknoownUser  
       2023-04-11 17:17:08 +08:00 via iPhone
    其实获取 ip 的网站一大把
    ipconfig.me
    ipconfig.co
    mikewang
        21
    mikewang  
       2023-04-11 17:38:15 +08:00 via iPhone
    轮子是不错的,不过有更简单的呀
    curl ip.sb
    curl ifconfig.co
    都能直接返回本机 IP 呀🤣
    bagel
        22
    bagel  
       2023-04-11 17:45:04 +08:00
    名字好评,功能不好说,下个二进制专门干这个事感觉稍麻烦。
    EsWann
        23
    EsWann  
       2023-04-11 22:04:43 +08:00
    curl ipip.sh
    crazyweeds
        24
    crazyweeds  
       2023-04-11 22:55:08 +08:00
    curl https://www.hutubox.com/api/ip/info

    特殊之处就是。。是我自己的接口,哈哈。
    qsnow6
        25
    qsnow6  
       2023-04-11 23:50:30 +08:00
    使用 myip.ipip.netip.sb 的人都没有长期使用这些服务,因为长期使用这些服务的人都知道它们不太可靠。我之前在家里运行了一个定时查询公网提交到 DDNS 的脚本,发现这两个服务经常会拒绝服务或者打不开。我猜测这可能是因为请求过多触发了风控。
    我第一次听说这个 STUN 服务,非常感谢!
    顺便也分享我使用的查询 IP 的接口, 非常稳定: http://checkip.amazonaws.com/
    xiangyuecn
        26
    xiangyuecn  
       2023-04-11 23:52:23 +08:00
    今天刚好在找免费 turn 服务,qq 的也挺好用,本地网卡 ip 、外网 ip 统统拿下


    var conn=new RTCPeerConnection({iceServers:[{ urls:["stun:stun.qq.com"] }]})
    conn.onicecandidate=function(e){
    if(e.candidate){
    if(/([\d\.]+) \d+ typ (\w+)/.test(e.candidate.candidate))
    console.log(RegExp.$2+" ip: "+RegExp.$1);
    }else{
    console.log("完成");
    }
    }
    conn.createDataChannel("test")
    var offer=await conn.createOffer()
    conn.setLocalDescription(offer)
    xiangyuecn
        27
    xiangyuecn  
       2023-04-11 23:59:27 +08:00
    STUN 在线测试 https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

    两个域名看起来比较老牌的服务,好像都是德国的:
    stun.sipgate.net
    stun.voipstunt.com
    dndx
        28
    dndx  
    OP
       2023-04-12 00:09:16 +08:00   ❤️ 1
    @qsnow6 没错,我测试 ipip 也经常超时或者跳出来 5 秒盾,总体来说稳定性还是达不到要求。

    国内能提供稳定 IP 查询接口的太少了。找来找去还是大厂的 STUN 服务器最稳定,比如 B 站的就是他们用来做直播 WebRTC P2P 的,甚至还写了优化文章: https://www.bilibili.com/read/cv19672394?from=articleDetail ,必然比各种公益性的服务要靠谱点。
    dndx
        29
    dndx  
    OP
       2023-04-12 00:10:19 +08:00
    @0o0O0o0O0o 公益的就难了,大厂 STUN 本来设计的就不是公益服务,所以可用性要靠谱点...国内的公益服务基本都不持久
    dndx
        30
    dndx  
    OP
       2023-04-12 00:12:21 +08:00
    @qsnow6 实际上 `stun.qq.com` 甚至还做了 GeoDNS 国内分区解析,算是很用心了。可用性不太需要担心,甚至可以顺带作为网络通断的判断。
    qsnow6
        31
    qsnow6  
       2023-04-12 00:34:25 +08:00
    @dndx #30 非常靠谱, 大厂维护的确实要靠谱些, 我会把这个加入到我的脚本中作为备选通道.
    someonedeng
        32
    someonedeng  
       2023-04-12 00:56:01 +08:00
    ip.sb 已经刻进 dna
    crazyweeds
        33
    crazyweeds  
       2023-04-12 01:11:16 +08:00
    @Ricky123 确实发布一下比较方便,虽然我个人网站支持,但确实命令行来得快。
    serafin
        34
    serafin  
       2023-04-12 05:00:42 +08:00
    我发个长亿点点的
    curl -s https://www.cloudflare.com/cdn-cgi/trace | awk -F= '/^ip/{print $2}'
    curl -s https://1.1.1.1/cdn-cgi/trace | awk -F= '/^ip/{print $2}'
    curl -s visa.com/cdn-cgi/trace | awk -F= '/^ip/{print $2}'
    tux
        35
    tux  
       2023-04-12 06:59:42 +08:00
    怎么没有 windows 版?
    swulling
        36
    swulling  
       2023-04-12 08:20:22 +08:00
    Python 的话直接用 aiostun 库就行了。
    v2wtf
        37
    v2wtf  
       2023-04-12 09:16:32 +08:00
    提个意见:主要面向国内的程序,不要默认 G 家服务器。

    这种东西最重要的事情之一是:方便。

    如果默认 G 家服务器,那么每次还得手动输入个国内服务器地址,或者写个 shell 脚本包一道。

    这么麻烦,我为何不直接 curl ip.sb?
    v2wtf
        38
    v2wtf  
       2023-04-12 09:19:40 +08:00
    除上面的意见之外,我觉得 OP 这个思路是对的。

    不需要自己搭建服务器,有大厂稳定性,零依赖的东西用起来真的很爽。
    dndx
        39
    dndx  
    OP
       2023-04-12 13:37:00 +08:00 via iPhone
    @v2wtf 感谢建议。实际上 G 家的 STUN 服务器在国内用起来也没问题,所以这个默认值也不是完全没道理。UDP 3478 比 TCP 443 被阻塞的概率也低多了。
    v2wtf
        40
    v2wtf  
       2023-04-12 15:35:32 +08:00   ❤️ 1
    @dndx 我下载回来第一次运行 uip 就是超时,看了下上面说的换了国内服务器才测试成功,所以才给出你提的建议。
    第一次运行直接就失败,所以默认服务器成功率就不可能高。
    dndx
        41
    dndx  
    OP
       2023-04-12 18:50:39 +08:00
    @v2wtf `uip -4` 试试,可能是你的 IPv6 不通
    qsnow6
        42
    qsnow6  
       2023-04-12 20:11:54 +08:00
    @dndx #41 ipv4 也有一定机率会连不通, 可能是 Google 的服务在墙内被干扰了.
    ```shell
    $ ./uip_x86_64-unknown-linux-musl -4
    Error: ErrTransactionTimeOut
    ```
    dndx
        43
    dndx  
    OP
       2023-04-12 22:18:57 +08:00   ❤️ 1
    @qsnow6 我觉得你说的很有道理,在 ipip 上测了一下,好像 `stun.l.google.com` 在国内一些地方的确是解析不出来(主要是联通)。

    刚发布了一个新版本 `v0.1.5`,在这个版本里默认的服务器已经改为了 `stun.cloudflare.com`,应该会好一些。考虑到国外的用户,不太想用国内的服务器作为默认值,希望理解。
    Ghonewyn
        44
    Ghonewyn  
       2023-04-12 22:41:54 +08:00 via iPhone
    @dndx 同问,这个方案在 windows 上能实现吗?
    kaddusabagei38
        45
    kaddusabagei38  
       2023-04-13 10:52:12 +08:00
    这个思路很棒
    devliu1
        46
    devliu1  
       2023-04-13 11:12:00 +08:00
    Ghonewyn
        47
    Ghonewyn  
       2023-04-13 16:25:51 +08:00   ❤️ 1
    @tux https://github.com/amorphobia/uip 已经有大佬改出来了 windows 下的 target
    dndx
        48
    dndx  
    OP
       2023-04-13 22:22:13 +08:00
    @Ghonewyn
    @tux

    Windows 版已经打出来了 https://github.com/dndx/uip/releases/tag/v0.1.6

    感谢 amorphobia 贡献 https://github.com/dndx/uip/pull/1

    我没有 Windows 系统,希望能有人帮忙测试一下能不能用。
    dorothyREN
        49
    dorothyREN  
       2023-04-16 13:03:49 +08:00
    mohumohu
        50
    mohumohu  
       2023-04-20 16:29:48 +08:00
    OP 的项目不错,是否可以支持 SOCKS5 代理?因为 stun 用来测 socks 的 nat type 挺方便的,最好支持一次性重试多个列表。
    另外公网获取 IP 的也有挺多 URL 可以用的,OP 可以看看这个 DDNS 脚本里面内置了一些获取 IP 的 URL: https://github.com/kkkgo/UE-DDNS
    fox233
        51
    fox233  
       2023-04-28 14:54:21 +08:00
    releases 里面为啥没有 x86_64 的 Linux 文件呢?只有安卓的和 arm 的
    dndx
        52
    dndx  
    OP
       2023-04-28 16:25:07 +08:00 via iPhone
    EsWann
        53
    EsWann  
       2023-07-07 03:10:18 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1003 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 56ms · UTC 21:16 · PVG 05:16 · LAX 13:16 · JFK 16:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.