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

uip - 获取公网 IP 的小程序

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

    用 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 条附言  ·  169 天前

    更多能用的 STUN 服务器:

    CF:

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

    国内 B 站的:

    $ uip stun.chat.bilibili.com
    
    第 2 条附言  ·  168 天前

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

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

    53 条回复    2023-07-07 03:10:18 +08:00
    Aloento
        1
    Aloento  
       169 天前 via iPhone
    这个好
    Ricky123
        2
    Ricky123  
       169 天前
    支持+1, 作者要不要发布到 brew
    patrickyoung
        3
    patrickyoung  
       169 天前 via iPhone
    molezznet
        4
    molezznet  
       169 天前
    我把默认的改成 stun.syncthing.net 。 这样内外都能用了
    否则出现 `Error: ErrTransactionTimeOut`
    OutOfMemoryError
        5
    OutOfMemoryError  
       169 天前
    我用的 4.ipw.cn
    rbe
        6
    rbe  
       169 天前   ❤️ 1
    curl cip.cc
    8355
        7
    8355  
       169 天前
    curl ip.gs
    asmoker
        8
    asmoker  
       169 天前 via Android
    kenvix
        9
    kenvix  
       169 天前
    可以做到 KB 级吗,路由器上 1MB 还是太紧张了
    NSAgold
        10
    NSAgold  
       169 天前 via Android
    我用的是 curl 4.ipw.cn 或 curl 6.ipw.cn
    0o0O0o0O0o
        11
    0o0O0o0O0o  
       169 天前   ❤️ 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  
       169 天前
    curl ip.sb
    Routeros
        13
    Routeros  
       169 天前
    @blankmiss 哈哈哈 我也就能记住这个。
    internelp
        14
    internelp  
       169 天前   ❤️ 1
    @blankmiss 我也用这个,以前用 ip.cn
    cq65617875
        15
    cq65617875  
       169 天前
    yinmin
        16
    yinmin  
       169 天前
    curl -4 ip.gs
    curl -6 ip.gs
    yinmin
        17
    yinmin  
       169 天前   ❤️ 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  
       169 天前   ❤️ 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  
       169 天前   ❤️ 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  
       169 天前 via iPhone
    其实获取 ip 的网站一大把
    ipconfig.me
    ipconfig.co
    mikewang
        21
    mikewang  
       169 天前 via iPhone
    轮子是不错的,不过有更简单的呀
    curl ip.sb
    curl ifconfig.co
    都能直接返回本机 IP 呀🤣
    bagel
        22
    bagel  
       169 天前
    名字好评,功能不好说,下个二进制专门干这个事感觉稍麻烦。
    EsWann
        23
    EsWann  
       168 天前
    curl ipip.sh
    crazyweeds
        24
    crazyweeds  
       168 天前
    curl https://www.hutubox.com/api/ip/info

    特殊之处就是。。是我自己的接口,哈哈。
    qsnow6
        25
    qsnow6  
       168 天前
    使用 myip.ipip.netip.sb 的人都没有长期使用这些服务,因为长期使用这些服务的人都知道它们不太可靠。我之前在家里运行了一个定时查询公网提交到 DDNS 的脚本,发现这两个服务经常会拒绝服务或者打不开。我猜测这可能是因为请求过多触发了风控。
    我第一次听说这个 STUN 服务,非常感谢!
    顺便也分享我使用的查询 IP 的接口, 非常稳定: http://checkip.amazonaws.com/
    xiangyuecn
        26
    xiangyuecn  
       168 天前
    今天刚好在找免费 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  
       168 天前
    STUN 在线测试 https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

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

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

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

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

    这么麻烦,我为何不直接 curl ip.sb?
    v2wtf
        38
    v2wtf  
       168 天前
    除上面的意见之外,我觉得 OP 这个思路是对的。

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

    刚发布了一个新版本 `v0.1.5`,在这个版本里默认的服务器已经改为了 `stun.cloudflare.com`,应该会好一些。考虑到国外的用户,不太想用国内的服务器作为默认值,希望理解。
    Ghonewyn
        44
    Ghonewyn  
       167 天前 via iPhone
    @dndx 同问,这个方案在 windows 上能实现吗?
    kaddusabagei38
        45
    kaddusabagei38  
       167 天前
    这个思路很棒
    devliu1
        46
    devliu1  
       167 天前
    Ghonewyn
        47
    Ghonewyn  
       167 天前   ❤️ 1
    @tux https://github.com/amorphobia/uip 已经有大佬改出来了 windows 下的 target
    dndx
        48
    dndx  
    OP
       166 天前
    @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  
       164 天前
    mohumohu
        50
    mohumohu  
       160 天前
    OP 的项目不错,是否可以支持 SOCKS5 代理?因为 stun 用来测 socks 的 nat type 挺方便的,最好支持一次性重试多个列表。
    另外公网获取 IP 的也有挺多 URL 可以用的,OP 可以看看这个 DDNS 脚本里面内置了一些获取 IP 的 URL: https://github.com/kkkgo/UE-DDNS
    fox233
        51
    fox233  
       152 天前
    releases 里面为啥没有 x86_64 的 Linux 文件呢?只有安卓的和 arm 的
    dndx
        52
    dndx  
    OP
       152 天前 via iPhone
    EsWann
        53
    EsWann  
       82 天前
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   4752 人在线   最高记录 6067   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 50ms · UTC 09:52 · PVG 17:52 · LAX 02:52 · JFK 05:52
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.