feat: Insert rules when the network changes a8a85e1dad
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -77,6 +77,7 @@ xclash() {
|
||||
fi
|
||||
fi
|
||||
log Info "xclash [ $xclash_option ] setup completed"
|
||||
return 0
|
||||
}
|
||||
|
||||
box_ownership() {
|
||||
|
||||
95
box/scripts/net.inotify
Normal file
95
box/scripts/net.inotify
Normal file
@@ -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
|
||||
@@ -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/
|
||||
|
||||
Reference in New Issue
Block a user