From ce1cf4407c04ef18a0384a317997713f563715de Mon Sep 17 00:00:00 2001 From: DaTekShaman Date: Sat, 27 Dec 2025 16:19:22 +0300 Subject: [PATCH] Upd --- scripts/iptables-mihomo-setup.sh | 198 ++++++++++++++++--------------- 1 file changed, 100 insertions(+), 98 deletions(-) diff --git a/scripts/iptables-mihomo-setup.sh b/scripts/iptables-mihomo-setup.sh index cc3ac33..3205e6a 100644 --- a/scripts/iptables-mihomo-setup.sh +++ b/scripts/iptables-mihomo-setup.sh @@ -5,7 +5,6 @@ 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) FW_MARK="0x1" @@ -19,129 +18,132 @@ EXCLUDE_IFACES=("tun0" "wg0") # ---------------------------- ipt() { iptables "$@"; } -del_jump_all() { - local table="$1" chain="$2" target="$3" - # Delete all rules in $chain that jump to $target (repeat until none left) - while iptables -t "$table" -C "$chain" -j "$target" 2>/dev/null; do - iptables -t "$table" -D "$chain" -j "$target" - done -} - -del_jump_iface_all() { - local table="$1" chain="$2" iface="$3" target="$4" - while iptables -t "$table" -C "$chain" -i "$iface" -j "$target" 2>/dev/null; do - iptables -t "$table" -D "$chain" -i "$iface" -j "$target" +# Функция для удаления правил по комментарию (чтобы не тереть чужое) +# Используем trick: добавляем комментарий ко всем правилам, чтобы потом их найти и удалить +cleanup_rules() { + local table="$1" + local chain="$2" + local comment="$3" + + # List rules with line numbers, grep by comment, sort reverse order (to delete safely), delete + iptables -t "$table" -nL "$chain" --line-numbers 2>/dev/null | \ + grep "$comment" | \ + sort -r | \ + awk '{print $1}' | \ + while read -r line; do + echo "Deleting rule $line from $table/$chain..." + iptables -t "$table" -D "$chain" "$line" done } ensure_ip_rule() { - # Remove duplicates if any (doesn't error if absent) + # 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} } # ---------------------------- -# NAT (REDIRECT) part (TCP only) +# CLEANUP PHASE # ---------------------------- +echo "Cleaning up old rules..." -# Cleanup old chains (ignore if absent) -ipt -t nat -F MIHOMO_REDIR 2>/dev/null || true -ipt -t nat -X MIHOMO_REDIR 2>/dev/null || true +# 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" -# NOTE: Your original script flushes OUTPUT table nat globally. -# Keeping behavior to match your current approach, but yes, it nukes other rules. -ipt -t nat -F OUTPUT 2>/dev/null || true +# 2. Clean NAT references +cleanup_rules nat OUTPUT "MIHOMO-JUMP" +cleanup_rules nat OUTPUT "MIHOMO-EXCLUDE" +cleanup_rules nat PREROUTING "MIHOMO-REDIRECT" -del_jump_all nat OUTPUT MIHOMO_REDIR - -# Create chain -ipt -t nat -N MIHOMO_REDIR - -# Exclude loopback and local subnets -# ipt -t nat -A MIHOMO_REDIR -d 127.0.0.0/8 -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 192.168.0.0/16 -j RETURN - -# Exclude traffic that is going via tun0/wg0 (your "do not touch" tunnels) -for IFACE in "${EXCLUDE_IFACES[@]}"; do - ipt -t nat -A OUTPUT -o "${IFACE}" -j RETURN 2>/dev/null || true -done - -# Exclude mihomo's own traffic by UID -ipt -t nat -C OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -j RETURN 2>/dev/null || \ -ipt -t nat -I OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -j RETURN - -# Everything else TCP -> REDIRECT to mihomo -ipt -t nat -A MIHOMO_REDIR -p tcp -j REDIRECT --to-ports "${REDIR_PORT}" - -# Apply to local OUTPUT TCP -ipt -t nat -C OUTPUT -p tcp -j MIHOMO_REDIR 2>/dev/null || \ -ipt -t nat -A OUTPUT -p tcp -j MIHOMO_REDIR - -# Apply to traffic coming from NetBird interface (ingress) -# Exclude tun0/wg0 by design: only target wt0 here. -ipt -t nat -C PREROUTING -i wt0 -p tcp -j REDIRECT --to-port "${REDIR_PORT}" 2>/dev/null || \ -ipt -t nat -A PREROUTING -i wt0 -p tcp -j REDIRECT --to-port "${REDIR_PORT}" - -# IMPORTANT: -# Removed your old rule "PREROUTING -i wg0 ... REDIRECT" -# because you explicitly asked to exclude wg0 from routing/interception. - -# ---------------------------- -# MANGLE (TPROXY) part (TCP+UDP typically) -# ---------------------------- - -ensure_ip_rule - -# Cleanup old chains +# 3. Flush and Delete Chains +# Now that references are gone, we can safely kill the chains ipt -t mangle -F MIHOMO_TPROXY 2>/dev/null || true ipt -t mangle -X MIHOMO_TPROXY 2>/dev/null || true -del_jump_iface_all mangle PREROUTING wt0 MIHOMO_TPROXY +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..." + +ipt -t nat -N MIHOMO_REDIR + +# Exclude private networks +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) +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) --- +# Exclude wt0 -> tun0/wg0 logic handled by routing mostly, but let's be safe if needed. +# For now, strictly redirect TCP incoming on wt0 +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) +# ---------------------------- +echo "Applying TPROXY rules..." + +ensure_ip_rule -# Create chain ipt -t mangle -N MIHOMO_TPROXY -# Exclusions: loopback/local subnets -ipt -t mangle -A MIHOMO_TPROXY -d 127.0.0.0/8 -j RETURN +# Exclude private networks +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 192.168.0.0/16 -j RETURN - -# Exclude traffic arriving from tun0/wg0 (ingress side) -for IFACE in "${EXCLUDE_IFACES[@]}"; do - ipt -t mangle -A PREROUTING -i "${IFACE}" -j RETURN 2>/dev/null || true -done - -# Exclude traffic leaving via tun0/wg0 (local OUTPUT side) -for IFACE in "${EXCLUDE_IFACES[@]}"; do - ipt -t mangle -C OUTPUT -o "${IFACE}" -j RETURN 2>/dev/null || \ - ipt -t mangle -I OUTPUT -o "${IFACE}" -j RETURN -done - -# Exclude mihomo's own traffic (OUTPUT) so it doesn't eat itself -ipt -t mangle -C OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -j RETURN 2>/dev/null || \ -ipt -t mangle -I OUTPUT -m owner --uid-owner "${MIHOMO_UID}" -j RETURN - -# --- TPROXY for local VM traffic (OUTPUT) --- -# Mark TCP/UDP so policy routing sends them to lo (where mihomo tproxy listens) -ipt -t mangle -C OUTPUT -p tcp -j MARK --set-mark "${FW_MARK}" 2>/dev/null || \ -ipt -t mangle -A OUTPUT -p tcp -j MARK --set-mark "${FW_MARK}" - -ipt -t mangle -C OUTPUT -p udp -j MARK --set-mark "${FW_MARK}" 2>/dev/null || \ -ipt -t mangle -A OUTPUT -p udp -j MARK --set-mark "${FW_MARK}" - -# --- TPROXY for wt0 ingress traffic (PREROUTING) --- -# First run through our exclusions, then TPROXY it. -ipt -t mangle -C PREROUTING -i wt0 -j MIHOMO_TPROXY 2>/dev/null || \ -ipt -t mangle -A PREROUTING -i wt0 -j MIHOMO_TPROXY +ipt -t mangle -A MIHOMO_TPROXY -d 127.0.0.0/8 -j RETURN +# TPROXY Target 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 +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 +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) +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