CHIZI-0618 / box4magisk

Use sing-box, clash, v2ray, xray tunnel proxy on Android devices.
GNU General Public License v3.0
920 stars 104 forks source link

透明代理绕过 App(白名单模式)在非命令行启动时无效 #4

Closed escapezn closed 1 year ago

escapezn commented 1 year ago

测试条件:pixel 4a Android 13 单用户, box4magisk 4.4

proxy_method="TPROXY"
proxy_mode="blacklist"
user_packages_list=("0:com.bilibili.app.in" "0:org.zwanoo.android.speedtest")

使用以上配置时,yacd面板中仍可看到bilibili和speedtest的流量被代理

CHIZI-0618 commented 1 year ago

打开 /data/adb/box/run/run.log 日志文件,检查黑名单是否生效,若 transparent proxy for all apps. 则代表黑名单没有生效。 目前通过magisk 控制启停 Box 时黑白名单不生效是已知问题,但您可以任意终端(比如 Termux)执行 su -c '/data/adb/box/scripts/box.tproxy renew' 命令使黑白名单生效(注意日志输出)。

escapezn commented 1 year ago

原来是已知问题,执行renew命令后正常生效。

mx4994 commented 1 year ago

打开 /data/adb/box/run/run.log 日志文件,检查黑名单是否生效,若 transparent proxy for all apps. 则代表黑名单没有生效。 目前通过magisk 控制启停 Box 时黑白名单不生效是已知问题,但您可以任意终端(比如 Termux)执行 su -c '/data/adb/box/scripts/box.tproxy renew' 命令使黑白名单生效(注意日志输出)。

我用白名单会报这个错误ip: RTNETLINK answers: File exists,然后白名单列表的应用没有网络。 能否解释下不同的用户启动box服务有啥区别嘛?换成root需要setcap,然后那个libcap链接不知道怎么用🤣🤣🤣

CHIZI-0618 commented 1 year ago

我用白名单会报这个错误ip: RTNETLINK answers: File exists,然后白名单列表的应用没有网络。

看起来你重复应用了透明代理脚本,其他看不出有效信息

能否解释下不同的用户启动box服务有啥区别嘛?换成root需要setcap

不同用户启动 box 服务没有本质区别,默认使用 root:net_admin 启动 box 服务。这些最终都是为了

然后那个libcap链接不知道怎么用🤣🤣🤣

至于 libcap,建议了解 Linux Capabilitieshttps://github.com/CHIZI-0618/box4magisk/blob/603b13a4130923c90830943c27dc36f6702b4c20/box/scripts/box.service#L56-L83

我给出的链接为源代码仓库,需要自己编译。

mx4994 commented 1 year ago

感谢解答,没区别就不折腾了🤣

CHIZI-0618 commented 1 year ago

原来是已知问题,执行renew命令后正常生效。

尝试 https://github.com/CHIZI-0618/box4magisk/commit/1af3ee024b1fb0bc1f759d1d6a2dc2ab1a58a42f

escapezn commented 1 year ago

run_error.log

netstat: /proc/4686: No such file or directory /data/adb/box/scripts/box.tproxy[526]: 0100000+: unexpected 'end of expression' /data/adb/box/scripts/box.tproxy[526]: 0100000+: unexpected 'end of expression'

并且绕过代理无效,renew命令执行后依然无效

CHIZI-0618 commented 1 year ago

run_error.log

netstat: /proc/4686: No such file or directory /data/adb/box/scripts/box.tproxy[526]: 0_100000+: unexpected 'end of expression' /data/adb/box/scripts/box.tproxy[526]: 0_100000+: unexpected 'end of expression'

并且绕过代理无效,renew命令执行后依然无效

https://github.com/CHIZI-0618/box4magisk/blob/38c4e962e9fb43c736a06ed8bd6762fd55824d03/box/scripts/box.tproxy#L36 这一行改为 uid_list[${#uid_list[@]}]=$(expr ${user} \* 100000 + $(cat /data/system/packages.list | grep ${package} | awk '{print $2}')) 试试

escapezn commented 1 year ago

刚试下了,好像已经可以了,但是日志还有报错

netstat: /proc/9444: No such file or directory expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input

CHIZI-0618 commented 1 year ago

你的 shell 行为太奇怪了

试试 100000 加个引号,uid_list[${#uid_list[@]}]=$(expr ${user} \* "100000" + $(cat /data/system/packages.list | grep ${package} | awk '{print $2}'))

CHIZI-0618 commented 1 year ago

测试时可以考虑改动 box.inotify 文件,删除 service 控制保留 tproxy 控制。此时 Magisk Manager 里本模块状态就可以仅仅控制透明代理而不影响核心启停

#!/system/bin/sh

scripts=$(realpath $0)
scripts_dir=$(dirname ${scripts})

source ${scripts_dir}/box.config

service_path="${scripts_dir}/box.service"
tproxy_path="${scripts_dir}/box.tproxy"

events=$1
monitor_dir=$2
monitor_file=$3

service_control() {
  if [ ! -f ${box_path}/manual ] ; then
    if [ "${monitor_file}" = "disable" ] ; then
      if [ "${events}" = "d" ] ; then
        ${tproxy_path} enable >> ${run_path}/run.log 2>> ${run_path}/run_error.log
      elif [ "${events}" = "n" ] ; then
        ${tproxy_path} disable >> ${run_path}/run.log 2>> ${run_path}/run_error.log
      fi
    fi
  fi
}

mkdir -p ${run_path}

service_control
escapezn commented 1 year ago

还是同样的错误,绕过功能应该正常了,暂时没发现有什么影响

CHIZI-0618 commented 1 year ago

还是同样的错误

改成

find_packages_uid() {
  for user_package in ${user_packages_list[@]} ; do
    user=$(echo ${user_package} | awk -F ':' '{print 100000*$1}')
    package=$(echo ${user_package} | awk -F ':' '{print $2}')
    uid_list[${#uid_list[@]}]=$(expr ${user} + $(cat /data/system/packages.list | grep ${package} | awk '{print $2}'))
  done
}
CHIZI-0618 commented 1 year ago

刚试下了,好像已经可以了,但是日志还有报错

netstat: /proc/9444: No such file or directory expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input expr: Unexpected end of input

或许我应该看一下你执行 cat /data/system/packages.list | grep com.tencent.mm | awk '{print $2}' 的结果,当然,你可以换 com.tencent.mm 包名

escapezn commented 1 year ago

10300

CHIZI-0618 commented 1 year ago

10300

那我不知道 expr 报错是为什么了(:

escapezn commented 1 year ago

还是同样的错误

改成

find_packages_uid() {
  for user_package in ${user_packages_list[@]} ; do
    user=$(echo ${user_package} | awk -F ':' '{print 100000*$1}')
    package=$(echo ${user_package} | awk -F ':' '{print $2}')
    uid_list[${#uid_list[@]}]=$(expr ${user} + $(cat /data/system/packages.list | grep ${package} | awk '{print $2}'))
  done
}

这样改同样的报错信息

CHIZI-0618 commented 1 year ago

还是同样的错误

改成

find_packages_uid() {
  for user_package in ${user_packages_list[@]} ; do
    user=$(echo ${user_package} | awk -F ':' '{print 100000*$1}')
    package=$(echo ${user_package} | awk -F ':' '{print $2}')
    uid_list[${#uid_list[@]}]=$(expr ${user} + $(cat /data/system/packages.list | grep ${package} | awk '{print $2}'))
  done
}

这样改同样的报错信息

虽然报错但能用就行,你可以使用 iptables -t mangle -nvL | grep "owner UID match" 来检查是否有 UID 绕过或代理

escapezn commented 1 year ago

破案了是我的问题,有些config里绕过的app已经删了所以找不到报错

CHIZI-0618 commented 1 year ago

破案了是我的问题,有些config里绕过的app已经删了所以找不到报错

啊确实,我知道了,就是因为 cat /data/system/packages.list | grep ${package} | awk '{print $2}' 这一句,如果 ${package} 不存在则返回值为空,后续的 expr 就有问题了,但不影响其他正常的 ${package} UID 填充,$(()) 做不到这一点。

Rakau commented 1 year ago

唯一的IS终于结束了

CHIZI-0618 commented 1 year ago

唯一的IS终于结束了

拖了一年多的时间(: 主要是原本是能用的只是不好用 我自己又没需求

powerAn2020 commented 1 year ago

发现新的bug,当我尝试使用白名单模式且勾选Google play商店的时候会发生问题,这是我过滤出来的内容 image

find_packages_uid() {
  for user_package in ${user_packages_list[@]} ; do
    user=$(echo ${user_package} | awk -F ':' '{print $1}')
    package=$(echo ${user_package} | awk -F ':' '{print $2}')
    uid_list[${#uid_list[@]}]=$((${user}*100000+$(cat /data/system/packages.list | grep ${package} | awk '{print $2}')))
  done
}

简单通过grep过滤会有问题。本来只想查找一个的,但是意外找到了所有从google play下载的应用。是否应该使用awk先过滤掉前两个字段,然后再进行后续查找呢

    uid_list[${#uid_list[@]}]=$((${user}*100000+$(awk '{if($1=="'${package}'"){print $2}}' /data/system/packages.list)))
CHIZI-0618 commented 1 year ago

发现新的bug,当我尝试使用白名单模式且勾选Google play商店的时候会发生问题,这是我过滤出来的内容 image

find_packages_uid() {
  for user_package in ${user_packages_list[@]} ; do
    user=$(echo ${user_package} | awk -F ':' '{print $1}')
    package=$(echo ${user_package} | awk -F ':' '{print $2}')
    uid_list[${#uid_list[@]}]=$((${user}*100000+$(cat /data/system/packages.list | grep ${package} | awk '{print $2}')))
  done
}

简单通过grep过滤会有问题。本来只想查找一个的,但是意外找到了所有从google play下载的应用。是否应该使用awk先过滤掉前两个字段,然后再进行后续查找呢

    uid_list[${#uid_list[@]}]=$((${user}*100000+$(awk '{if($1=="'${package}'"){print $2}}' /data/system/packages.list)))

很好的建议,可以 pr