bypass support for auto-iptables

This commit is contained in:
Adlyq 2022-03-23 11:04:43 +08:00
parent 91e83ea955
commit f19b67fe9d
3 changed files with 22 additions and 13 deletions

View file

@ -121,8 +121,9 @@ type Script struct {
// IPTables config
type IPTables struct {
Enable bool `yaml:"enable" json:"enable"`
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
Enable bool `yaml:"enable" json:"enable"`
InboundInterface string `yaml:"inbound-interface" json:"inbound-interface"`
Bypass []string `yaml:"bypass" json:"bypass"`
}
// Experimental config
@ -247,6 +248,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) {
IPTables: IPTables{
Enable: false,
InboundInterface: "lo",
Bypass: []string{},
},
DNS: RawDNS{
Enable: false,

View file

@ -317,6 +317,7 @@ func updateIPTables(cfg *config.Config) {
var (
inboundInterface = "lo"
bypass = iptables.Bypass
tProxyPort = cfg.General.TProxyPort
dnsCfg = cfg.DNS
)
@ -351,7 +352,7 @@ func updateIPTables(cfg *config.Config) {
dialer.DefaultRoutingMark.Store(2158)
}
err = tproxy.SetTProxyIPTables(inboundInterface, uint16(tProxyPort), uint16(dnsPort))
err = tproxy.SetTProxyIPTables(inboundInterface, bypass, uint16(tProxyPort), uint16(dnsPort))
if err != nil {
return
}

View file

@ -3,6 +3,7 @@ package tproxy
import (
"errors"
"fmt"
"net"
"runtime"
"github.com/Dreamacro/clash/common/cmd"
@ -21,9 +22,8 @@ const (
PROXY_ROUTE_TABLE = "0x2d0"
)
func SetTProxyIPTables(ifname string, tport uint16, dport uint16) error {
var err error
if err = execCmd("iptables -V"); err != nil {
func SetTProxyIPTables(ifname string, bypass []string, tport uint16, 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)
}
@ -61,7 +61,7 @@ func SetTProxyIPTables(ifname string, tport uint16, dport uint16) error {
execCmd("iptables -t mangle -A clash_prerouting -p udp --dport 53 -j ACCEPT")
execCmd("iptables -t mangle -A clash_prerouting -p tcp --dport 53 -j ACCEPT")
execCmd("iptables -t mangle -A clash_prerouting -m addrtype --dst-type LOCAL -j RETURN")
addLocalnetworkToChain("clash_prerouting")
addLocalnetworkToChain("clash_prerouting", bypass)
execCmd("iptables -t mangle -A clash_prerouting -p tcp -m socket -j clash_divert")
execCmd("iptables -t mangle -A clash_prerouting -p udp -m socket -j clash_divert")
execCmd(fmt.Sprintf("iptables -t mangle -A clash_prerouting -p tcp -j TPROXY --on-port %d --tproxy-mark %s/%s", tProxyPort, PROXY_FWMARK, PROXY_FWMARK))
@ -84,7 +84,7 @@ func SetTProxyIPTables(ifname string, tport uint16, dport uint16) error {
execCmd("iptables -t mangle -A clash_output -p tcp --dport 53 -j ACCEPT")
execCmd("iptables -t mangle -A clash_output -m addrtype --dst-type LOCAL -j RETURN")
execCmd("iptables -t mangle -A clash_output -m addrtype --dst-type BROADCAST -j RETURN")
addLocalnetworkToChain("clash_output")
addLocalnetworkToChain("clash_output", bypass)
execCmd(fmt.Sprintf("iptables -t mangle -A clash_output -p tcp -j MARK --set-mark %s", PROXY_FWMARK))
execCmd(fmt.Sprintf("iptables -t mangle -A clash_output -p udp -j MARK --set-mark %s", PROXY_FWMARK))
execCmd(fmt.Sprintf("iptables -t mangle -I OUTPUT -o %s -j clash_output", interfaceName))
@ -113,7 +113,7 @@ func CleanupTProxyIPTables() {
dialer.DefaultRoutingMark.Store(0)
}
if err := execCmd("iptables -t mangle -L clash_divert"); err != nil {
if _, err := cmd.ExecCmd("iptables -t mangle -L clash_divert"); err != nil {
return
}
@ -159,7 +159,15 @@ func CleanupTProxyIPTables() {
dnsPort = 0
}
func addLocalnetworkToChain(chain string) {
func addLocalnetworkToChain(chain string, bypass []string) {
for _, bp := range bypass {
_, _, err := net.ParseCIDR(bp)
if err != nil {
log.Warnln("[IPTABLES] %s", err)
continue
}
execCmd(fmt.Sprintf("iptables -t mangle -A %s -d %s -j RETURN", chain, bp))
}
execCmd(fmt.Sprintf("iptables -t mangle -A %s -d 0.0.0.0/8 -j RETURN", chain))
execCmd(fmt.Sprintf("iptables -t mangle -A %s -d 10.0.0.0/8 -j RETURN", chain))
execCmd(fmt.Sprintf("iptables -t mangle -A %s -d 100.64.0.0/10 -j RETURN", chain))
@ -177,13 +185,11 @@ func addLocalnetworkToChain(chain string) {
execCmd(fmt.Sprintf("iptables -t mangle -A %s -d 255.255.255.255/32 -j RETURN", chain))
}
func execCmd(cmdStr string) error {
func execCmd(cmdStr string) {
log.Debugln("[IPTABLES] %s", cmdStr)
_, err := cmd.ExecCmd(cmdStr)
if err != nil {
log.Warnln("[IPTABLES] exec cmd: %v", err)
}
return err
}