From 54296bf16164098e4d25f11c540826601f091738 Mon Sep 17 00:00:00 2001 From: DaTekShaman Date: Sat, 27 Dec 2025 16:53:07 +0300 Subject: [PATCH] Refactor cleanup process in iptables setup script for improved robustness and clarity --- scripts/iptables-mihomo-setup.sh | 111 +++++++++++++------------------ 1 file changed, 47 insertions(+), 64 deletions(-) diff --git a/scripts/iptables-mihomo-setup.sh b/scripts/iptables-mihomo-setup.sh index f593d92..54a7eea 100644 --- a/scripts/iptables-mihomo-setup.sh +++ b/scripts/iptables-mihomo-setup.sh @@ -5,12 +5,11 @@ set -euo pipefail # Config # ---------------------------- MIHOMO_UID="mihomo" -REDIR_PORT="7892" # mihomo redir-port (NAT REDIRECT for TCP) -TPROXY_PORT="7893" # mihomo tproxy-port (TPROXY for TCP/UDP) +REDIR_PORT="7892" # TCP Redirect +TPROXY_PORT="7893" # UDP/TCP TProxy FW_MARK="0x1" ROUTE_TABLE="100" -# Interfaces to EXCLUDE completely from interception EXCLUDE_IFACES=("tun0" "wg0") # ---------------------------- @@ -18,131 +17,115 @@ EXCLUDE_IFACES=("tun0" "wg0") # ---------------------------- ipt() { iptables "$@"; } -# Функция для удаления правил по комментарию -cleanup_rules() { - local table="$1" - local chain="$2" - local comment="$3" - - # Добавлено "|| true" к grep, чтобы скрипт не падал, если правил нет (пустой grep возвращает 1) - iptables -t "$table" -nL "$chain" --line-numbers 2>/dev/null | \ - grep "$comment" || true | \ - sort -r | \ - awk '{print $1}' | \ - while read -r line; do - # Проверка на пустую строку, на случай если grep ничего не нашел - if [[ -n "$line" ]]; then - echo "Deleting rule $line from $table/$chain..." - iptables -t "$table" -D "$chain" "$line" - fi +# Надежная функция удаления: Пытается удалить правило, пока iptables не скажет "нет такого правила" +# $1=table, $2=chain, $3=args (часть правила для матчинга) +del_loop() { + local table=$1 + local chain=$2 + shift 2 + local rule_args="$@" + + # Пока проверка (-C) успешна, делаем удаление (-D) + while iptables -t "$table" -C "$chain" $rule_args 2>/dev/null; do + echo "Deleting from $table/$chain: $rule_args" + iptables -t "$table" -D "$chain" $rule_args done } ensure_ip_rule() { - # Clean up ip rules first while ip rule list | grep -q "fwmark ${FW_MARK} lookup ${ROUTE_TABLE}"; do ip rule del fwmark ${FW_MARK} lookup ${ROUTE_TABLE} || true done - ip rule add fwmark ${FW_MARK} lookup ${ROUTE_TABLE} - # Route table entry, forced ip route replace local 0.0.0.0/0 dev lo table ${ROUTE_TABLE} } # ---------------------------- # CLEANUP PHASE # ---------------------------- -echo "Cleaning up old rules..." +echo "--- Cleaning up old rules (Robust Mode) ---" -# 1. Clean MANGLE references -cleanup_rules mangle OUTPUT "MIHOMO-MARK" -cleanup_rules mangle OUTPUT "MIHOMO-EXCLUDE" -cleanup_rules mangle PREROUTING "MIHOMO-JUMP" -cleanup_rules mangle PREROUTING "MIHOMO-EXCLUDE" +# 1. Удаляем ссылки (JUMP) на наши цепочки +del_loop nat OUTPUT -p tcp -m comment --comment "MIHOMO-JUMP" -j MIHOMO_REDIR +del_loop nat PREROUTING -i wt0 -p tcp -m comment --comment "MIHOMO-REDIRECT" -j REDIRECT --to-port "${REDIR_PORT}" +del_loop mangle PREROUTING -i wt0 -m comment --comment "MIHOMO-JUMP" -j MIHOMO_TPROXY -# 2. Clean NAT references -cleanup_rules nat OUTPUT "MIHOMO-JUMP" -cleanup_rules nat OUTPUT "MIHOMO-EXCLUDE" -cleanup_rules nat PREROUTING "MIHOMO-REDIRECT" +# 2. Удаляем исключения (EXCLUDE) и маркеры (MARK) +# Mangle OUTPUT +del_loop mangle OUTPUT -p tcp -m comment --comment "MIHOMO-MARK" -j MARK --set-mark "${FW_MARK}" +del_loop mangle OUTPUT -p udp -m comment --comment "MIHOMO-MARK" -j MARK --set-mark "${FW_MARK}" -# 3. Flush and Delete Chains +for IFACE in "${EXCLUDE_IFACES[@]}"; do + del_loop mangle OUTPUT -o "${IFACE}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN + del_loop mangle PREROUTING -i "${IFACE}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN + del_loop nat OUTPUT -o "${IFACE}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN +done + +del_loop mangle OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN +del_loop nat OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN + +# 3. Теперь, когда ссылок нет, можно безопасно удалить цепочки +# Сначала сбрасываем содержимое (-F), потом удаляем саму цепочку (-X) ipt -t mangle -F MIHOMO_TPROXY 2>/dev/null || true ipt -t mangle -X MIHOMO_TPROXY 2>/dev/null || true ipt -t nat -F MIHOMO_REDIR 2>/dev/null || true ipt -t nat -X MIHOMO_REDIR 2>/dev/null || true -# ---------------------------- -# NAT (REDIRECT) part (TCP only) -# ---------------------------- -echo "Applying NAT rules..." +echo "--- Cleanup finished. Applying new rules ---" +# ---------------------------- +# NAT (REDIRECT) - TCP +# ---------------------------- ipt -t nat -N MIHOMO_REDIR -# Exclude private networks +# Local exclusions inside chain ipt -t nat -A MIHOMO_REDIR -d 192.168.0.0/16 -j RETURN ipt -t nat -A MIHOMO_REDIR -d 10.0.0.0/8 -j RETURN ipt -t nat -A MIHOMO_REDIR -d 172.16.0.0/12 -j RETURN ipt -t nat -A MIHOMO_REDIR -d 127.0.0.0/8 -j RETURN - -# Everything else TCP -> REDIRECT ipt -t nat -A MIHOMO_REDIR -p tcp -j REDIRECT --to-ports "${REDIR_PORT}" -# --- APPLY TO OUTPUT (Local Traffic) --- -# Exclude traffic going via tunnels (tun0/wg0) +# Apply to OUTPUT (Local) for IFACE in "${EXCLUDE_IFACES[@]}"; do ipt -t nat -A OUTPUT -o "${IFACE}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN done - -# Exclude mihomo user ipt -t nat -A OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN - -# Redirect remaining TCP ipt -t nat -A OUTPUT -p tcp -m comment --comment "MIHOMO-JUMP" -j MIHOMO_REDIR -# --- APPLY TO INGRESS (wt0) --- +# Apply to PREROUTING (wt0 Ingress) - Force Redir ipt -t nat -A PREROUTING -i wt0 -p tcp -m comment --comment "MIHOMO-REDIRECT" -j REDIRECT --to-port "${REDIR_PORT}" - # ---------------------------- -# MANGLE (TPROXY) part (TCP+UDP) +# MANGLE (TPROXY) - UDP/TCP # ---------------------------- -echo "Applying TPROXY rules..." - ensure_ip_rule - ipt -t mangle -N MIHOMO_TPROXY -# Exclude private networks +# Local exclusions inside chain ipt -t mangle -A MIHOMO_TPROXY -d 192.168.0.0/16 -j RETURN ipt -t mangle -A MIHOMO_TPROXY -d 10.0.0.0/8 -j RETURN ipt -t mangle -A MIHOMO_TPROXY -d 172.16.0.0/12 -j RETURN ipt -t mangle -A MIHOMO_TPROXY -d 127.0.0.0/8 -j RETURN -# TPROXY Target +# TProxy Targets ipt -t mangle -A MIHOMO_TPROXY -p tcp -j TPROXY --on-port "${TPROXY_PORT}" --tproxy-mark "${FW_MARK}/${FW_MARK}" ipt -t mangle -A MIHOMO_TPROXY -p udp -j TPROXY --on-port "${TPROXY_PORT}" --tproxy-mark "${FW_MARK}/${FW_MARK}" -# --- APPLY TO OUTPUT (Local Traffic) --- -# Exclude tunnels +# Apply to OUTPUT (Local) for IFACE in "${EXCLUDE_IFACES[@]}"; do ipt -t mangle -A OUTPUT -o "${IFACE}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN done - -# Exclude mihomo user ipt -t mangle -A OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN -# Mark remaining traffic for Policy Routing +# Mark packets ipt -t mangle -A OUTPUT -p tcp -m comment --comment "MIHOMO-MARK" -j MARK --set-mark "${FW_MARK}" ipt -t mangle -A OUTPUT -p udp -m comment --comment "MIHOMO-MARK" -j MARK --set-mark "${FW_MARK}" -# --- APPLY TO INGRESS (wt0) --- -# Exclude tunnels (ingress logic) +# Apply to PREROUTING (wt0 Ingress) for IFACE in "${EXCLUDE_IFACES[@]}"; do ipt -t mangle -A PREROUTING -i "${IFACE}" -m comment --comment "MIHOMO-EXCLUDE" -j RETURN done - -# Jump wt0 traffic to TPROXY chain ipt -t mangle -A PREROUTING -i wt0 -m comment --comment "MIHOMO-JUMP" -j MIHOMO_TPROXY echo "Done." \ No newline at end of file