uip - 获取公网 IP 的小程序 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
dndx
V2EX    分享创造

uip - 获取公网 IP 的小程序

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

    用 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`
    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())
    ```
    slowman
        18
    slowman      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
    slowman
        19
    slowman  
       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`,应该会好一些。考虑到国外的用户,不太想用国内的服务器作为默认值,希望理解。
    AokiHina
        44
    AokiHina  
       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
    AokiHina
        47
    AokiHina  
       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     Solana     2812 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 06:31 PVG 14:31 LAX 23:31 JFK 02:31
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86