chore: Add dns-redirect options to iptables

This commit is contained in:
xishang0128 2024-03-07 00:52:20 +08:00
parent 974332c0cc
commit 823f59b5c7
No known key found for this signature in database
GPG Key ID: 44A1E10B5ADF68CB
3 changed files with 54 additions and 32 deletions

View File

@ -152,6 +152,7 @@ type IPTables struct {
Enable bool `yaml:"enable" json:"enable"` Enable bool `yaml:"enable" json:"enable"`
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"` InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
Bypass []string `yaml:"bypass" json:"bypass"` Bypass []string `yaml:"bypass" json:"bypass"`
DnsRedirect bool `yaml:"dns-redirect" json:"dns-redirect"`
} }
type Sniffer struct { type Sniffer struct {
@ -440,6 +441,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
Enable: false, Enable: false,
InboundInterface: "lo", InboundInterface: "lo",
Bypass: []string{}, Bypass: []string{},
DnsRedirect: true,
}, },
NTP: RawNTP{ NTP: RawNTP{
Enable: false, Enable: false,

View File

@ -478,6 +478,9 @@ func updateIPTables(cfg *config.Config) {
bypass = iptables.Bypass bypass = iptables.Bypass
tProxyPort = cfg.General.TProxyPort tProxyPort = cfg.General.TProxyPort
dnsCfg = cfg.DNS dnsCfg = cfg.DNS
DnsRedirect = iptables.DnsRedirect
dnsPort netip.AddrPort
) )
if tProxyPort == 0 { if tProxyPort == 0 {
@ -485,16 +488,18 @@ func updateIPTables(cfg *config.Config) {
return return
} }
if DnsRedirect {
if !dnsCfg.Enable { if !dnsCfg.Enable {
err = fmt.Errorf("DNS server must be enable") err = fmt.Errorf("DNS server must be enable")
return return
} }
dnsPort, err := netip.ParseAddrPort(dnsCfg.Listen) dnsPort, err = netip.ParseAddrPort(dnsCfg.Listen)
if err != nil { if err != nil {
err = fmt.Errorf("DNS server must be correct") err = fmt.Errorf("DNS server must be correct")
return return
} }
}
if iptables.InboundInterface != "" { if iptables.InboundInterface != "" {
inboundInterface = iptables.InboundInterface inboundInterface = iptables.InboundInterface
@ -504,7 +509,7 @@ func updateIPTables(cfg *config.Config) {
dialer.DefaultRoutingMark.Store(2158) dialer.DefaultRoutingMark.Store(2158)
} }
err = tproxy.SetTProxyIPTables(inboundInterface, bypass, uint16(tProxyPort), dnsPort.Port()) err = tproxy.SetTProxyIPTables(inboundInterface, bypass, uint16(tProxyPort), DnsRedirect, dnsPort.Port())
if err != nil { if err != nil {
return return
} }

View File

@ -15,6 +15,7 @@ var (
dnsPort uint16 dnsPort uint16
tProxyPort uint16 tProxyPort uint16
interfaceName string interfaceName string
DnsRedirect bool
) )
const ( const (
@ -22,7 +23,7 @@ const (
PROXY_ROUTE_TABLE = "0x2d0" PROXY_ROUTE_TABLE = "0x2d0"
) )
func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint16) error { func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dnsredir bool, dport uint16) error {
if _, err := cmd.ExecCmd("iptables -V"); err != nil { if _, err := cmd.ExecCmd("iptables -V"); err != nil {
return fmt.Errorf("current operations system [%s] are not support iptables or command iptables does not exist", runtime.GOOS) return fmt.Errorf("current operations system [%s] are not support iptables or command iptables does not exist", runtime.GOOS)
} }
@ -33,6 +34,7 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
interfaceName = ifname interfaceName = ifname
tProxyPort = tport tProxyPort = tport
DnsRedirect = dnsredir
dnsPort = dport dnsPort = dport
// add route // add route
@ -58,8 +60,10 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
execCmd("iptables -t mangle -N mihomo_prerouting") execCmd("iptables -t mangle -N mihomo_prerouting")
execCmd("iptables -t mangle -F mihomo_prerouting") execCmd("iptables -t mangle -F mihomo_prerouting")
execCmd("iptables -t mangle -A mihomo_prerouting -s 172.17.0.0/16 -j RETURN") execCmd("iptables -t mangle -A mihomo_prerouting -s 172.17.0.0/16 -j RETURN")
if DnsRedirect {
execCmd("iptables -t mangle -A mihomo_prerouting -p udp --dport 53 -j ACCEPT") execCmd("iptables -t mangle -A mihomo_prerouting -p udp --dport 53 -j ACCEPT")
execCmd("iptables -t mangle -A mihomo_prerouting -p tcp --dport 53 -j ACCEPT") execCmd("iptables -t mangle -A mihomo_prerouting -p tcp --dport 53 -j ACCEPT")
}
execCmd("iptables -t mangle -A mihomo_prerouting -m addrtype --dst-type LOCAL -j RETURN") execCmd("iptables -t mangle -A mihomo_prerouting -m addrtype --dst-type LOCAL -j RETURN")
addLocalnetworkToChain("mihomo_prerouting", bypass) addLocalnetworkToChain("mihomo_prerouting", bypass)
execCmd("iptables -t mangle -A mihomo_prerouting -p tcp -m socket -j mihomo_divert") execCmd("iptables -t mangle -A mihomo_prerouting -p tcp -m socket -j mihomo_divert")
@ -68,8 +72,10 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
execCmd(fmt.Sprintf("iptables -t mangle -A mihomo_prerouting -p udp -j TPROXY --on-port %d --tproxy-mark %s/%s", tProxyPort, PROXY_FWMARK, PROXY_FWMARK)) execCmd(fmt.Sprintf("iptables -t mangle -A mihomo_prerouting -p udp -j TPROXY --on-port %d --tproxy-mark %s/%s", tProxyPort, PROXY_FWMARK, PROXY_FWMARK))
execCmd("iptables -t mangle -A PREROUTING -j mihomo_prerouting") execCmd("iptables -t mangle -A PREROUTING -j mihomo_prerouting")
if DnsRedirect {
execCmd(fmt.Sprintf("iptables -t nat -I PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p tcp --dport 53 -j REDIRECT --to %d", dnsPort)) execCmd(fmt.Sprintf("iptables -t nat -I PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p tcp --dport 53 -j REDIRECT --to %d", dnsPort))
execCmd(fmt.Sprintf("iptables -t nat -I PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p udp --dport 53 -j REDIRECT --to %d", dnsPort)) execCmd(fmt.Sprintf("iptables -t nat -I PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p udp --dport 53 -j REDIRECT --to %d", dnsPort))
}
// set post routing // set post routing
if interfaceName != "lo" { if interfaceName != "lo" {
@ -80,8 +86,10 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
execCmd("iptables -t mangle -N mihomo_output") execCmd("iptables -t mangle -N mihomo_output")
execCmd("iptables -t mangle -F mihomo_output") execCmd("iptables -t mangle -F mihomo_output")
execCmd(fmt.Sprintf("iptables -t mangle -A mihomo_output -m mark --mark %#x -j RETURN", dialer.DefaultRoutingMark.Load())) execCmd(fmt.Sprintf("iptables -t mangle -A mihomo_output -m mark --mark %#x -j RETURN", dialer.DefaultRoutingMark.Load()))
if DnsRedirect {
execCmd("iptables -t mangle -A mihomo_output -p udp -m multiport --dports 53,123,137 -j ACCEPT") execCmd("iptables -t mangle -A mihomo_output -p udp -m multiport --dports 53,123,137 -j ACCEPT")
execCmd("iptables -t mangle -A mihomo_output -p tcp --dport 53 -j ACCEPT") execCmd("iptables -t mangle -A mihomo_output -p tcp --dport 53 -j ACCEPT")
}
execCmd("iptables -t mangle -A mihomo_output -m addrtype --dst-type LOCAL -j RETURN") execCmd("iptables -t mangle -A mihomo_output -m addrtype --dst-type LOCAL -j RETURN")
execCmd("iptables -t mangle -A mihomo_output -m addrtype --dst-type BROADCAST -j RETURN") execCmd("iptables -t mangle -A mihomo_output -m addrtype --dst-type BROADCAST -j RETURN")
addLocalnetworkToChain("mihomo_output", bypass) addLocalnetworkToChain("mihomo_output", bypass)
@ -90,6 +98,7 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
execCmd(fmt.Sprintf("iptables -t mangle -I OUTPUT -o %s -j mihomo_output", interfaceName)) execCmd(fmt.Sprintf("iptables -t mangle -I OUTPUT -o %s -j mihomo_output", interfaceName))
// set dns output // set dns output
if DnsRedirect {
execCmd("iptables -t nat -N mihomo_dns_output") execCmd("iptables -t nat -N mihomo_dns_output")
execCmd("iptables -t nat -F mihomo_dns_output") execCmd("iptables -t nat -F mihomo_dns_output")
execCmd(fmt.Sprintf("iptables -t nat -A mihomo_dns_output -m mark --mark %#x -j RETURN", dialer.DefaultRoutingMark.Load())) execCmd(fmt.Sprintf("iptables -t nat -A mihomo_dns_output -m mark --mark %#x -j RETURN", dialer.DefaultRoutingMark.Load()))
@ -98,12 +107,13 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
execCmd(fmt.Sprintf("iptables -t nat -A mihomo_dns_output -p tcp -j REDIRECT --to-ports %d", dnsPort)) execCmd(fmt.Sprintf("iptables -t nat -A mihomo_dns_output -p tcp -j REDIRECT --to-ports %d", dnsPort))
execCmd("iptables -t nat -I OUTPUT -p tcp --dport 53 -j mihomo_dns_output") execCmd("iptables -t nat -I OUTPUT -p tcp --dport 53 -j mihomo_dns_output")
execCmd("iptables -t nat -I OUTPUT -p udp --dport 53 -j mihomo_dns_output") execCmd("iptables -t nat -I OUTPUT -p udp --dport 53 -j mihomo_dns_output")
}
return nil return nil
} }
func CleanupTProxyIPTables() { func CleanupTProxyIPTables() {
if runtime.GOOS != "linux" || interfaceName == "" || tProxyPort == 0 || dnsPort == 0 { if runtime.GOOS != "linux" || interfaceName == "" || tProxyPort == 0 {
return return
} }
@ -130,8 +140,10 @@ func CleanupTProxyIPTables() {
} }
// clean PREROUTING // clean PREROUTING
if DnsRedirect {
execCmd(fmt.Sprintf("iptables -t nat -D PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p tcp --dport 53 -j REDIRECT --to %d", dnsPort)) execCmd(fmt.Sprintf("iptables -t nat -D PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p tcp --dport 53 -j REDIRECT --to %d", dnsPort))
execCmd(fmt.Sprintf("iptables -t nat -D PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p udp --dport 53 -j REDIRECT --to %d", dnsPort)) execCmd(fmt.Sprintf("iptables -t nat -D PREROUTING ! -s 172.17.0.0/16 ! -d 127.0.0.0/8 -p udp --dport 53 -j REDIRECT --to %d", dnsPort))
}
execCmd("iptables -t mangle -D PREROUTING -j mihomo_prerouting") execCmd("iptables -t mangle -D PREROUTING -j mihomo_prerouting")
// clean POSTROUTING // clean POSTROUTING
@ -141,8 +153,10 @@ func CleanupTProxyIPTables() {
// clean OUTPUT // clean OUTPUT
execCmd(fmt.Sprintf("iptables -t mangle -D OUTPUT -o %s -j mihomo_output", interfaceName)) execCmd(fmt.Sprintf("iptables -t mangle -D OUTPUT -o %s -j mihomo_output", interfaceName))
if DnsRedirect {
execCmd("iptables -t nat -D OUTPUT -p tcp --dport 53 -j mihomo_dns_output") execCmd("iptables -t nat -D OUTPUT -p tcp --dport 53 -j mihomo_dns_output")
execCmd("iptables -t nat -D OUTPUT -p udp --dport 53 -j mihomo_dns_output") execCmd("iptables -t nat -D OUTPUT -p udp --dport 53 -j mihomo_dns_output")
}
// clean chain // clean chain
execCmd("iptables -t mangle -F mihomo_prerouting") execCmd("iptables -t mangle -F mihomo_prerouting")
@ -151,9 +165,10 @@ func CleanupTProxyIPTables() {
execCmd("iptables -t mangle -X mihomo_divert") execCmd("iptables -t mangle -X mihomo_divert")
execCmd("iptables -t mangle -F mihomo_output") execCmd("iptables -t mangle -F mihomo_output")
execCmd("iptables -t mangle -X mihomo_output") execCmd("iptables -t mangle -X mihomo_output")
if DnsRedirect {
execCmd("iptables -t nat -F mihomo_dns_output") execCmd("iptables -t nat -F mihomo_dns_output")
execCmd("iptables -t nat -X mihomo_dns_output") execCmd("iptables -t nat -X mihomo_dns_output")
}
interfaceName = "" interfaceName = ""
tProxyPort = 0 tProxyPort = 0
dnsPort = 0 dnsPort = 0