From 359f8ffca3c22e25bdad07252bb7a1d8904fa3eb Mon Sep 17 00:00:00 2001 From: yaling888 <73897884+yaling888@users.noreply.github.com> Date: Sun, 13 Mar 2022 17:48:43 +0800 Subject: [PATCH] Fix: should use the correct gateway for TUN system stack --- listener/tun/ipstack/commons/router_darwin.go | 12 ++++++---- listener/tun/ipstack/commons/router_linux.go | 11 ++++++--- .../tun/ipstack/commons/router_windows.go | 24 +++++++++++++------ listener/tun/ipstack/system/stack.go | 6 +++-- listener/tun/tun_adapter.go | 20 ++++++++++++---- 5 files changed, 53 insertions(+), 20 deletions(-) diff --git a/listener/tun/ipstack/commons/router_darwin.go b/listener/tun/ipstack/commons/router_darwin.go index 50e15542..f48b362c 100644 --- a/listener/tun/ipstack/commons/router_darwin.go +++ b/listener/tun/ipstack/commons/router_darwin.go @@ -13,14 +13,18 @@ func GetAutoDetectInterface() (string, error) { } func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute bool) error { - interfaceName := dev.Name() if !addr.Addr().Is4() { return fmt.Errorf("supported ipv4 only") } - ip := addr.Addr() - netmask := IPv4MaskString(addr.Bits()) - cmdStr := fmt.Sprintf("ifconfig %s inet %s netmask %s %s", interfaceName, ip, netmask, ip) + var ( + interfaceName = dev.Name() + ip = addr.Masked().Addr().Next() + gw = addr.Addr() + netmask = IPv4MaskString(addr.Bits()) + ) + + cmdStr := fmt.Sprintf("ifconfig %s inet %s netmask %s %s", interfaceName, ip, netmask, gw) _, err := cmd.ExecCmd(cmdStr) if err != nil { diff --git a/listener/tun/ipstack/commons/router_linux.go b/listener/tun/ipstack/commons/router_linux.go index f8bc7224..a306c1f0 100644 --- a/listener/tun/ipstack/commons/router_linux.go +++ b/listener/tun/ipstack/commons/router_linux.go @@ -13,8 +13,12 @@ func GetAutoDetectInterface() (string, error) { } func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, autoRoute bool) error { - interfaceName := dev.Name() - _, err := cmd.ExecCmd(fmt.Sprintf("ip addr add %s dev %s", addr.String(), interfaceName)) + var ( + interfaceName = dev.Name() + ip = addr.Masked().Addr().Next() + ) + + _, err := cmd.ExecCmd(fmt.Sprintf("ip addr add %s dev %s", ip.String(), interfaceName)) if err != nil { return err } @@ -31,8 +35,9 @@ func ConfigInterfaceAddress(dev device.Device, addr netip.Prefix, forceMTU int, } func configInterfaceRouting(interfaceName string, addr netip.Prefix) error { + linkIP := addr.Masked().Addr().Next() for _, route := range ROUTES { - if err := execRouterCmd("add", route, interfaceName, addr.Addr().String()); err != nil { + if err := execRouterCmd("add", route, interfaceName, linkIP.String()); err != nil { return err } } diff --git a/listener/tun/ipstack/commons/router_windows.go b/listener/tun/ipstack/commons/router_windows.go index ee6911ce..2a7fdfa8 100644 --- a/listener/tun/ipstack/commons/router_windows.go +++ b/listener/tun/ipstack/commons/router_windows.go @@ -40,12 +40,15 @@ startOver: log.Infoln("[wintun]: tun adapter GUID: %s", guid.String()) } - addresses := []netip.Prefix{addr} + var ( + ip = addr.Masked().Addr().Next() + addresses = []netip.Prefix{netip.PrefixFrom(ip, addr.Bits())} - family := winipcfg.AddressFamily(windows.AF_INET) - familyV6 := winipcfg.AddressFamily(windows.AF_INET6) + family4 = winipcfg.AddressFamily(windows.AF_INET) + familyV6 = winipcfg.AddressFamily(windows.AF_INET6) + currentFamily = winipcfg.AddressFamily(windows.AF_INET6) + ) - currentFamily := winipcfg.AddressFamily(windows.AF_INET6) if addr.Addr().Is4() { currentFamily = winipcfg.AddressFamily(windows.AF_INET) } @@ -114,7 +117,14 @@ startOver: deduplicatedRoutes = append(deduplicatedRoutes, &r) } - err = luid.SetRoutesForFamily(family, deduplicatedRoutes) + // append the gateway + deduplicatedRoutes = append(deduplicatedRoutes, &winipcfg.RouteData{ + Destination: addr.Masked(), + NextHop: addr.Addr(), + Metric: 0, + }) + + err = luid.SetRoutesForFamily(currentFamily, deduplicatedRoutes) if err == windows.ERROR_NOT_FOUND && retryOnFailure { goto startOver } else if err != nil { @@ -134,7 +144,7 @@ startOver: } var ipif *winipcfg.MibIPInterfaceRow - ipif, err = luid.IPInterface(family) + ipif, err = luid.IPInterface(family4) if err != nil { return err } @@ -181,7 +191,7 @@ startOver: } dnsAdds := []netip.Addr{netip.MustParseAddr("198.18.0.2")} - err = luid.SetDNS(family, dnsAdds, nil) + err = luid.SetDNS(family4, dnsAdds, nil) if err == windows.ERROR_NOT_FOUND && retryOnFailure { goto startOver } else if err != nil { diff --git a/listener/tun/ipstack/system/stack.go b/listener/tun/ipstack/system/stack.go index 693d7f2f..27f83c7e 100644 --- a/listener/tun/ipstack/system/stack.go +++ b/listener/tun/ipstack/system/stack.go @@ -38,8 +38,10 @@ func (s sysStack) Close() error { var ipv4LoopBack = netip.MustParsePrefix("127.0.0.0/8") func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Prefix, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.Stack, error) { - portal := tunAddress.Addr() - gateway := portal + var ( + portal = tunAddress.Addr() + gateway = tunAddress.Masked().Addr().Next() + ) stack, err := mars.StartListener(device, gateway, portal) if err != nil { diff --git a/listener/tun/tun_adapter.go b/listener/tun/tun_adapter.go index 2fe7cf4c..a4a701a5 100644 --- a/listener/tun/tun_adapter.go +++ b/listener/tun/tun_adapter.go @@ -28,7 +28,7 @@ func New(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound. devName = generateDeviceName() } - tunAddress := netip.MustParsePrefix("198.18.0.1/16") + tunAddress := netip.MustParsePrefix("198.18.255.254/16") autoRoute := tunConf.AutoRoute stackType := tunConf.Stack mtu := 9000 @@ -87,9 +87,9 @@ func New(tunConf *config.Tun, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound. return nil, fmt.Errorf("setting interface address and routing failed: %w", err) } - setAtLatest(stackType) + setAtLatest(stackType, devName) - log.Infoln("TUN stack listening at: %s(%s), mtu: %d, auto route: %v, ip stack: %s", tunDevice.Name(), tunAddress.Addr().String(), mtu, autoRoute, stackType) + log.Infoln("TUN stack listening at: %s(%s), mtu: %d, auto route: %v, ip stack: %s", tunDevice.Name(), tunAddress.Masked().Addr().Next().String(), mtu, autoRoute, stackType) return tunStack, nil } @@ -127,7 +127,7 @@ func parseDevice(s string, mtu uint32) (device.Device, error) { } } -func setAtLatest(stackType C.TUNStack) { +func setAtLatest(stackType C.TUNStack, devName string) { if stackType != C.TunSystem { return } @@ -137,6 +137,18 @@ func setAtLatest(stackType C.TUNStack) { _, _ = cmd.ExecCmd("ipconfig /renew") case "linux": // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.ip_forward=1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.all.forwarding = 1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.all.accept_local = 1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.all.accept_redirects = 1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.all.rp_filter = 2") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.default.forwarding = 1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.default.accept_local = 1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.default.accept_redirects = 1") + // _, _ = cmd.ExecCmd("sysctl -w net.ipv4.conf.default.rp_filter = 2") + // _, _ = cmd.ExecCmd(fmt.Sprintf("sysctl -w net.ipv4.conf.%s.forwarding = 1", devName)) + // _, _ = cmd.ExecCmd(fmt.Sprintf("sysctl -w net.ipv4.conf.%s.accept_local = 1", devName)) + // _, _ = cmd.ExecCmd(fmt.Sprintf("sysctl -w net.ipv4.conf.%s.accept_redirects = 1", devName)) + // _, _ = cmd.ExecCmd(fmt.Sprintf("sysctl -w net.ipv4.conf.%s.rp_filter = 2", devName)) // _, _ = cmd.ExecCmd("iptables -t filter -P FORWARD ACCEPT") } }