[skip ci]

# Conflicts:
#	.github/workflows/linter.yml
#	.github/workflows/release.yml
#	config/config.go
#	go.mod
#	go.sum
#	hub/executor/executor.go
This commit is contained in:
MetaCubeX
2022-03-23 00:46:37 +08:00
14 changed files with 165 additions and 107 deletions

View File

@ -310,7 +310,7 @@ func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.P
log.Infoln("Mixed(http+socks) proxy listening at: %s", mixedListener.Address())
}
func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
func ReCreateTun(tunConf *config.Tun, dnsCfg *config.DNS, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) {
tunMux.Lock()
defer tunMux.Unlock()
@ -330,7 +330,7 @@ func ReCreateTun(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *
if !tunConf.Enable {
return
}
tunStackListener, err = tun.New(tunConf, tcpIn, udpIn)
tunStackListener, err = tun.New(tunConf, dnsCfg, tcpIn, udpIn)
if err != nil {
log.Warnln("Failed to start TUN interface: %s", err.Error())
}

View File

@ -11,9 +11,9 @@ import (
)
var (
dnsPort = 0
tProxyPort = 0
interfaceName = ""
dnsPort uint16
tProxyPort uint16
interfaceName string
)
const (
@ -21,7 +21,7 @@ const (
PROXY_ROUTE_TABLE = "0x2d0"
)
func SetTProxyLinuxIPTables(ifname string, tport int, dport int) error {
func SetTProxyIPTables(ifname string, tport uint16, dport uint16) error {
var err error
if err = execCmd("iptables -V"); err != nil {
return fmt.Errorf("current operations system [%s] are not support iptables or command iptables does not exist", runtime.GOOS)
@ -40,11 +40,13 @@ func SetTProxyLinuxIPTables(ifname string, tport int, dport int) error {
execCmd(fmt.Sprintf("ip -f inet route add local default dev %s table %s", interfaceName, PROXY_ROUTE_TABLE))
// set FORWARD
execCmd("sysctl -w net.ipv4.ip_forward=1")
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -o %s -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -o %s -j ACCEPT", interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -i %s ! -o %s -j ACCEPT", interfaceName, interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -i %s -o %s -j ACCEPT", interfaceName, interfaceName))
if interfaceName != "lo" {
execCmd("sysctl -w net.ipv4.ip_forward=1")
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -o %s -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -o %s -j ACCEPT", interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -i %s ! -o %s -j ACCEPT", interfaceName, interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -A FORWARD -i %s -o %s -j ACCEPT", interfaceName, interfaceName))
}
// set clash divert
execCmd("iptables -t mangle -N clash_divert")
@ -70,7 +72,9 @@ func SetTProxyLinuxIPTables(ifname string, tport int, dport int) error {
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
execCmd(fmt.Sprintf("iptables -t nat -A POSTROUTING -o %s -m addrtype ! --src-type LOCAL -j MASQUERADE", interfaceName))
if interfaceName != "lo" {
execCmd(fmt.Sprintf("iptables -t nat -A POSTROUTING -o %s -m addrtype ! --src-type LOCAL -j MASQUERADE", interfaceName))
}
// set output
execCmd("iptables -t mangle -N clash_output")
@ -95,16 +99,15 @@ func SetTProxyLinuxIPTables(ifname string, tport int, dport int) error {
execCmd("iptables -t nat -I OUTPUT -p tcp --dport 53 -j clash_dns_output")
execCmd("iptables -t nat -I OUTPUT -p udp --dport 53 -j clash_dns_output")
log.Infoln("[TPROXY] Setting iptables completed")
return nil
}
func CleanUpTProxyLinuxIPTables() {
if interfaceName == "" || tProxyPort == 0 || dnsPort == 0 {
func CleanupTProxyIPTables() {
if runtime.GOOS != "linux" || interfaceName == "" || tProxyPort == 0 || dnsPort == 0 {
return
}
log.Warnln("Clean up tproxy linux iptables")
log.Warnln("Cleanup tproxy linux iptables")
if int(dialer.DefaultRoutingMark.Load()) == 2158 {
dialer.DefaultRoutingMark.Store(0)
@ -119,10 +122,12 @@ func CleanUpTProxyLinuxIPTables() {
execCmd(fmt.Sprintf("ip -f inet route del local default dev %s table %s", interfaceName, PROXY_ROUTE_TABLE))
// clean FORWARD
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -i %s ! -o %s -j ACCEPT", interfaceName, interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -i %s -o %s -j ACCEPT", interfaceName, interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -o %s -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -o %s -j ACCEPT", interfaceName))
if interfaceName != "lo" {
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -i %s ! -o %s -j ACCEPT", interfaceName, interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -i %s -o %s -j ACCEPT", interfaceName, interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -o %s -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", interfaceName))
execCmd(fmt.Sprintf("iptables -t filter -D FORWARD -o %s -j ACCEPT", interfaceName))
}
// 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))
@ -130,7 +135,9 @@ func CleanUpTProxyLinuxIPTables() {
execCmd("iptables -t mangle -D PREROUTING -j clash_prerouting")
// clean POSTROUTING
execCmd(fmt.Sprintf("iptables -t nat -D POSTROUTING -o %s -m addrtype ! --src-type LOCAL -j MASQUERADE", interfaceName))
if interfaceName != "lo" {
execCmd(fmt.Sprintf("iptables -t nat -D POSTROUTING -o %s -m addrtype ! --src-type LOCAL -j MASQUERADE", interfaceName))
}
// clean OUTPUT
execCmd(fmt.Sprintf("iptables -t mangle -D OUTPUT -o %s -j clash_output", interfaceName))
@ -146,6 +153,10 @@ func CleanUpTProxyLinuxIPTables() {
execCmd("iptables -t mangle -X clash_output")
execCmd("iptables -t nat -F clash_dns_output")
execCmd("iptables -t nat -X clash_dns_output")
interfaceName = ""
tProxyPort = 0
dnsPort = 0
}
func addLocalnetworkToChain(chain string) {
@ -167,11 +178,11 @@ func addLocalnetworkToChain(chain string) {
}
func execCmd(cmdStr string) error {
log.Debugln("[TPROXY] %s", cmdStr)
log.Debugln("[IPTABLES] %s", cmdStr)
_, err := cmd.ExecCmd(cmdStr)
if err != nil {
log.Warnln("[TPROXY] exec cmd: %v", err)
log.Warnln("[IPTABLES] exec cmd: %v", err)
}
return err

View File

@ -5,6 +5,7 @@ package tun
import (
"fmt"
"runtime"
"strings"
"github.com/Dreamacro/clash/common/pool"
"github.com/Dreamacro/clash/listener/tun/device"
@ -50,9 +51,18 @@ func Open(name string, mtu uint32) (_ device.Device, err error) {
}
nt, err := tun.CreateTUN(t.name, forcedMTU) // forcedMTU do not work on wintun, need to be setting by other way
// retry if abnormal exit on Windows at last time
if err != nil && runtime.GOOS == "windows" &&
strings.HasSuffix(err.Error(), "file already exists.") {
nt, err = tun.CreateTUN(t.name, forcedMTU)
}
if err != nil {
return nil, fmt.Errorf("create tun: %w", err)
}
t.nt = nt.(*tun.NativeTun)
tunMTU, err := nt.MTU()

View File

@ -39,9 +39,11 @@ startOver:
tryTimes++
var (
luid = winipcfg.LUID(dev.(*tun.TUN).LUID())
ip = addr.Masked().Addr().Next()
addresses = []netip.Prefix{netip.PrefixFrom(ip, addr.Bits())}
luid = winipcfg.LUID(dev.(*tun.TUN).LUID())
ip = addr.Masked().Addr().Next()
gw = ip.Next()
addresses = []netip.Prefix{netip.PrefixFrom(ip, addr.Bits())}
dnsAddress = []netip.Addr{gw}
family4 = winipcfg.AddressFamily(windows.AF_INET)
familyV6 = winipcfg.AddressFamily(windows.AF_INET6)
@ -123,7 +125,7 @@ startOver:
// add gateway
deduplicatedRoutes = append(deduplicatedRoutes, &winipcfg.RouteData{
Destination: addr.Masked(),
NextHop: addr.Masked().Addr().Next().Next(),
NextHop: gw,
Metric: 0,
})
@ -193,12 +195,11 @@ startOver:
return fmt.Errorf("unable to set v6 metric and MTU: %w", err)
}
dnsAdds := []netip.Addr{netip.MustParseAddr("198.18.0.2")}
err = luid.SetDNS(family4, dnsAdds, nil)
err = luid.SetDNS(family4, dnsAddress, nil)
if err == windows.ERROR_NOT_FOUND && retryOnFailure {
goto startOver
} else if err != nil {
return fmt.Errorf("unable to set DNS %s %s: %w", "198.18.0.2", "nil", err)
return fmt.Errorf("unable to set DNS %s %s: %w", dnsAddress[0].String(), "nil", err)
}
wintunInterfaceName = dev.Name()

View File

@ -2,12 +2,6 @@ package tun
import (
"fmt"
"net/netip"
"net/url"
"runtime"
"strings"
"time"
"github.com/Dreamacro/clash/adapter/inbound"
"github.com/Dreamacro/clash/common/cmd"
"github.com/Dreamacro/clash/component/process"
@ -21,12 +15,21 @@ import (
"github.com/Dreamacro/clash/listener/tun/ipstack/gvisor"
"github.com/Dreamacro/clash/listener/tun/ipstack/system"
"github.com/Dreamacro/clash/log"
"net/netip"
"net/url"
"runtime"
"strings"
)
// New TunAdapter
func New(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.Stack, error) {
func New(tunConf *config.Tun, dnsConf *config.DNS, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.Stack, error) {
var tunAddressPrefix string
if dnsConf.FakeIPRange != nil {
tunAddressPrefix = dnsConf.FakeIPRange.IPNet().String()
}
var (
tunAddress, _ = netip.ParsePrefix("198.18.0.1/16")
tunAddress, _ = netip.ParsePrefix(tunAddressPrefix)
devName = tunConf.Device
stackType = tunConf.Stack
autoRoute = tunConf.AutoRoute
@ -42,21 +45,19 @@ func New(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.
devName = generateDeviceName()
}
//if !tunAddress.IsValid() || !tunAddress.Addr().Is4() {
// tunAddress = netip.MustParsePrefix("198.18.0.1/16")
//}
if !tunAddress.IsValid() || !tunAddress.Addr().Is4() {
tunAddress = netip.MustParsePrefix("198.18.0.1/16")
}
process.AppendLocalIPs(tunAddress.Masked().Addr().Next().AsSlice())
// open tun device
for i := 1; i < 3; i++ {
time.Sleep(time.Second * 1)
tunDevice, err = parseDevice(devName, uint32(mtu))
if err != nil {
return nil, fmt.Errorf("can't open tun: %w", err)
}
break
tunDevice, err = parseDevice(devName, uint32(mtu))
if err != nil {
return nil, fmt.Errorf("can't open tun: %w", err)
}
// new ip stack
switch stackType {
case C.TunGvisor: