是否有可能 Zerotier-One 直接在 Android 设备上运行? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
gam2046
V2EX    Android

是否有可能 Zerotier-One 直接在 Android 设备上运行?

  •  
  •   gam2046 2022-06-30 10:43:02 +08:00 14889 次点击
    这是一个创建于 1254 天前的主题,其中的信息可能已经有所发展或是发生改变。

    准备

    • 获取Zerotier-One代码,并 checkout 到 1.8.9 。
    • 配置 arm 交叉编译环境并采用静态编译
      • 这里并未采用 NDK 主要是因为一直不成功
      • 所以才使用静态编译的方法,应用直接通到 syscall
    • 将编译后的程序丢到 Android 设备上,通过 root 用户运行( Android 10)
    • zerotier-cli join <ID>,加入网络
    • zerotier 可以正常打开 /dev/tun ,并且正常创建了虚拟网卡,且正确配置 IP 与路由
      • 通过ip adip route可正确显示相关信息
    • zerotier 运行无输出

    问题

    虽然看起来组网成功,并且 zerotier controller 也显示设备已连接,并正确显示版本等信息,但实际上网络访问并不通。

    通过分析(实际就是加输出日志),确认 zerotier正常进入此循环,同时也未发现 zerotier 对系统有其他额外要求,只需要存在 tun 设备即可。


    猜测

    那目前看起来比较有可能的原因,是 Android 中对 tun 的行为有所不同。常规 Android 开发中,只有 VpnService 会经由一系列检查以及用户授权后,打开 tun 设备,变更路由表,并将句柄返回给应用层。

    由此猜测可能是 Android 对 tun 有一些魔改,但是我翻阅了一下(更多的可能是水平不够),AOSP 里没看到一些可疑的操作。

    所以请问一下大佬,在有 root 的情况下,有没有可能直接在 Android 设备上使用 zerotier ,而不需要装个 APP 呢?( APP 有些设置在 UI 中也没有)

    28 条回复    2023-11-18 23:30:22 +08:00
    gam2046
        1
    gam2046  
    OP
       2022-06-30 11:16:17 +08:00
    通过 AOSP 中一些代码的对比,并未看到 AOSP 中有什么不一样的操作。几乎与 zerotier 的代码一致。

    https://cs.android.com/android/platform/superproject/+/master:frameworks/base/services/core/jni/com_android_server_connectivity_Vpn.cpp;l=59;drc=912b26d95c411a41126393b7d341a18f04981342

    看了下,设备中的 /dev/tun 所有者是 system:vpn ,我使用 root 去 open 原则上也是没有问题的。对 /dev/tun 的读写就直接进内核了,原与 Android 中的上层应用都无关(就是 framework 那一大堆)。

    唯一的区别是,AOSP 将设备初始化为 IFF_TUN ,而 zerotier 中设置为 IFF_TAP 。但既然 ioctl 没返回失败,就应该是没问题。

    实在找不出原因了,大佬们救救孩子吧。
    neptuno
        2
    neptuno  
       2022-06-30 11:42:20 +08:00
    超纲了,,想问一下,你这样做,好处是什么呢? zerotier 不是有安卓客户端吗
    yaott2020
        3
    yaott2020  
       2022-06-30 12:31:27 +08:00 via Android
    @neptuno 可能是因为官方安卓客户端不支持 moon 。第三方客户端支持( zerotierfix )
    gam2046
        4
    gam2046  
    OP
       2022-06-30 13:11:37 +08:00
    @neptuno @yaott2020 #2 #3 一些个性化配置是一方面,另一方是具体使用设备上,并不是手机,而是定制设备,因此需要能够实现 CLI 。

    至于 zerotierfix ,也有关注到,其依旧通过 VpnService 实现,因此要转换成 CLI 工具比较困难,app_process 并不能提供较为完整的 Android 上下文环境,但依旧可以作为备选方案,毕竟各种 context 与 service 都是代理对象。

    ---
    再补充一些信息,通过打开调试信息后,可以得到一些 zerotier 的日志

    ```
    requesting configuration for network <NETWORK_ID>
    learned new path 47.254.39.171/9993 to 451e1bcd2d (packet 83c94f7455245fc1 local socket 24751240 network 0000000000000000)
    learned new path 47.254.39.171/9993 to 451e1bcd2d (packet 27f78687dc532c4c local socket 24752072 network 0000000000000000)
    learned new path 47.254.39.171/9993 to 451e1bcd2d (packet 3aace22563cf24c1 local socket 24761048 network 0000000000000000)
    learned new path 84.17.53.155/9993 to cafe04eba9 (packet 6206803e3b771efa local socket 24751240 network 0000000000000000)
    learned new path 50.7.252.138/9993 to 62f865ae71 (packet 62067fb9b5119d9a local socket 24752072 network 0000000000000000)
    learned new path 104.194.8.134/9993 to cafe9efeb9 (packet 62965da8502523c5 local socket 24751240 network 0000000000000000)
    trying unknown path 104.194.8.134/9993 to cafe9efeb9 (packet 62965da85025b36f verb 5 local socket 24761048 network 0000000000000000)
    requesting configuration for network <NETWORK_ID>
    learned new path 103.195.103.66/9993 to 778cde7190 (packet 624f26cab7985461 local socket 24761048 network 0000000000000000)
    trying unknown path 122.233.117.194/30356 to f4b7f79a0a (packet 5fd54282b47ffaab verb 8 local socket 24761048 network 0000000000000000)
    trying unknown path 122.233.117.194/30356 to f4b7f79a0a (packet 9350ccb5c20f1429 verb 8 local socket 24751240 network 0000000000000000)
    trying unknown path 122.233.117.194/30356 to f4b7f79a0a (packet b7cb5f1fc6e0c571 verb 8 local socket 24752072 network 0000000000000000)
    learned new path 84.17.53.155/9993 to cafe04eba9 (packet 6206803e3bb32355 local socket 24752072 network 0000000000000000)
    trying unknown path 104.194.8.134/9993 to cafe9efeb9 (packet 62965da85094d197 verb 5 local socket 24761048 network 0000000000000000)
    trying unknown path 104.194.8.134/9993 to cafe9efeb9 (packet 62965da850bbe285 verb 5 local socket 24761048 network 0000000000000000)
    trying unknown path 122.233.117.194/30356 to f4b7f79a0a (packet 2592f42b345e677b verb 8 local socket 24761048 network 0000000000000000)
    trying unknown path 122.233.117.194/30356 to f4b7f79a0a (packet c3430f29f87d3b50 verb 8 local socket 24751240 network 0000000000000000)
    ```

    有考虑过,是否为网络原因导致实际访问路径不通,但是在相同网络环境下,一台 Windows 主机可以快速的接入网络并访问,因此无法怀疑是网络问题。

    同时附上编译参数:
    make \
    ZT_STATIC=1 \
    ZT_DEBUG=1 \
    CC=arm-none-linux-gnueabihf-gcc \
    CXX=arm-none-linux-gnueabihf-g++ \
    CFLAGS="-Wall -O3" \
    CXXFLAGS="-Wall -O3" \
    LDFLAGS="-s" \
    $*
    ZiShuo
        5
    ZiShuo  
       2022-06-30 13:47:13 +08:00
    关注一下,前几个月也有楼主这个需求,自己倒腾了好久也没搞成。当然我纯小白,连交叉编译怎么搞都不会的那种,最后在安卓下面安装了个 optware 变相实现了这个需求。

    PS:很想楼主写个搭建 Arm 交叉编译的教程,然后一起折腾。
    gam2046
        6
    gam2046  
    OP
       2022-06-30 15:20:54 +08:00
    @ZiShuo #5 简单的编译环境并不困难,特别是借助 docker 以后。如果想玩,这里给你一个 arm 的参考样例,可以新建一个 dockerfile ,写入以下内容

    https://gist.github.com/Lua12138/940ba02c809a1f28416e10b0cfc9cfa9

    然后 docker build -t builder:arm . 构建镜像即可。编译的时候,参考命令:

    docker run --rm -it \
    -v $PWD/ZeroTierOne/:/code \ # <- 挂载进去代码,根据你的实际位置修改
    -w /code \
    builder:arm \
    make \ # <- 这里就是写各种编译参数了
    ZT_STATIC=1 \
    ZT_DEBUG=1 \
    CC=arm-none-linux-gnueabihf-gcc \
    CXX=arm-none-linux-gnueabihf-g++ \
    LDFLAGS="-s" \
    datocp
        7
    datocp  
       2022-07-01 05:17:40 +08:00 via Android
    神器可试试 gscript lite 或者 juicessh 。
    如果你对这软件从设置到路由都非常熟悉的话,其它可能就是被 iptables 挡了。android 10/12 用 android 该除的都除了,至少用的一个 sslsocks,stunnel 的 gui 实现正常 。

    iptables -F
    iptables -X
    iptables -t nat -F
    iptables -t nat -X
    #iptables -t mangle -F
    #iptables -t mangle -X
    iptables -t raw -F
    iptables -t raw -X
    iptables -t security -F
    iptables -t security -X
    # Apply and allow now your rules from here ...
    iptables -P INPUT ACCEPT
    iptables -P FORWARD ACCEPT
    iptables -P OUTPUT ACCEPT
    iptables -F fw_dozable
    iptables -X fw_dozable
    ZiShuo
        8
    ZiShuo  
       2022-07-01 09:34:32 +08:00
    @gam2046 感谢大佬,我现在就去搭建环境再倒腾下,我是想把 zerotier 扔到 4G 随身 wifi 里面使用。
    gam2046
        9
    gam2046  
    OP
       2022-07-01 10:11:58 +08:00
    @datocp #7 唔,还不一样。sslsocks 、stunnel 都是 7 层协议。而 zerotier 使用 tun/tap ,它需要的是二层。经过一些排查基本确定就是少了一步类似 VpnService.protect 的步骤。


    @ZiShuo #8 如果系统也是 Android 的话,还是优先考虑 zerotier one 自己的客户端吧。如果是 openwrt 或者其他 Linux 设备,可以直接用我编译好的程序(如果也是 arm 架构,其他架构官网上也有下载不用你自己编译)。
    ZiShuo
        10
    ZiShuo  
       2022-07-01 12:36:06 +08:00
    @gam2046 谢谢,主要是我要替换 zerotier 里面的根,换成自己的根,默认的根在境外我这有时候连不上,系统是安卓,处理器是骁龙 410 的,貌似是 Arm64 架构的,淘宝 20 多买的那种 4G 随身 wifi
    sbilly
        11
    sbilly  
       2022-07-03 22:38:24 +08:00
    @ZiShuo 你的随身 4G 是 Android 系统?
    ZiShuo
        12
    ZiShuo  
       2022-07-13 14:56:57 +08:00
    @sbilly 是的
    jeesk
        13
    jeesk  
       2022-12-21 22:57:19 +08:00
    zerotierfix 在 github 上面有入轨的版本。
    huazhaozhe
        14
    huazhaozhe  
       2023-04-14 01:39:12 +08:00
    楼主有什么解决方法了没,我在 Android 上通过 chroot 部署了 ubuntu22 arm64 ,然后在里边用官方的方法安装了 zerotier-one ,加入网络 OK ,也有虚拟网卡,一开始成功了,后边配了新的网络又不行了,感觉也是和 tun 以及 Android 网络这方面有关,不是特别懂就懵了
    huazhaozhe
        15
    huazhaozhe  
       2023-04-14 01:42:19 +08:00
    另外有个方法是内核支持 docker 的话,直接装个 docker 把 tun 挂进去就行了,手机内核需要重新编译可能不一定能支持 docker
    gam2046
        16
    gam2046  
    OP
       2023-04-14 10:13:40 +08:00
    @huazhaozhe #14 即使把 docker 移植到 Android 上也不是一件容易的事情。要移植许多工具链,肉眼可见的坑就是 libc 的差异以及 iptables
    huazhaozhe
        17
    huazhaozhe  
       2023-04-15 09:00:11 +08:00
    @gam2046 #16 这个倒是有的,我在 k40 上就是用的 docker 跑 zerotier-one ,编译内核开启几个选项就可以了
    gam2046
        19
    gam2046  
    OP
       2023-04-15 09:38:09 +08:00
    @huazhaozhe #16 这可不是一个玩意,你这个依托于 Termux ,并不能独立部署。我以前尝试过,把这类工具从 Termux 里摘出来,合并到 Android 主线上。

    但是没成功,需要我魔改的地方太多了。

    如果你用这个是可以用的话,那么应该问题不在 tun/tap 上,Termux 本身并没有魔法。

    那么我之前的问题可能是出在了本地路由表上,等我有空了,再回去看看。
    gam2046
        20
    gam2046  
    OP
       2023-10-27 14:17:23 +08:00
    @ZiShuo
    @datocp
    @huazhaozhe

    目前该问题已经解决,与 Zerotier 并无太大关系,经过大佬指点,主要问题出在 Android 使用 RPDB ( routing policy database )来决定应用程序的 IP 数据包路由,它不依赖于传统的主路由表(也就是 main ,table id 254 ),有自己的路由策略。

    因此解决方案也非常简单,只需要根据自己的实际情况,修改 RPDB 即可。
    newuser666
        21
    newuser666  
       2023-11-01 13:47:09 +08:00
    @gam2046 大佬大佬,可以给点 RPDB 样例吗,我在 github 上看你的回答说修改了一些代码,方便教一下怎么做到吗
    gam2046
        22
    gam2046  
    OP
       2023-11-01 19:29:28 +08:00
    @newuser666 #20 ,大概的意思就是这样,归根到底,其实就是因为没有走主路由表。

    https://gist.github.com/Lua12138/77252e88857f34432e297bfcde7adc74
    newuser666
        23
    newuser666  
       2023-11-01 22:28:29 +08:00
    @gam2046 打扰了大佬,小白一个,看不懂 C 代码,我表达的不清楚,我看了 git 上的回复,我需要的是这个命令的正确用法 `ip route add table $your_selected_table_id $cide/$prefix dev $zt_iface_name proto kernel scope link`,我看了那位大佬给的文档和你写的回复,但是还是不太清楚应该怎么写。我试着替换了命令中的变量为自己的网段、掩码和接口名,your_selected_table_id 写了个 252 ,但是并没有用处,希望大佬能给个正确的样例。
    另外不知道什么原因我用你的 dockerfile 编译了一个 1.12.1 版本,可以执行`zerotier-one -d $homepath` 但是无法执行 `zerotier-one -q $homepath`,也就是 cli 命令执行报错`./zerotier-cli: missing port and zerotier-one.port not found in /var/lib/zerotier-one`,读取的 home 路径并不是我指定的路径,只能通过 http 请求的形式加入网络,这个是我编译的代码问题吗。
    newuser666
        24
    newuser666  
       2023-11-06 17:53:51 +08:00
    #23 cli 报错从提案中找到了答案,有个隐藏选项文档没写,需要加上 `-Dhomepath`也就是`zerotier-one -q -D$homepath`,但是默认路由依然没生效
    gam2046
        25
    gam2046  
    OP
       2023-11-06 20:54:24 +08:00
    @newuser666 #22 原则上是关系不大的,只要不是 254 理论上都可以,试试看 table id 255 ,或者从 1 开始试试。

    作为 cli 使用如果你不使用软连接的话,根据 ZT 的代码( https://github.com/zerotier/ZeroTierOne/blob/1bd2fecbf6a0419740b33ce95ff6ec4ce33ebd88/one.cpp#L132 ),你需要这样手动指定工作目录,例如:

    ./zerotier-one -D$homepath -q info

    当然你也可以在编译时,直接修改其默认的工作目录

    https://github.com/zerotier/ZeroTierOne/blob/1bd2fecbf6a0419740b33ce95ff6ec4ce33ebd88/osdep/OSUtils.cpp#L447
    newuser666
        26
    newuser666  
       2023-11-08 16:37:50 +08:00
    @gam2046 #25 感谢大佬的回复,您给的方案有效,这几天逛 github 的时候发现个简单粗暴的方法,`ip rule add from all lookup main pref 1`,使用后连自定义路由都不需要添加了,不过暂时还不清楚提升 main 表优先级有没有弊端。
    ynkcc
        27
    ynkcc  
       2023-11-18 19:59:18 +08:00 via Android
    安装楼主的方法,成功在部署了 zerotier 。结果有几台设备连不上默认的根节点。不打算折腾 moon 节点和自建 planet 。准备去试一下 tailscale 能不能编译在 Android 使用
    ynkcc
        28
    ynkcc  
       2023-11-18 23:30:22 +08:00 via Android
    算了,还是自建 planet 吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     900 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 22ms UTC 19:41 PVG 03:41 LAX 11:41 JFK 14:41
    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