mirror of
https://github.com/SagerNet/sing-tun.git
synced 2025-09-27 13:02:08 +08:00
redirect: Remove iptables rules except basic output redirect for Android
This commit is contained in:
@@ -3,12 +3,9 @@
|
|||||||
package tun
|
package tun
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/netip"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/sagernet/sing/common"
|
|
||||||
E "github.com/sagernet/sing/common/exceptions"
|
E "github.com/sagernet/sing/common/exceptions"
|
||||||
F "github.com/sagernet/sing/common/format"
|
F "github.com/sagernet/sing/common/format"
|
||||||
)
|
)
|
||||||
@@ -30,10 +27,7 @@ func (r *autoRedirect) setupIPTables() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *autoRedirect) setupIPTablesForFamily(iptablesPath string) error {
|
func (r *autoRedirect) setupIPTablesForFamily(iptablesPath string) error {
|
||||||
tableNameInput := r.tableName + "-input"
|
|
||||||
tableNameForward := r.tableName + "-forward"
|
|
||||||
tableNameOutput := r.tableName + "-output"
|
tableNameOutput := r.tableName + "-output"
|
||||||
tableNamePreRouteing := r.tableName + "-prerouting"
|
|
||||||
redirectPort := r.redirectPort()
|
redirectPort := r.redirectPort()
|
||||||
// OUTPUT
|
// OUTPUT
|
||||||
err := r.runShell(iptablesPath, "-t nat -N", tableNameOutput)
|
err := r.runShell(iptablesPath, "-t nat -N", tableNameOutput)
|
||||||
@@ -50,184 +44,6 @@ func (r *autoRedirect) setupIPTablesForFamily(iptablesPath string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,29 +57,11 @@ func (r *autoRedirect) cleanupIPTables() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *autoRedirect) cleanupIPTablesForFamily(iptablesPath string) {
|
func (r *autoRedirect) cleanupIPTablesForFamily(iptablesPath string) {
|
||||||
tableNameInput := r.tableName + "-input"
|
|
||||||
tableNameOutput := r.tableName + "-output"
|
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 -D OUTPUT -j", tableNameOutput)
|
||||||
_ = r.runShell(iptablesPath, "-t nat -F", tableNameOutput)
|
_ = r.runShell(iptablesPath, "-t nat -F", tableNameOutput)
|
||||||
_ = r.runShell(iptablesPath, "-t nat -X", 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 {
|
func (r *autoRedirect) runShell(commands ...any) error {
|
||||||
|
@@ -83,9 +83,8 @@ func (r *autoRedirect) Start() error {
|
|||||||
} else {
|
} else {
|
||||||
if r.useNFTables {
|
if r.useNFTables {
|
||||||
err = r.initializeNFTables()
|
err = r.initializeNFTables()
|
||||||
if err != nil && err != os.ErrInvalid {
|
if err != nil {
|
||||||
r.useNFTables = false
|
return E.Cause(err, "missing nftables support")
|
||||||
r.logger.Debug("missing nftables support: ", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(r.tunOptions.Inet4Address) > 0 {
|
if len(r.tunOptions.Inet4Address) > 0 {
|
||||||
|
Reference in New Issue
Block a user