From 31e29f93cceb82ab3c8d710b4359e5715887dd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Fri, 11 Apr 2025 10:39:23 +0800 Subject: [PATCH] redirect: Remove iptables rules except basic output redirect for Android --- redirect_iptables.go | 202 ------------------------------------------- redirect_linux.go | 5 +- 2 files changed, 2 insertions(+), 205 deletions(-) diff --git a/redirect_iptables.go b/redirect_iptables.go index 59c2d1d..2c6e2e2 100644 --- a/redirect_iptables.go +++ b/redirect_iptables.go @@ -3,12 +3,9 @@ package tun import ( - "net/netip" "os/exec" - "runtime" "strings" - "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" F "github.com/sagernet/sing/common/format" ) @@ -30,10 +27,7 @@ func (r *autoRedirect) setupIPTables() error { } func (r *autoRedirect) setupIPTablesForFamily(iptablesPath string) error { - tableNameInput := r.tableName + "-input" - tableNameForward := r.tableName + "-forward" tableNameOutput := r.tableName + "-output" - tableNamePreRouteing := r.tableName + "-prerouting" redirectPort := r.redirectPort() // OUTPUT err := r.runShell(iptablesPath, "-t nat -N", tableNameOutput) @@ -50,184 +44,6 @@ func (r *autoRedirect) setupIPTablesForFamily(iptablesPath string) error { if err != nil { return err } - if runtime.GOOS == "android" { - return nil - } - // INPUT - err = r.runShell(iptablesPath, "-N", tableNameInput) - if err != nil { - return err - } - err = r.runShell(iptablesPath, "-A", tableNameInput, - "-i", r.tunOptions.Name, "-j", "ACCEPT") - if err != nil { - return err - } - err = r.runShell(iptablesPath, "-A", tableNameInput, - "-o", r.tunOptions.Name, "-j", "ACCEPT") - if err != nil { - return err - } - err = r.runShell(iptablesPath, "-I INPUT -j", tableNameInput) - if err != nil { - return err - } - // FORWARD - err = r.runShell(iptablesPath, "-N", tableNameForward) - if err != nil { - return err - } - err = r.runShell(iptablesPath, "-A", tableNameForward, - "-i", r.tunOptions.Name, "-j", "ACCEPT") - if err != nil { - return err - } - err = r.runShell(iptablesPath, "-A", tableNameForward, - "-o", r.tunOptions.Name, "-j", "ACCEPT") - if err != nil { - return err - } - err = r.runShell(iptablesPath, "-I FORWARD -j", tableNameForward) - if err != nil { - return err - } - // PREROUTING - err = r.runShell(iptablesPath, "-t nat -N", tableNamePreRouteing) - if err != nil { - return err - } - var ( - routeAddress []netip.Prefix - routeExcludeAddress []netip.Prefix - ) - if iptablesPath == r.iptablesPath { - routeAddress = r.tunOptions.Inet4RouteAddress - routeExcludeAddress = r.tunOptions.Inet4RouteExcludeAddress - } else { - routeAddress = r.tunOptions.Inet6RouteAddress - routeExcludeAddress = r.tunOptions.Inet6RouteExcludeAddress - } - if len(routeAddress) > 0 && (len(r.tunOptions.IncludeInterface) > 0 || len(r.tunOptions.IncludeUID) > 0) { - return E.New("`*_route_address` is conflict with `include_interface` or `include_uid`") - } - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-i", r.tunOptions.Name, "-j RETURN") - if err != nil { - return err - } - for _, address := range routeExcludeAddress { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-d", address.String(), "-j RETURN") - if err != nil { - return err - } - } - for _, name := range r.tunOptions.ExcludeInterface { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-i", name, "-j RETURN") - if err != nil { - return err - } - } - for _, uid := range r.tunOptions.ExcludeUID { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-m owner --uid-owner", uid, "-j RETURN") - if err != nil { - return err - } - } - if !r.tunOptions.EXP_DisableDNSHijack { - dnsServer := common.Find(r.tunOptions.DNSServers, func(it netip.Addr) bool { - return it.Is4() == (iptablesPath == r.iptablesPath) - }) - if !dnsServer.IsValid() { - if iptablesPath == r.iptablesPath { - if HasNextAddress(r.tunOptions.Inet4Address[0], 1) { - dnsServer = r.tunOptions.Inet4Address[0].Addr().Next() - } - } else { - if HasNextAddress(r.tunOptions.Inet6Address[0], 1) { - dnsServer = r.tunOptions.Inet6Address[0].Addr().Next() - } - } - } - if dnsServer.IsValid() { - if len(routeAddress) > 0 { - for _, address := range routeAddress { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-d", address.String(), "-p udp --dport 53 -j DNAT --to", dnsServer) - if err != nil { - return err - } - } - } else if len(r.tunOptions.IncludeInterface) > 0 || len(r.tunOptions.IncludeUID) > 0 { - for _, name := range r.tunOptions.IncludeInterface { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-i", name, "-p udp --dport 53 -j DNAT --to", dnsServer) - if err != nil { - return err - } - } - for _, uidRange := range r.tunOptions.IncludeUID { - for uid := uidRange.Start; uid <= uidRange.End; uid++ { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-m owner --uid-owner", uid, "-p udp --dport 53 -j DNAT --to", dnsServer) - if err != nil { - return err - } - } - } - } else { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-p udp --dport 53 -j DNAT --to", dnsServer) - if err != nil { - return err - } - } - } - } - - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, "-m addrtype --dst-type LOCAL -j RETURN") - if err != nil { - return err - } - - if len(routeAddress) > 0 { - for _, address := range routeAddress { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-d", address.String(), "-p tcp -j REDIRECT --to-ports", redirectPort) - if err != nil { - return err - } - } - } else if len(r.tunOptions.IncludeInterface) > 0 || len(r.tunOptions.IncludeUID) > 0 { - for _, name := range r.tunOptions.IncludeInterface { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-i", name, "-p tcp -j REDIRECT --to-ports", redirectPort) - if err != nil { - return err - } - } - for _, uidRange := range r.tunOptions.IncludeUID { - for uid := uidRange.Start; uid <= uidRange.End; uid++ { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-m owner --uid-owner", uid, "-p tcp -j REDIRECT --to-ports", redirectPort) - if err != nil { - return err - } - } - } - } else { - err = r.runShell(iptablesPath, "-t nat -A", tableNamePreRouteing, - "-p tcp -j REDIRECT --to-ports", redirectPort) - if err != nil { - return err - } - } - err = r.runShell(iptablesPath, "-t nat -I PREROUTING -j", tableNamePreRouteing) - if err != nil { - return err - } return nil } @@ -241,29 +57,11 @@ func (r *autoRedirect) cleanupIPTables() { } func (r *autoRedirect) cleanupIPTablesForFamily(iptablesPath string) { - tableNameInput := r.tableName + "-input" tableNameOutput := r.tableName + "-output" - tableNameForward := r.tableName + "-forward" - tableNamePreRouteing := r.tableName + "-prerouting" _ = r.runShell(iptablesPath, "-t nat -D OUTPUT -j", tableNameOutput) _ = r.runShell(iptablesPath, "-t nat -F", tableNameOutput) _ = r.runShell(iptablesPath, "-t nat -X", tableNameOutput) - if runtime.GOOS == "android" { - return - } - - _ = r.runShell(iptablesPath, "-D INPUT -j", tableNameInput) - _ = r.runShell(iptablesPath, "-F", tableNameInput) - _ = r.runShell(iptablesPath, "-X", tableNameInput) - - _ = r.runShell(iptablesPath, "-D FORWARD -j", tableNameForward) - _ = r.runShell(iptablesPath, "-F", tableNameForward) - _ = r.runShell(iptablesPath, "-X", tableNameForward) - - _ = r.runShell(iptablesPath, "-t nat -D PREROUTING -j", tableNamePreRouteing) - _ = r.runShell(iptablesPath, "-t nat -F", tableNamePreRouteing) - _ = r.runShell(iptablesPath, "-t nat -X", tableNamePreRouteing) } func (r *autoRedirect) runShell(commands ...any) error { diff --git a/redirect_linux.go b/redirect_linux.go index 113d6f1..5441bc1 100644 --- a/redirect_linux.go +++ b/redirect_linux.go @@ -83,9 +83,8 @@ func (r *autoRedirect) Start() error { } else { if r.useNFTables { err = r.initializeNFTables() - if err != nil && err != os.ErrInvalid { - r.useNFTables = false - r.logger.Debug("missing nftables support: ", err) + if err != nil { + return E.Cause(err, "missing nftables support") } } if len(r.tunOptions.Inet4Address) > 0 {