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

2022-06-30 10:43:02 +08:00
 gam2046

准备


问题

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

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


猜测

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

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

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

10615 次点击
所在节点    Android
28 条回复
gam2046
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
2022-06-30 11:42:20 +08:00
超纲了,,想问一下,你这样做,好处是什么呢? zerotier 不是有安卓客户端吗
yaott2020
2022-06-30 12:31:27 +08:00
@neptuno 可能是因为官方安卓客户端不支持 moon 。第三方客户端支持( zerotierfix )
gam2046
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
2022-06-30 13:47:13 +08:00
关注一下,前几个月也有楼主这个需求,自己倒腾了好久也没搞成。当然我纯小白,连交叉编译怎么搞都不会的那种,最后在安卓下面安装了个 optware 变相实现了这个需求。

PS:很想楼主写个搭建 Arm 交叉编译的教程,然后一起折腾。
gam2046
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
2022-07-01 05:17:40 +08:00
神器可试试 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
2022-07-01 09:34:32 +08:00
@gam2046 感谢大佬,我现在就去搭建环境再倒腾下,我是想把 zerotier 扔到 4G 随身 wifi 里面使用。
gam2046
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
2022-07-01 12:36:06 +08:00
@gam2046 谢谢,主要是我要替换 zerotier 里面的根,换成自己的根,默认的根在境外我这有时候连不上,系统是安卓,处理器是骁龙 410 的,貌似是 Arm64 架构的,淘宝 20 多买的那种 4G 随身 wifi
sbilly
2022-07-03 22:38:24 +08:00
@ZiShuo 你的随身 4G 是 Android 系统?
ZiShuo
2022-07-13 14:56:57 +08:00
@sbilly 是的
jeesk
2022-12-21 22:57:19 +08:00
zerotierfix 在 github 上面有入轨的版本。
huazhaozhe
2023-04-14 01:39:12 +08:00
楼主有什么解决方法了没,我在 Android 上通过 chroot 部署了 ubuntu22 arm64 ,然后在里边用官方的方法安装了 zerotier-one ,加入网络 OK ,也有虚拟网卡,一开始成功了,后边配了新的网络又不行了,感觉也是和 tun 以及 Android 网络这方面有关,不是特别懂就懵了😂
huazhaozhe
2023-04-14 01:42:19 +08:00
另外有个方法是内核支持 docker 的话,直接装个 docker 把 tun 挂进去就行了,手机内核需要重新编译可能不一定能支持 docker
gam2046
2023-04-14 10:13:40 +08:00
@huazhaozhe #14 即使把 docker 移植到 Android 上也不是一件容易的事情。要移植许多工具链,肉眼可见的坑就是 libc 的差异以及 iptables
huazhaozhe
2023-04-15 09:00:11 +08:00
@gam2046 #16 这个倒是有的,我在 k40 上就是用的 docker 跑 zerotier-one ,编译内核开启几个选项就可以了
huazhaozhe
2023-04-15 09:04:07 +08:00
gam2046
2023-04-15 09:38:09 +08:00
@huazhaozhe #16 这可不是一个玩意,你这个依托于 Termux ,并不能独立部署。我以前尝试过,把这类工具从 Termux 里摘出来,合并到 Android 主线上。

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

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

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

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

因此解决方案也非常简单,只需要根据自己的实际情况,修改 RPDB 即可。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/863131

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX