diff --git a/box/scripts/box.iptables b/box/scripts/box.iptables index 1837aed..4ed7398 100755 --- a/box/scripts/box.iptables +++ b/box/scripts/box.iptables @@ -14,8 +14,8 @@ fake_ip_range="" iptables_version=$(iptables --version | busybox awk '/^iptables/ {print $2}') required_version="v1.6.1" if [ "$(printf '%s\n' "$required_version" "$iptables_version" | sort -V | head -n1)" = "$required_version" ]; then - IPV="iptables -w 32" - IP6V="ip6tables -w 32" + IPV="iptables -w 64" + IP6V="ip6tables -w 64" else IPV="iptables" IP6V="ip6tables" @@ -36,10 +36,12 @@ case "${bin_name}" in "sing-box") if [[ "${network_mode}" == @(mixed|tun) ]]; then tun_device=$(find "${box_dir}/sing-box/" -maxdepth 1 -type f -name "*.json" -exec busybox grep -oE '"interface_name": "[^"]*' {} + | busybox awk -F'"' '{print $4}' 2>/dev/null | head -n 1) + if [ -z "$tun_device" ]; then tun_device="tun0" fi fi + fake_ip_range=$(find ${box_dir}/sing-box/ -maxdepth 1 -type f -name "*.json" -exec busybox awk -F'"' '/inet4_range/ {print $4}' {} +) fake_ip6_range=$(find ${box_dir}/sing-box/ -maxdepth 1 -type f -name "*.json" -exec busybox awk -F'"' '/inet6_range/ {print $4}' {} +) ;; @@ -212,9 +214,9 @@ ipv4_rules=( ipv6_rules=( "iif lo goto 6000 pref 5000" "iif ${tun_device} lookup main suppress_prefixlength 0 pref 5010" - # "from 10.0.0.0/8 lookup ${tun_table_index} pref 5030" - # "from 172.16.0.0/12 lookup ${tun_table_index} pref 5040" - # "from 192.168.0.0/16 lookup ${tun_table_index} pref 5050" + # "from 2001:db8::/32 lookup ${tun_table_index} pref 5030" + # "from fc00::/7 lookup ${tun_table_index} pref 5040" + # "from fd00::/8 lookup ${tun_table_index} pref 5050" "iif ${tun_device} goto 6000 pref 5020" "nop pref 6000" ) @@ -232,9 +234,9 @@ ipv6_rules=( # Function to delete IP rules for the tun device tun_forward_ip_rules_del() { - for pref in 5000 5010 5020 5030 5040 5050 6000; do - ip -4 rule del pref $pref - ip -6 rule del pref $pref + for preff in 5000 5010 5020 5030 5040 5050 6000; do + ip -4 rule del pref $preff + ip -6 rule del pref $preff done } @@ -249,6 +251,7 @@ sing_tun_ip_rules() { # Function to modify the FORWARD chain for the specified tun device using iptables forward() { local action=$1 + ${iptables} "${action}" FORWARD -i "${tun_device}" -j ACCEPT ${iptables} "${action}" FORWARD -o "${tun_device}" -j ACCEPT @@ -257,26 +260,25 @@ forward() { sysctl -w net.ipv4.conf.all.rp_filter=2 probe_tun_index - if [ "${tun_forward}" = "enable" ] ; then + + if [ "${tun_forward}" = "enable" ]; then if probe_tun_device; then + tun_forward_ip_rules_del + tun_forward_ip_rules "${action}" if [ "${action}" = "-I" ]; then - tun_forward_ip_rules_del - tun_forward_ip_rules "${action}" - sing_tun_ip_rules "add">> /dev/null 2>&1 + sing_tun_ip_rules "add" else - tun_forward_ip_rules_del - tun_forward_ip_rules "${action}" - sing_tun_ip_rules "del" >> /dev/null 2>&1 + sing_tun_ip_rules "del" fi - return 0 else tun_forward_ip_rules_del tun_forward_ip_rules -D - sing_tun_ip_rules "del" >> /dev/null 2>&1 + sing_tun_ip_rules "del" log Error "tun device not found" return 1 fi fi + return 0 } >> /dev/null 2>&1 start_redirect() { @@ -299,9 +301,11 @@ start_redirect() { # Fix ICMP (ping) # This does not guarantee that the ping result is valid # Just that it returns a result - if [ -n "${fake_ip_range}" ]; then - ${iptables} -t nat -A BOX_EXTERNAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 - ${iptables} -t nat -A BOX_LOCAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 + if [[ "${bin_name}" == @(clash|sing-box) ]]; then + if [ -n "${fake_ip_range}" ]; then + ${iptables} -t nat -A BOX_EXTERNAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 + ${iptables} -t nat -A BOX_LOCAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 + fi fi # Allow access to intranet subnets @@ -324,7 +328,7 @@ start_redirect() { if [ "${ignore_out_list}" != "" ]; then for ignore in "${ignore_out_list[@]}"; do - ${iptables} -t nat -I BOX_LOCAL -o "${ignore}" -j RETURN + ${iptables} -t nat -A BOX_LOCAL -o "${ignore}" -j RETURN done [ ${network_mode} = "enhance" ] || log Info "${ignore_out_list[*]} ignore transparent proxy." fi @@ -345,7 +349,7 @@ start_redirect() { # loop through the UID list while read -r appid; do # add iptables rules for returning packets - ${iptables} -t nat -I BOX_LOCAL -m owner --uid-owner "${appid}" -j RETURN + ${iptables} -t nat -A BOX_LOCAL -m owner --uid-owner "${appid}" -j RETURN done < "${uid_list[@]}" # Allow !app ${iptables} -t nat -A BOX_LOCAL -p tcp -j REDIRECT --to-ports "${redir_port}" @@ -354,9 +358,11 @@ start_redirect() { if [ "${gid_list}" != "" ] ; then # Bypass gids for gid in ${gid_list[@]} ; do - ${iptables} -t nat -I BOX_LOCAL -m owner --gid-owner ${gid} -j RETURN + ${iptables} -t nat -A BOX_LOCAL -m owner --gid-owner ${gid} -j RETURN done - [ ${network_mode} = "enhance" ] || [ "${iptables}" = "$IPV" ] && log Info "proxy mode: ${proxy_mode}, GID ${gid_list[*]} no transparent proxy." + [ ${network_mode} = "enhance" ] || { + [ "${iptables}" = "$IPV" ] && log Info "proxy mode: ${proxy_mode}, GID ${gid_list[*]} no transparent proxy." + } fi ;; whitelist) @@ -641,9 +647,11 @@ fi fi # Fix ICMP (ping), this does not guarantee that the ping result is valid (proxies such as clash do not support forwarding ICMP), # just that it returns a result, "--to-destination" can be set to a reachable address. - if [ -n "${fake_ip_range}" ]; then - ${iptables} -t nat -I OUTPUT -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 - ${iptables} -t nat -I PREROUTING -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 + if [[ "${bin_name}" == @(clash|sing-box) ]]; then + if [ -n "${fake_ip_range}" ]; then + ${iptables} -t nat -I OUTPUT -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 + ${iptables} -t nat -I PREROUTING -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 + fi fi fi } diff --git a/box/scripts/box.service b/box/scripts/box.service index 99c9065..d95c811 100755 --- a/box/scripts/box.service +++ b/box/scripts/box.service @@ -77,6 +77,7 @@ xclash() { fi fi log Info "xclash [ $xclash_option ] setup completed" + return 0 } box_ownership() { diff --git a/box/scripts/net.inotify b/box/scripts/net.inotify new file mode 100644 index 0000000..567732e --- /dev/null +++ b/box/scripts/net.inotify @@ -0,0 +1,95 @@ +#!/system/bin/sh + +events=$1 +# monitor_dir=$2 +# monitor_file=$3 + +export PATH="/data/adb/magisk:/data/adb/ksu/bin:/data/adb/ap/bin:$PATH:/system/bin" +iptables_version=$(iptables --version | busybox awk '/^iptables/ {print $2}') +required_version="v1.6.1" +if [ "$(printf '%s\n' "$required_version" "$iptables_version" | sort -V | head -n1)" = "$required_version" ]; then + IPV="iptables -w 64" + IP6V="ip6tables -w 64" +else + IPV="iptables" + IP6V="ip6tables" +fi +iptables=$IPV +ip6tables=$IP6V + +rules_add() { + # Retrieve all local IPv4 addresses except loopback (127.0.0.1) + ip -4 a | busybox awk '/inet/ {print $2}' | grep -vE "^127.0.0.1" | while read -r local_ipv4 ; do + echo "Checking IPv4 address: $local_ipv4" >> /data/adb/box/run/net.inotify.log + # Check if a rule for the local IPv4 address already exists in the mangle table + if ! iptables -t mangle -nL BOX_LOCAL | grep -q $local_ipv4 > /dev/null 2>&1 ; then + echo "Adding IPv4 address $local_ipv4 to mangle tables." >> /data/adb/box/run/net.inotify.log + # If not, add a rule to prevent traffic to the local IPv4 address from going external + ${iptables} -t mangle -I BOX_EXTERNAL 3 -d $local_ipv4 -j RETURN + ${iptables} -t mangle -I BOX_LOCAL 4 -d $local_ipv4 -j RETURN + fi + # Check if a rule for the local IPv4 address already exists in the nat table + if ! iptables -t nat -nL BOX_LOCAL | grep -q $local_ipv4 > /dev/null 2>&1 ; then + echo "Adding IPv4 address $local_ipv4 to nat tables." >> /data/adb/box/run/net.inotify.log + # If not, add a rule to prevent NAT on the local IPv4 address + ${iptables} -t nat -I BOX_EXTERNAL 3 -d $local_ipv4 -j RETURN + ${iptables} -t nat -I BOX_LOCAL 4 -d $local_ipv4 -j RETURN + fi + done + + # Retrieve all local IPv6 addresses except link-local (fe80::) and loopback (::1) + ip -6 a | busybox awk '/inet6/ {print $2}' | grep -vE "^fe80|^::1" | while read -r local_ipv6 ; do + echo "Checking IPv6 address: $local_ipv6" >> /data/adb/box/run/net.inotify.log + # Check if a rule for the local IPv6 address already exists in the mangle table + if ! ip6tables -t mangle -nL BOX_LOCAL | grep -q $local_ipv6 > /dev/null 2>&1 ; then + echo "Adding IPv6 address $local_ipv6 to mangle tables." >> /data/adb/box/run/net.inotify.log + # If not, add a rule to prevent traffic to the local IPv6 address from going external + ${ip6tables} -t mangle -I BOX_EXTERNAL 3 -d $local_ipv6 -j RETURN + ${ip6tables} -t mangle -I BOX_LOCAL 4 -d $local_ipv6 -j RETURN + fi + done +} + +rules_delete() { + # Retrieve all local IPv4 addresses except loopback (127.0.0.1) + ip -4 a | busybox awk '/inet/ {print $2}' | grep -vE "^127.0.0.1" | while read -r local_ipv4 ; do + echo "Checking IPv4 address for deletion: $local_ipv4" >> /data/adb/box/run/net.inotify.log + # Check if a rule for the local IPv4 address exists in the mangle table + if iptables -t mangle -nL BOX_LOCAL | grep -q $local_ipv4 > /dev/null 2>&1 ; then + echo "Deleting IPv4 address $local_ipv4 from mangle tables." >> /data/adb/box/run/net.inotify.log + # If exists, delete the rule + ${iptables} -t mangle -D BOX_EXTERNAL -d $local_ipv4 -j RETURN + ${iptables} -t mangle -D BOX_LOCAL -d $local_ipv4 -j RETURN + fi + # Check if a rule for the local IPv4 address exists in the nat table + if iptables -t nat -nL BOX_LOCAL | grep -q $local_ipv4 > /dev/null 2>&1 ; then + echo "Deleting IPv4 address $local_ipv4 from nat tables." >> /data/adb/box/run/net.inotify.log + # If exists, delete the rule + ${iptables} -t nat -D BOX_EXTERNAL -d $local_ipv4 -j RETURN + ${iptables} -t nat -D BOX_LOCAL -d $local_ipv4 -j RETURN + fi + done + + # Retrieve all local IPv6 addresses except link-local (fe80::) and loopback (::1) + ip -6 a | busybox awk '/inet6/ {print $2}' | grep -vE "^fe80|^::1" | while read -r local_ipv6 ; do + echo "Checking IPv6 address for deletion: $local_ipv6" >> /data/adb/box/run/net.inotify.log + # Check if a rule for the local IPv6 address exists in the mangle table + if ip6tables -t mangle -nL BOX_LOCAL | grep -q $local_ipv6 > /dev/null 2>&1 ; then + echo "Deleting IPv6 address $local_ipv6 from mangle tables." >> /data/adb/box/run/net.inotify.log + # If exists, delete the rule + ${ip6tables} -t mangle -D BOX_EXTERNAL -d $local_ipv6 -j RETURN + ${ip6tables} -t mangle -D BOX_LOCAL -d $local_ipv6 -j RETURN + fi + done +} + +if [ "$events" = "w" ]; then + date > /data/adb/box/run/net.inotify.log + if [ -f /data/adb/box/run/box.pid ] ; then + rules_add + rm -f /data/adb/box/run/net + elif [ ! -f /data/adb/box/run/net ]; then + rules_delete + touch /data/adb/box/run/net + fi +fi \ No newline at end of file diff --git a/box/scripts/start.sh b/box/scripts/start.sh index 5340195..fe3abf2 100755 --- a/box/scripts/start.sh +++ b/box/scripts/start.sh @@ -2,23 +2,12 @@ scripts_dir="${0%/*}" file_settings="/data/adb/box/settings.ini" - moddir="/data/adb/modules/box_for_root" -if [ -n "$(magisk -v | grep lite &> /dev/null )" ]; then - moddir="/data/adb/lite_modules/box_for_root" -fi - -if [ -f "/data/adb/ksu/bin/busybox" ]; then - # busybox KSU - busybox="/data/adb/ksu/bin/busybox" -elif [ -f "/data/adb/ap/bin/busybox" ]; then - # busybox APatch - busybox="/data/adb/ap/bin/busybox" -else - # busybox Magisk - busybox="/data/adb/magisk/busybox" -fi +# busybox Magisk/KSU/Apatch +busybox="/data/adb/magisk/busybox" +[ -f "/data/adb/ksu/bin/busybox" ] && busybox="/data/adb/ksu/bin/busybox" +[ -f "/data/adb/ap/bin/busybox" ] && busybox="/data/adb/ap/bin/busybox" refresh_box() { if [ -f "/data/adb/box/run/box.pid" ]; then @@ -54,7 +43,15 @@ start_inotifyd() { kill -9 "$PID" fi done - inotifyd "${scripts_dir}/box.inotify" "${moddir}" >> "/dev/null" 2>&1 & + inotifyd "${scripts_dir}/box.inotify" "${moddir}" > "/dev/null" 2>&1 & + + while [ ! -f /data/misc/net/rt_tables ] ; do + sleep 3 + done + + net_dir="/data/misc/net" + # Use inotifyd to monitor write events in the /data/misc/net directory for network changes, perhaps we have a better choice of files to monitor (the /proc filesystem is unsupported) and cyclic polling is a bad solution + inotifyd "${scripts_dir}/net.inotify" "${net_dir}" > "/dev/null" 2>&1 & } mkdir -p /data/adb/box/run/