From 2c8c1b8d644531e3ffe5a0aecc460fb984886927 Mon Sep 17 00:00:00 2001 From: tearmoon Date: Tue, 21 May 2024 23:12:07 +0700 Subject: [PATCH] [adjust] box.iptables --- box/scripts/box.iptables | 131 ++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 78 deletions(-) diff --git a/box/scripts/box.iptables b/box/scripts/box.iptables index 12bb97f..871784b 100755 --- a/box/scripts/box.iptables +++ b/box/scripts/box.iptables @@ -3,14 +3,15 @@ scripts_dir="${0%/*}" source /data/adb/box/settings.ini -table="223" -fwmark="223" +fwmark="16777216/16777216" +table="2024" pref="100" # disable / enable quic using iptables rules quic="enable" iptables_version=$(iptables --version | busybox awk '/^iptables/ {print $2}') -if busybox awk -v current_version="$iptables_version" -v required_version="v1.6.1" 'BEGIN { exit !(current_version > required_version) }'; then +required_version="v1.6.1" +if [ "$(printf '%s\n' "$required_version" "$iptables_version" | sort -V | head -n1)" = "$required_version" ]; then IPV="iptables -w 100" IP6V="ip6tables -w 100" else @@ -153,6 +154,7 @@ intranet=( 255.255.255.0/24 255.255.255.255/32 ) +# The use of 100.0.0.0/8 instead of 100.64.0.0/10 is purely due to a mistake by China Telecom's service provider, and you can change it back. intranet+=($(ip -4 a | busybox awk '/inet/ {print $2}' | busybox grep -vE "^127.0.0.1")) intranet6=( @@ -190,7 +192,6 @@ start_redirect() { if [ "${bin_name}" = "clash" ]; then ${iptables} -t nat -A BOX_EXTERNAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}" ${iptables} -t nat -A BOX_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}" - # Other types of inbound should be added here to receive DNS traffic instead of sniffing # ${iptables} -t nat -A BOX_EXTERNAL -p udp --dport 53 -j REDIRECT --to-ports "${redir_port}" # ${iptables} -t nat -A BOX_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${redir_port}" @@ -200,7 +201,6 @@ start_redirect() { # This does not guarantee that the ping result is valid # Just that it returns a result # "--to-destination" can be set to a reachable address. - # 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 @@ -222,7 +222,6 @@ start_redirect() { fi ${iptables} -t nat -I PREROUTING -j BOX_EXTERNAL - ${iptables} -t nat -I BOX_LOCAL -m owner --uid-owner "${box_user}" --gid-owner "${box_group}" -j RETURN if [ "${ignore_out_list}" != "" ]; then @@ -250,7 +249,6 @@ start_redirect() { # add iptables rules for returning packets ${iptables} -t nat -I 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}" [ ${network_mode} = "enhance" ] || log Info "proxy-mode: ${proxy_mode}, package ${packages_list[*]} no transparent proxy." @@ -275,7 +273,6 @@ start_redirect() { # add iptables rules for TCP traffic ${iptables} -t nat -A BOX_LOCAL -p tcp -m owner --uid-owner "${appid}" -j REDIRECT --to-ports "${redir_port}" done < "${uid_list[@]}" - ${iptables} -t nat -A BOX_LOCAL -p tcp -m owner --uid-owner 0 -j REDIRECT --to-ports "${redir_port}" ${iptables} -t nat -A BOX_LOCAL -p tcp -m owner --uid-owner 1052 -j REDIRECT --to-ports "${redir_port}" [ ${network_mode} = "enhance" ] || log Info "proxy-mode: ${proxy_mode}, package ${packages_list[*]} transparent proxy." @@ -324,7 +321,6 @@ stop_redirect() { if [ "${iptables}" = "$IPV" ]; then # ${iptables} -t nat -D BOX_EXTERNAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 # ${iptables} -t nat -D BOX_LOCAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 - ${iptables} -t nat -F BOX_EXTERNAL ${iptables} -t nat -X BOX_EXTERNAL ${iptables} -t nat -F BOX_LOCAL @@ -345,11 +341,7 @@ start_tproxy() { # Create the BOX_EXTERNAL chain if it doesn't exist ${iptables} -t mangle -N BOX_EXTERNAL 2>/dev/null - ${iptables} -t mangle -F BOX_EXTERNAL - - # TTL - # ${iptables} -t mangle -A BOX_EXTERNAL -m ttl --ttl-lt 32 -j DROP - # ${iptables} -t mangle -D BOX_EXTERNAL -m ttl --ttl-lt 32 -j DROP + ${iptables} -t mangle -F BOX_EXTERNAL 2>/dev/null # Bypass box itself # ${iptables} -t mangle -A BOX_EXTERNAL -m mark --mark ${routing_mark} -j RETURN @@ -360,30 +352,34 @@ start_tproxy() { # ${iptables} -t mangle -I BOX_EXTERNAL -i rmnet_data+ -j RETURN # ${iptables} -t mangle -I BOX_EXTERNAL -i ccmni+ -j RETURN + # Skip traffic already handled by TProxy + # If the interface of the default route has a public IPv4 or IPv6 address assigned by the ISP, omitting these rules will result in abnormal proxy behavior for local traffic, which may cause the entire network to run slower + # [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_EXTERNAL -p tcp -m socket --transparent -j MARK --set-mark ${fwmark} + # ${iptables} -t mangle -A BOX_EXTERNAL -p udp -m socket --transparent -j MARK --set-mark ${fwmark} + # ${iptables} -t mangle -A BOX_EXTERNAL -m socket -j RETURN + # Bypass intranet - # Add rules for intranet subnets + if [ "${bin_name}" = "clash" ] ; then + [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_EXTERNAL -p tcp --dport 53 -j RETURN + ${iptables} -t mangle -A BOX_EXTERNAL -p udp --dport 53 -j RETURN + else + # Route DNS request to Box + [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_EXTERNAL -p tcp --dport 53 -j TPROXY --on-port ${tproxy_port} --tproxy-mark ${fwmark} + ${iptables} -t mangle -A BOX_EXTERNAL -p udp --dport 53 -j TPROXY --on-port ${tproxy_port} --tproxy-mark ${fwmark} + fi + + # Bypass intranet + # Run `su -c 'zcat /proc/config.gz | grep -i addrtype'` to check compatibility + # ${iptables} -t mangle -A BOX_EXTERNAL -m addrtype --dst-type LOCAL -j RETURN if [ "${iptables}" = "$IPV" ]; then - for subnet in "${intranet[@]}"; do - if [ "${bin_name}" = "clash" ]; then - ${iptables} -t mangle -A BOX_EXTERNAL -d "${subnet}" -j RETURN - else - ${iptables} -t mangle -A BOX_EXTERNAL -d "${subnet}" -p udp ! --dport 53 -j RETURN - [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_EXTERNAL -d "${subnet}" ! -p udp -j RETURN - fi + for subnet in ${intranet[@]} ; do + ${iptables} -t mangle -A BOX_EXTERNAL -d ${subnet} -j RETURN done else - # Add rules for intranet6 subnets - for subnet6 in "${intranet6[@]}"; do - if [ "${bin_name}" = "clash" ]; then - ${iptables} -t mangle -A BOX_EXTERNAL -d "${subnet6}" -j RETURN - else - ${iptables} -t mangle -A BOX_EXTERNAL -d "${subnet6}" -p udp ! --dport 53 -j RETURN - [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_EXTERNAL -d "${subnet6}" ! -p udp -j RETURN - fi + for subnet6 in ${intranet6[@]} ; do + ${iptables} -t mangle -A BOX_EXTERNAL -d ${subnet6} -j RETURN done fi - # Append the BOX_EXTERNAL chain to the PREROUTING chain - # ${iptables} -t mangle -A PREROUTING -j BOX_EXTERNAL [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_EXTERNAL -p tcp -i lo -j TPROXY --on-port "${tproxy_port}" --tproxy-mark "${fwmark}" ${iptables} -t mangle -A BOX_EXTERNAL -p udp -i lo -j TPROXY --on-port "${tproxy_port}" --tproxy-mark "${fwmark}" @@ -406,48 +402,38 @@ start_tproxy() { ${iptables} -t mangle -N BOX_LOCAL ${iptables} -t mangle -F BOX_LOCAL + # Bypass box itself + ${iptables} -t mangle -A BOX_LOCAL -m owner --uid-owner ${box_user} --gid-owner ${box_group} -j RETURN + # ${iptables} -t mangle -A BOX_LOCAL -m mark --mark ${routing_mark} -j RETURN + # Bypass ignored interfaces if [ "${ignore_out_list}" != "" ]; then for ignore in ${ignore_out_list[@]} ; do - ${iptables} -t mangle -I BOX_LOCAL -o "${ignore}" -j RETURN + ${iptables} -t mangle -A BOX_LOCAL -o "${ignore}" -j RETURN done [ "${iptables}" = "$IPV" ] && log Info "${ignore_out_list[*]} ignore transparent proxy." fi # Bypass intranet Clash if [ "${bin_name}" = "clash" ]; then + [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -p tcp --dport 53 -j RETURN ${iptables} -t mangle -A BOX_LOCAL -p udp --dport 53 -j RETURN - if [ "${iptables}" = "$IPV" ]; then - for subnet in "${intranet[@]}"; do - ${iptables} -t mangle -A BOX_LOCAL -d "${subnet}" -j RETURN - done - else - for subnet6 in "${intranet6[@]}"; do - ${iptables} -t mangle -A BOX_LOCAL -d "${subnet6}" -j RETURN - done - fi else - if [ "${iptables}" = "$IPV" ]; then - for subnet in "${intranet[@]}"; do - ${iptables} -t mangle -A BOX_LOCAL -d "${subnet}" -p udp ! --dport 53 -j RETURN - [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -d "${subnet}" ! -p udp -j RETURN - done - else - for subnet6 in "${intranet6[@]}"; do - ${iptables} -t mangle -A BOX_LOCAL -d "${subnet6}" -p udp ! --dport 53 -j RETURN - [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -d "${subnet6}" ! -p udp -j RETURN - done - fi + # Route DNS request to Box + [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -p tcp --dport 53 -j MARK --set-xmark ${fwmark} + ${iptables} -t mangle -A BOX_LOCAL -p udp --dport 53 -j MARK --set-xmark ${fwmark} fi - # Bypass box itself - ${iptables} -t mangle -I BOX_LOCAL -m owner --uid-owner "${box_user}" --gid-owner "${box_group}" -j RETURN - # ${iptables} -t mangle -I BOX_LOCAL -m mark --mark ${routing_mark} -j RETURN + if [ "${iptables}" = "$IPV" ]; then + for subnet in ${intranet[@]} ; do + ${iptables} -t mangle -A BOX_LOCAL -d ${subnet} -j RETURN + done + else + for subnet6 in ${intranet6[@]} ; do + ${iptables} -t mangle -A BOX_LOCAL -d ${subnet6} -j RETURN + done + fi - # Disable kernel - # ${iptables} -t mangle -A BOX_LOCAL -m owner ! --uid 0-99999999 -j DROP - - # check proxy mode case "${proxy_mode}" in blacklist) if [ -z "$(cat "${uid_list[@]}")" ] ; then @@ -456,12 +442,10 @@ start_tproxy() { ${iptables} -t mangle -A BOX_LOCAL -p udp -j MARK --set-mark "${fwmark}" [ "${iptables}" = "$IPV" ] && log Info "transparent proxy for all apps." else - # Bypass apps while read -r appid; do - ${iptables} -t mangle -I BOX_LOCAL -m owner --uid-owner "${appid}" -j RETURN + ${iptables} -t mangle -A BOX_LOCAL -m owner --uid-owner "${appid}" -j RETURN done < "${uid_list[@]}" - # Allow !app [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -p tcp -j MARK --set-mark "${fwmark}" ${iptables} -t mangle -A BOX_LOCAL -p udp -j MARK --set-mark "${fwmark}" @@ -470,7 +454,7 @@ start_tproxy() { if [ "${gid_list}" != "" ] ; then # Bypass gids for gid in ${gid_list[@]} ; do - ${iptables} -t mangle -I BOX_LOCAL -m owner --gid-owner ${gid} -j RETURN + ${iptables} -t mangle -A BOX_LOCAL -m owner --gid-owner ${gid} -j RETURN done [ "${iptables}" = "$IPV" ] && log Info "proxy mode: ${proxy_mode}, GID ${gid_list[*]} no transparent proxy." fi @@ -488,14 +472,11 @@ start_tproxy() { [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -p tcp -m owner --uid-owner "${appid}" -j MARK --set-mark "${fwmark}" ${iptables} -t mangle -A BOX_LOCAL -p udp -m owner --uid-owner "${appid}" -j MARK --set-mark "${fwmark}" done < "${uid_list[@]}" - [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -p tcp -m owner --uid-owner 0 -j MARK --set-mark "${fwmark}" ${iptables} -t mangle -A BOX_LOCAL -p udp -m owner --uid-owner 0 -j MARK --set-mark "${fwmark}" # Route dnsmasq to Box [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -A BOX_LOCAL -p tcp -m owner --uid-owner 1052 -j MARK --set-mark "${fwmark}" ${iptables} -t mangle -A BOX_LOCAL -p udp -m owner --uid-owner 1052 -j MARK --set-mark "${fwmark}" - # Route DNS request to Box - [ "${bin_name}" != "clash" ] && ${iptables} -t mangle -A BOX_LOCAL -p udp --dport 53 -j MARK --set-mark "${fwmark}" [ "${iptables}" = "$IPV" ] && log Info "proxy-mode: ${proxy_mode}, package ${packages_list[*]} transparent proxy." fi if [ "${gid_list}" != "" ] ; then @@ -517,12 +498,11 @@ start_tproxy() { ${iptables} -t mangle -I OUTPUT -j BOX_LOCAL - ${iptables} -t mangle -N DIVERT - ${iptables} -t mangle -F DIVERT - ${iptables} -t mangle -A DIVERT -j MARK --set-mark "${fwmark}" - ${iptables} -t mangle -A DIVERT -j ACCEPT - - [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -I PREROUTING -p tcp -m socket -j DIVERT + # ${iptables} -t mangle -N DIVERT + # ${iptables} -t mangle -F DIVERT + # ${iptables} -t mangle -A DIVERT -j MARK --set-mark "${fwmark}" + # ${iptables} -t mangle -A DIVERT -j ACCEPT + # [ ${network_mode} = "enhance" ] || ${iptables} -t mangle -I PREROUTING -p tcp -m socket -j DIVERT # Disable QUIC if [ "${quic}" = "disable" ]; then @@ -548,7 +528,6 @@ fi ${iptables} -t nat -F CLASH_DNS_EXTERNAL ${iptables} -t nat -A CLASH_DNS_EXTERNAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}" ${iptables} -t nat -I PREROUTING -j CLASH_DNS_EXTERNAL - # Create and configure CLASH_DNS_LOCAL chain ${iptables} -t nat -N CLASH_DNS_LOCAL ${iptables} -t nat -F CLASH_DNS_LOCAL @@ -556,7 +535,6 @@ fi ${iptables} -t nat -A CLASH_DNS_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}" ${iptables} -t nat -I OUTPUT -j CLASH_DNS_LOCAL 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 @@ -612,17 +590,14 @@ stop_tproxy() { if [ "${iptables}" = "$IPV" ]; then ${iptables} -t nat -D PREROUTING -j CLASH_DNS_EXTERNAL ${iptables} -t nat -D OUTPUT -j CLASH_DNS_LOCAL - ${iptables} -t nat -F CLASH_DNS_EXTERNAL ${iptables} -t nat -X CLASH_DNS_EXTERNAL - ${iptables} -t nat -F CLASH_DNS_LOCAL ${iptables} -t nat -X CLASH_DNS_LOCAL if [ -n "${fake_ip_range}" ]; then ${iptables} -t nat -D OUTPUT -p icmp -d "${fake_ip_range}" -j DNAT --to-destination 127.0.0.1 ${iptables} -t nat -D PREROUTING -p icmp -d "${fake_ip_range}" -j DNAT --to-destination 127.0.0.1 - ${iptables} -t nat -D OUTPUT -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 ${iptables} -t nat -D PREROUTING -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1 fi