update zerotier module to support rootless app

This commit is contained in:
eventlOwOp
2024-07-02 12:25:20 +08:00
parent 7394eee0f0
commit fa2d60e1b8
11 changed files with 271 additions and 104 deletions
+7 -1
View File
@@ -14,6 +14,8 @@
**Use Android App to control ZeroTier**
**Support for Private Root Servers**
## Requirements
1. a version is built with Android NDK Toolchain, supporting api 28 (Android 9.0) and above.
@@ -34,9 +36,13 @@ AArch64 suppots ARMv8-A and above; Arm version supports ARMv7-A (compiling with
## Usage
### Use Private Root Servers
Replace `/data/adb/zerotier/home/planet` with your own `planet` file.
### Controller App
Needs root privilege
Does not need root privilege
| Feature | Supported? |
| :----------------- | :--------- |
+7 -1
View File
@@ -14,6 +14,8 @@
**使用 Android App 进行控制**
**支持自建 Planet**
## 运行要求
1. 使用 NDK 编译的版本,支持 api 28 (Android 9.0) 及以上的设备
@@ -34,9 +36,13 @@ AArch64 版本支持 ARMv8-A 及以上;Arm 版本均对 ARMv7-A 进行编译 (
## 使用
### 自建 Planet
`/data/adb/zerotier/home/planet` 替换为自己的 planet 文件即可
### 控制器 App
root 授权
需 root 授权
| 功能 | 支持状态 |
| :--------------- | :------- |
+6 -3
View File
@@ -1,5 +1,6 @@
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
class AuthedClientInner extends http.BaseClient {
final String _secret;
@@ -25,9 +26,11 @@ class AuthedClientInner extends http.BaseClient {
class AuthedClient {
late Future<AuthedClientInner> client;
Future<AuthedClientInner> loadSecret() async {
final results = await Process.run(
'su', ['-c', 'cat', '/data/adb/zerotier/home/authtoken.secret']);
return AuthedClientInner(results.stdout.toString().trim(), http.Client());
final path = (await getApplicationDocumentsDirectory()).path;
final file = File('$path/authtoken');
final token = await file.readAsString();
return AuthedClientInner(token.trim(), http.Client());
}
AuthedClient() {
+5 -6
View File
@@ -40,9 +40,8 @@ class MyHomePage extends StatefulWidget {
State<MyHomePage> createState() => _MyHomePageState();
}
Future zerotierCommand(String exe, String command) {
return Process.run('su', ['-c', '/data/adb/zerotier/$exe', command],
environment: {'LD_LIBRARY_PATH': '/system/lib64:/data/adb/zerotier/lib'});
Future zerotierCommand(String command) {
return Process.run('echo', [command, '>/data/data/com.eventlowop.zerotier_magisk_app/files/pipe']);
}
class _MyHomePageState extends State<MyHomePage> {
@@ -125,9 +124,9 @@ class _MyHomePageState extends State<MyHomePage> {
_MyHomePageState() : super() {
restartFn =
cmdButtonWrapper(() => zerotierCommand('zerotier.sh', 'restart'));
startFn = cmdButtonWrapper(() => zerotierCommand('zerotier.sh', 'start'));
stopFn = cmdButtonWrapper(() => zerotierCommand('zerotier.sh', 'stop'));
cmdButtonWrapper(() => zerotierCommand('restart'));
startFn = cmdButtonWrapper(() => zerotierCommand('start'));
stopFn = cmdButtonWrapper(() => zerotierCommand('stop'));
joinFn = cmdButtonWrapper(() => joinNetwork(_idInputController.text));
}
+89 -1
View File
@@ -97,6 +97,14 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.1.2"
flutter:
dependency: "direct main"
description: flutter
@@ -227,6 +235,54 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "1.9.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.1.3"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.2.4"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.4.0"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.2.1"
petitparser:
dependency: transitive
description:
@@ -235,6 +291,22 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "6.0.2"
platform:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "2.1.8"
sky_engine:
dependency: transitive
description: flutter
@@ -320,6 +392,22 @@ packages:
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "0.5.1"
win32:
dependency: transitive
description:
name: win32
sha256: "0eaf06e3446824099858367950a813472af675116bf63f008a4c2a75ae13e9cb"
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "5.5.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/"
source: hosted
version: "1.0.4"
xml:
dependency: transitive
description:
@@ -338,4 +426,4 @@ packages:
version: "3.1.2"
sdks:
dart: ">=3.3.4 <4.0.0"
flutter: ">=1.17.0"
flutter: ">=3.16.6"
+1
View File
@@ -36,6 +36,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6
http: ^1.2.1
path_provider: ^2.1.3
dev_dependencies:
flutter_test:
+1
View File
@@ -25,6 +25,7 @@ ln -sf $ZTPATH/zerotier-idtool $MODPATH$SYSBIN/zerotier-idtool
ui_print "- set file permission"
set_perm_recursive $MODPATH 0 0 0755 0644
set_perm_recursive $ZTPATH 0 0 0755 0644
set_perm $MODPATH/handle.sh 0 0 0755
set_perm $ZTPATH/zerotier.sh 0 0 0755
set_perm $ZTPATH/zerotier-one 0 0 0755
+83
View File
@@ -0,0 +1,83 @@
#!/system/bin/sh
MODDIR=${0%/*}
# load variables
. $MODDIR/vars.sh
# LD_LIBRARY_PATH for NDK
export LD_LIBRARY_PATH=/system/lib64:/data/adb/zerotier/lib
log_cli() {
echo -e "$1" >> $ZTROOT/run/cli.out
}
log() {
t=`date +"%m-%d %H:%M:%S.%3N"`
echo -e "[$t][$$][L] $@" >> $DAEMON_LOG
log_cli "$@"
}
_stop() {
pid=`pidof zerotier-one`
if [[ $? -ne 0 ]]; then
log "zerotier-one not running"
return
fi
kill -9 $pid
if [[ $? -ne 0 ]]; then
log "kill zerotier-one failed"
return
fi
wait
sleep 1 # sometimes it fails without sleeping
log "stopped zerotier-one"
}
_start() {
if pid=`pidof zerotier-one`; then
log "zerotier-one already running pid $pid"
else
$ZTROOT/zerotier-one -d >> $ZT_LOG 2>&1 &
pid=`pidof zerotier-one`
log "started zerotier-one pid $pid"
fi
}
_status() {
# fake systemd lol
if pid=`pidof zerotier-one`; then
log_cli "\033[32m●\033[0m zerotier-one.service - ZeroTier One - Global Area Networking"
log_cli " Active: \033[32mactive (running)\033[0m"
log_cli " Main PID: $pid (zerotier-one)"
else
read pid_ < $ZTROOT/home/zerotier-one.pid
log_cli "○ zerotier-one.service - ZeroTier One - Global Area Networking"
log_cli " Active: inactive (dead)"
log_cli " Main PID: $pid_ (code=exited)"
fi
}
# ----------------------------------------------
# call from inotifyd
# ----------------------------------------------
if [[ $# == 2 && "$1" == "w" ]]; then
read cmd < $2
rm -f $ZTROOT/run/cli.out
case "$cmd" in
"start") _start;;
"stop") _stop;;
"restart") _stop; _start;;
"status") _status;;
*) log "unknown command $cmd";;
esac
if [[ -f "$ZTROOT/run/cli.pid" ]]; then
read cpid < $ZTROOT/run/cli.pid
rm -f $ZTROOT/run/cli.pid
kill -SIGUSR1 $cpid
fi
exit 0
fi
+54 -84
View File
@@ -2,96 +2,66 @@
MODDIR=${0%/*}
ZTROOT=/data/adb/zerotier
ZTRUNTIME=$ZTROOT/run
APPROOT=/data/data/com.eventlowop.zerotier_magisk_app/files
# load variables
. $MODDIR/vars.sh
pipe=$ZTRUNTIME/pipe
ZTLOG=$ZTRUNTIME/zerotier.log
daemon_log=$ZTRUNTIME/daemon.log
# wait_until_login from yc9559/uperf at uperf/magisk/script/libcommon.sh
wait_until_login() {
# in case of /data encryption is disabled
while [ "$(getprop sys.boot_completed)" != "1" ]; do
sleep 1
done
cli_output=$ZTRUNTIME/cli.out
cli_pid=$ZTRUNTIME/cli.pid
log() {
t=`date +"%m-%d %H:%M:%S.%3N"`
echo -e "[$t][$$][L] $1" >> $daemon_log
echo -e "$1" >> $cli_output
}
log_cli() {
echo -e "$1" >> $cli_output
}
_stop() {
pid=`pidof zerotier-one`
if [[ $? -ne 0 ]]; then
log "zerotier-one not running"
return
fi
kill -9 $pid
if [[ $? -ne 0 ]]; then
log "kill zerotier-one failed"
return
fi
wait
log "stopped zerotier-one"
}
__start() {
$ZTROOT/zerotier-one -d >> $ZTLOG 2>&1 &
}
_start() {
if pid=`pidof zerotier-one`; then
log "zerotier-one already running pid $pid"
else
__start
pid=`pidof zerotier-one`
log "started zerotier-one pid $pid"
fi
}
_status() {
# fake systemd lol
if pid=`pidof zerotier-one`; then
log_cli "\033[32m●\033[0m zerotier-one.service - ZeroTier One - Global Area Networking"
log_cli " Active: \033[32mactive (running)\033[0m"
log_cli " Main PID: $pid (zerotier-one)"
else
pid_=`cat $zerotier_root/home/zerotier-one.pid`
log_cli "○ zerotier-one.service - ZeroTier One - Global Area Networking"
log_cli " Active: inactive (dead)"
log_cli " Main PID: $pid_ (code=exited)"
fi
# we doesn't have the permission to rw "/sdcard" before the user unlocks the screen
local test_file="/sdcard/Android/.PERMISSION_TEST"
true >"$test_file"
while [ ! -f "$test_file" ]; do
true >"$test_file"
sleep 1
done
rm "$test_file"
}
cd $ZTROOT
rm -f $ZTRUNTIME
mkfifo $pipe
# ----------------------------------------------
# clean before start
# ----------------------------------------------
chmod 666 $pipe $cli_output $cli_pid
rm -rf $ZTROOT/run
mkdir -p $ZTROOT/run
# ----------------------------------------------
# start zerotier
# ----------------------------------------------
# add main route table to lookup rules
ip rule add from all lookup main pref 1
export LD_LIBRARY_PATH=/system/lib64:/data/adb/zerotier/lib
ip -6 rule add from all lookup main pref 1
if [[ -e /data/data/com.eventlowop.zerotier_magisk_app/files ]]; then
ln -sf $pipe $APPROOT/pipe
ln -sf $cli_output $APPROOT/cli.out
ln -sf $cli_pid $APPROOT/cli.pid
# LD_LIBRARY_PATH for NDK
export LD_LIBRARY_PATH=$ZTROOT/lib
# start zerotier
$ZTROOT/zerotier-one -d >> $ZT_LOG 2>&1 &
# ----------------------------------------------
# CLI before login
# ----------------------------------------------
touch $PIPE_CLI
inotifyd $MODDIR/handle.sh $PIPE_CLI:w &>/dev/null & # toybox inotifyd bug: needs an extra character after colon
# ----------------------------------------------
# APP after login
# ----------------------------------------------
wait_until_login
if [[ -d "$APPROOT" ]]; then
rm -rf $APPROOT/run
mkdir -p $APPROOT/run
cp $ZTROOT/home/authtoken.secret $APPROOT/run/authtoken
touch $PIPE_APP
chmod 666 $APPROOT/run/authtoken $PIPE_APP
inotifyd $MODDIR/handle.sh $PIPE_APP:w &>/dev/null &
fi
__start
while true
do
if read cmd < $pipe; then
case "$cmd" in
"start") _start;;
"stop") _stop;;
"restart") _stop; _start;;
"status") _status;;
*) log "unknown command $cmd";;
esac
cpid=`cat $cli_pid`
kill -SIGUSR1 $cpid;
fi
done
+12
View File
@@ -0,0 +1,12 @@
# variables
ZTROOT=/data/adb/zerotier
APPROOT=/data/data/com.eventlowop.zerotier_magisk_app/app_flutter
ZT_LOG=$ZTROOT/run/zerotier.log
DAEMON_LOG=$ZTROOT/run/daemon.log
PIPE_CLI=$ZTROOT/run/pipe
PIPE_APP=$APPROOT/run/pipe
BB=/data/adb/magisk/busybox
+8 -10
View File
@@ -1,26 +1,24 @@
#!/system/bin/sh
pipe=/data/adb/zerotier/run/pipe
cli_output=/data/adb/zerotier/run/cli.out
cli_pid=/data/adb/zerotier/run/cli.pid
ZTROOT=/data/adb/zerotier
PIPE=$ZTROOT/run/pipe
help_text="Usage: zerotier.sh {start|stop|restart|status}"
HELP="Usage: zerotier.sh {start|stop|restart|status}"
if [[ ! -p $pipe ]]; then
if [[ ! -f $PIPE ]]; then
echo "daemon not running"
exit 1
fi
rm -f $cli_output
echo $$ > $cli_pid
echo $$ > $ZTROOT/run/cli.pid
on_receive() {
kill -9 %%
cat $cli_output
cat $ZTROOT/run/cli.out
exit 0
}
run() {
echo $cmd > $pipe
echo $cmd > $PIPE
}
trap 'on_receive' SIGUSR1
@@ -35,7 +33,7 @@ if [[ $# -eq 1 ]]; then
*) echo "unknown command $cmd";;
esac
else
echo $help_text
echo $HELP
exit 1
fi