Skip to content

Commit

Permalink
chore: Add dns-redirect options to iptables
Browse files Browse the repository at this point in the history
  • Loading branch information
xishang0128 committed Mar 6, 2024
1 parent 974332c commit 823f59b
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 32 deletions.
2 changes: 2 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ type IPTables struct {
Enable bool `yaml:"enable" json:"enable"`
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
Bypass []string `yaml:"bypass" json:"bypass"`
DnsRedirect bool `yaml:"dns-redirect" json:"dns-redirect"`
}

type Sniffer struct {
Expand Down Expand Up @@ -440,6 +441,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
Enable: false,
InboundInterface: "lo",
Bypass: []string{},
DnsRedirect: true,
},
NTP: RawNTP{
Enable: false,
Expand Down
23 changes: 14 additions & 9 deletions hub/executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -478,22 +478,27 @@ func updateIPTables(cfg *config.Config) {
bypass = iptables.Bypass
tProxyPort = cfg.General.TProxyPort
dnsCfg = cfg.DNS
DnsRedirect = iptables.DnsRedirect

dnsPort netip.AddrPort
)

if tProxyPort == 0 {
err = fmt.Errorf("tproxy-port must be greater than zero")
return
}

if !dnsCfg.Enable {
err = fmt.Errorf("DNS server must be enable")
return
}
if DnsRedirect {
if !dnsCfg.Enable {
err = fmt.Errorf("DNS server must be enable")
return
}

dnsPort, err := netip.ParseAddrPort(dnsCfg.Listen)
if err != nil {
err = fmt.Errorf("DNS server must be correct")
return
dnsPort, err = netip.ParseAddrPort(dnsCfg.Listen)
if err != nil {
err = fmt.Errorf("DNS server must be correct")
return
}
}

if iptables.InboundInterface != "" {
Expand All @@ -504,7 +509,7 @@ func updateIPTables(cfg *config.Config) {
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 {
return
}
Expand Down
61 changes: 38 additions & 23 deletions listener/tproxy/tproxy_iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ var (
dnsPort uint16
tProxyPort uint16
interfaceName string
DnsRedirect bool
)

const (
PROXY_FWMARK = "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 {
return fmt.Errorf("current operations system [%s] are not support iptables or command iptables does not exist", runtime.GOOS)
}
Expand All @@ -33,6 +34,7 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1

interfaceName = ifname
tProxyPort = tport
DnsRedirect = dnsredir
dnsPort = dport

// add route
Expand All @@ -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 -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 -p udp --dport 53 -j ACCEPT")
execCmd("iptables -t mangle -A mihomo_prerouting -p tcp --dport 53 -j ACCEPT")
if DnsRedirect {
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 -m addrtype --dst-type LOCAL -j RETURN")
addLocalnetworkToChain("mihomo_prerouting", bypass)
execCmd("iptables -t mangle -A mihomo_prerouting -p tcp -m socket -j mihomo_divert")
Expand All @@ -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("iptables -t mangle -A PREROUTING -j mihomo_prerouting")

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))
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 udp --dport 53 -j REDIRECT --to %d", dnsPort))
}

// set post routing
if interfaceName != "lo" {
Expand All @@ -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 -F mihomo_output")
execCmd(fmt.Sprintf("iptables -t mangle -A mihomo_output -m mark --mark %#x -j RETURN", dialer.DefaultRoutingMark.Load()))
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")
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 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 BROADCAST -j RETURN")
addLocalnetworkToChain("mihomo_output", bypass)
Expand All @@ -90,20 +98,22 @@ func SetTProxyIPTables(ifname string, bypass []string, tport uint16, dport uint1
execCmd(fmt.Sprintf("iptables -t mangle -I OUTPUT -o %s -j mihomo_output", interfaceName))

// set dns output
execCmd("iptables -t nat -N 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("iptables -t nat -A mihomo_dns_output -s 172.17.0.0/16 -j RETURN")
execCmd(fmt.Sprintf("iptables -t nat -A mihomo_dns_output -p udp -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 udp --dport 53 -j mihomo_dns_output")
if DnsRedirect {
execCmd("iptables -t nat -N 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("iptables -t nat -A mihomo_dns_output -s 172.17.0.0/16 -j RETURN")
execCmd(fmt.Sprintf("iptables -t nat -A mihomo_dns_output -p udp -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 udp --dport 53 -j mihomo_dns_output")
}

return nil
}

func CleanupTProxyIPTables() {
if runtime.GOOS != "linux" || interfaceName == "" || tProxyPort == 0 || dnsPort == 0 {
if runtime.GOOS != "linux" || interfaceName == "" || tProxyPort == 0 {
return
}

Expand All @@ -130,8 +140,10 @@ func CleanupTProxyIPTables() {
}

// clean PREROUTING
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))
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 udp --dport 53 -j REDIRECT --to %d", dnsPort))
}
execCmd("iptables -t mangle -D PREROUTING -j mihomo_prerouting")

// clean POSTROUTING
Expand All @@ -141,8 +153,10 @@ func CleanupTProxyIPTables() {

// clean OUTPUT
execCmd(fmt.Sprintf("iptables -t mangle -D OUTPUT -o %s -j mihomo_output", interfaceName))
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")
if DnsRedirect {
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")
}

// clean chain
execCmd("iptables -t mangle -F mihomo_prerouting")
Expand All @@ -151,9 +165,10 @@ func CleanupTProxyIPTables() {
execCmd("iptables -t mangle -X mihomo_divert")
execCmd("iptables -t mangle -F mihomo_output")
execCmd("iptables -t mangle -X mihomo_output")
execCmd("iptables -t nat -F mihomo_dns_output")
execCmd("iptables -t nat -X mihomo_dns_output")

if DnsRedirect {
execCmd("iptables -t nat -F mihomo_dns_output")
execCmd("iptables -t nat -X mihomo_dns_output")
}
interfaceName = ""
tProxyPort = 0
dnsPort = 0
Expand Down

0 comments on commit 823f59b

Please sign in to comment.