diff --git a/easytier-contrib/easytier-magisk/action.sh b/easytier-contrib/easytier-magisk/action.sh index 7ab70f3..599a119 100644 --- a/easytier-contrib/easytier-magisk/action.sh +++ b/easytier-contrib/easytier-magisk/action.sh @@ -1,14 +1,43 @@ #!/data/adb/magisk/busybox sh MODDIR=${0%/*} +MODULE_PROP="${MODDIR}/module.prop" -# 查找 easytier-core 进程的 PID -PID=$(pgrep easytier-core) +ET_STATUS="" +REDIR_STATUS="" +# 更新module.prop文件中的description +update_module_description() { + local status_message=$1 + sed -i "/^description=/c\description=[状态]${status_message}" ${MODULE_PROP} +} -# 检查是否找到了进程 -if [ -z "$PID" ]; then - echo "easytier-core 进程未找到" -else - # 结束进程 - kill $PID - echo "已结束 easytier-core 进程 (PID: $PID)" + +if [ -f "${MODDIR}/disable" ]; then + ET_STATUS="已关闭" +elif pgrep -f 'easytier-core' >/dev/null; then + if [ -f "${MODDIR}/config/command_args"]; then + ET_STATUS="主程序已开启(启动参数模式)" + else + ET_STATUS="主程序已开启(配置文件模式)" + fi +fi + +#ET_STATUS不存在说明开启模块未正常运行,不修改状态 +if [ -n "$ET_STATUS" ]; then + if [ -f "${MODDIR}/enable_IP_rule" ]; then + rm -f "${MODDIR}/enable_IP_rule" + ${MODDIR}/hotspot_iprule.sh del + REDIR_STATUS="转发已禁用" + echo "热点子网转发已禁用" + echo "[ET-NAT] IP rule disabled." >> "${MODDIR}/log.log" + else + touch "${MODDIR}/enable_IP_rule" + ${MODDIR}/hotspot_iprule.sh del + ${MODDIR}/hotspot_iprule.sh add_once + REDIR_STATUS="转发已激活" + echo "热点子网转发已激活,热点开启后将自动将热点加入转发网络(要求已配置本地网络cidr=参数)。转发规则将随着热点开关而自动开关。该状态将保持到转发被禁用为止。" + echo "[ET-NAT] IP rule enabled." >> "${MODDIR}/log.log" + fi + update_module_description "${ET_STATUS} | ${REDIR_STATUS}" +else + echo "主程序未正常启动,请先检查配置文件" fi diff --git a/easytier-contrib/easytier-magisk/customize.sh b/easytier-contrib/easytier-magisk/customize.sh index 986d419..f437828 100644 --- a/easytier-contrib/easytier-magisk/customize.sh +++ b/easytier-contrib/easytier-magisk/customize.sh @@ -4,5 +4,6 @@ ui_print '当前系统版本为' + $API ui_print '安装目录为: /data/adb/modules/easytier_magisk' ui_print '配置文件位置: /data/adb/modules/easytier_magisk/config/config.toml' ui_print '如果需要自定义启动参数,可将 /data/adb/modules/easytier_magisk/config/command_args_sample 重命名为 command_args,并修改其中内容,使用自定义启动参数时会忽略配置文件' -ui_print '修改后配置文件后在magisk app点击操作按钮即可生效' -ui_print '记得重启' \ No newline at end of file +ui_print '修改配置文件后在magisk app禁用应用再启动即可生效' +ui_print '点击操作按钮可启动/关闭热点子网转发,配合easytier的子网代理功能实现手机热点访问easytier网络' +ui_print '记得重启' diff --git a/easytier-contrib/easytier-magisk/easytier_core.sh b/easytier-contrib/easytier-magisk/easytier_core.sh index 8949f4f..0d148a1 100644 --- a/easytier-contrib/easytier-magisk/easytier_core.sh +++ b/easytier-contrib/easytier-magisk/easytier_core.sh @@ -5,6 +5,7 @@ CONFIG_FILE="${MODDIR}/config/config.toml" LOG_FILE="${MODDIR}/log.log" MODULE_PROP="${MODDIR}/module.prop" EASYTIER="${MODDIR}/easytier-core" +REDIR_STATUS="" # 更新module.prop文件中的description update_module_description() { @@ -12,6 +13,12 @@ update_module_description() { sed -i "/^description=/c\description=[状态]${status_message}" ${MODULE_PROP} } +if [ -f "${MODDIR}/enable_IP_rule" ]; then + REDIR_STATUS="转发已激活" +else + REDIR_STATUS="转发已禁用" +fi + if [ ! -e /dev/net/tun ]; then if [ ! -d /dev/net ]; then mkdir -p /dev/net @@ -22,7 +29,7 @@ fi while true; do if ls $MODDIR | grep -q "disable"; then - update_module_description "关闭中" + update_module_description "关闭中 | ${REDIR_STATUS}" if pgrep -f 'easytier-core' >/dev/null; then echo "开关控制$(date "+%Y-%m-%d %H:%M:%S") 进程已存在,正在关闭 ..." pkill easytier-core # 关闭进程 @@ -39,13 +46,16 @@ while true; do if [ -f "${MODDIR}/config/command_args" ]; then TZ=Asia/Shanghai ${EASYTIER} $(cat ${MODDIR}/config/command_args) > ${LOG_FILE} & sleep 5s # 等待easytier-core启动完成 - update_module_description "已开启(自定义启动参数)(不一定运行成功)" + update_module_description "主程序已开启(启动参数模式) | ${REDIR_STATUS}" else TZ=Asia/Shanghai ${EASYTIER} -c ${CONFIG_FILE} > ${LOG_FILE} & sleep 5s # 等待easytier-core启动完成 - update_module_description "已开启(不一定运行成功)" + update_module_description "主程序已开启(配置文件模式) | ${REDIR_STATUS}" fi ip rule add from all lookup main + if ! pgrep -f 'easytier-core' >/dev/null; then + update_module_descriptio "主程序启动失败,请检查配置文件" + fi else echo "开关控制$(date "+%Y-%m-%d %H:%M:%S") 进程已存在" fi diff --git a/easytier-contrib/easytier-magisk/hotspot_iprule.sh b/easytier-contrib/easytier-magisk/hotspot_iprule.sh new file mode 100644 index 0000000..03b1e64 --- /dev/null +++ b/easytier-contrib/easytier-magisk/hotspot_iprule.sh @@ -0,0 +1,90 @@ +#!/system/bin/sh +MODDIR=${0%/*} +CONFIG_FILE="${MODDIR}/config/config.toml" +LOG_FILE="${MODDIR}/log.log" +ACTION="$1" # 参数:add add_once del + + +# 获取接口/IP +get_et_iface() { + awk ' + BEGIN { IGNORECASE = 1 } + /^[[:space:]]*dev_name[[:space:]]*=/ { + val = $0 + sub(/^[^=]*=[[:space:]]*/, "", val) + gsub(/[" \t]/, "", val) + print val + exit + } + ' "$CONFIG_FILE" +} +get_tun_iface() { + ip link | awk -F': ' '/ tun[[:alnum:]]+/ {print $2; exit}' +} +get_hot_iface() { + ip link | awk -F': ' '/(^| )(swlan[[:alnum:]_]*|softap[[:alnum:]_]*|ap[[:alnum:]_]*)\:/ {print $2; exit}' | cut -d'@' -f1 | head -n1 +} +get_hot_cidr() { + ip -4 addr show dev "$1" | awk '/inet /{print $2; exit}' +} + + +set_nat_rules() { + ET_IFACE=$(get_et_iface) + [ -z "$ET_IFACE" ] && ET_IFACE="$(get_tun_iface)" + HOT_IFACE=$(get_hot_iface) + HOT_CIDR=$(get_hot_cidr "$HOT_IFACE") + + # 如果热点关闭就删除自定义链 + [ -n "$ET_IFACE" ] && [ -n "$HOT_CIDR" ] || return 1 + + # 创建自定义链(如不存在) + iptables -t nat -N ET_NAT 2>/dev/null + iptables -N ET_FWD 2>/dev/null + + # 确保主链首条跳转到自定义链 + iptables -t nat -C POSTROUTING -j ET_NAT 2>/dev/null || \ + iptables -t nat -I POSTROUTING 1 -j ET_NAT + iptables -C FORWARD -j ET_FWD 2>/dev/null || \ + iptables -I FORWARD 1 -j ET_FWD + + # 添加规则 + iptables -t nat -A ET_NAT -s "$HOT_CIDR" -o "$ET_IFACE" -j MASQUERADE + iptables -A ET_FWD -i "$HOT_IFACE" -o "$ET_IFACE" \ + -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT + iptables -A ET_FWD -i "$ET_IFACE" -o "$HOT_IFACE" \ + -m state --state ESTABLISHED,RELATED -j ACCEPT + + echo "[ET-NAT] Rules applied: $HOT_IFACE $HOT_CIDR ↔ $ET_IFACE" >> "$LOG_FILE" +} + +flush_rules() { + iptables -t nat -F ET_NAT 2>/dev/null + iptables -F ET_FWD 2>/dev/null + echo "[ET-NAT] Custom chains flushed." >> "$LOG_FILE" +} + +case "$ACTION" in + add) + set_nat_rules + echo "[ET-NAT] Guard started." >> "$LOG_FILE" + ip monitor link addr | while read -r _; do + if [ -f "${MODDIR}/enable_IP_rule" ]; then + flush_rules + set_nat_rules + fi + done + ;; + add_once) + flush_rules + set_nat_rules + echo "[ET-NAT] One-time rules applied." >> "$LOG_FILE" + ;; + del) + flush_rules + ;; + *) + echo "Usage: $0 [add|del]" + exit 1 + ;; +esac diff --git a/easytier-contrib/easytier-magisk/service.sh b/easytier-contrib/easytier-magisk/service.sh index c443017..489f392 100644 --- a/easytier-contrib/easytier-magisk/service.sh +++ b/easytier-contrib/easytier-magisk/service.sh @@ -18,10 +18,7 @@ sed -i 's/$(description=)$[^"]*/\1[状态]关闭中/' "$MODDIR/module.prop" sleep 3s "${MODDIR}/easytier_core.sh" & +"${MODDIR}/hotspot_iprule.sh" add & -# 检查是否启用模块 -while [ ! -f ${MODDIR}/disable ]; do - sleep 2 -done - -pkill easytier-core +# easytier_core.sh 和 hotspot_iprule.sh 都有内部循环做守护, +# 所以这里不需要再做守护了