From 2a45c178fabf525af125f9349b9fe8aeedd1f978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Mon, 30 Oct 2023 12:00:00 +0800 Subject: [PATCH] Add exclude route support for tun & Update gVisor to 20231113.0 --- docs/configuration/inbound/tun.md | 14 +++++++++ docs/configuration/inbound/tun.zh.md | 14 +++++++++ experimental/libbox/service.go | 6 +++- experimental/libbox/tun.go | 9 ++++-- go.mod | 6 ++-- go.sum | 12 ++++---- inbound/tun.go | 36 ++++++++++++----------- option/tun.go | 44 +++++++++++++++------------- 8 files changed, 91 insertions(+), 50 deletions(-) diff --git a/docs/configuration/inbound/tun.md b/docs/configuration/inbound/tun.md index 4c9670a2..e6c52c54 100644 --- a/docs/configuration/inbound/tun.md +++ b/docs/configuration/inbound/tun.md @@ -22,6 +22,12 @@ "::/1", "8000::/1" ], + "inet4_route_exclude_address": [ + "192.168.0.0/16" + ], + "inet6_route_exclude_address": [ + "fc00::/7" + ], "endpoint_independent_nat": false, "stack": "system", "include_interface": [ @@ -130,6 +136,14 @@ Use custom routes instead of default when `auto_route` is enabled. Use custom routes instead of default when `auto_route` is enabled. +#### inet4_route_exclude_address + +Exclude custom routes when `auto_route` is enabled. + +#### inet6_route_exclude_address + +Exclude custom routes when `auto_route` is enabled. + #### endpoint_independent_nat !!! info "" diff --git a/docs/configuration/inbound/tun.zh.md b/docs/configuration/inbound/tun.zh.md index fbd10abf..8f246c04 100644 --- a/docs/configuration/inbound/tun.zh.md +++ b/docs/configuration/inbound/tun.zh.md @@ -22,6 +22,12 @@ "::/1", "8000::/1" ], + "inet4_route_exclude_address": [ + "192.168.0.0/16" + ], + "inet6_route_exclude_address": [ + "fc00::/7" + ], "endpoint_independent_nat": false, "stack": "system", "include_interface": [ @@ -131,6 +137,14 @@ tun 接口的 IPv6 前缀。 启用 `auto_route` 时使用自定义路由而不是默认路由。 +#### inet4_route_exclude_address + +启用 `auto_route` 时排除自定义路由。 + +#### inet6_route_exclude_address + +启用 `auto_route` 时排除自定义路由。 + #### endpoint_independent_nat 启用独立于端点的 NAT。 diff --git a/experimental/libbox/service.go b/experimental/libbox/service.go index 67b57d7d..ce4d6d2a 100644 --- a/experimental/libbox/service.go +++ b/experimental/libbox/service.go @@ -122,7 +122,11 @@ func (w *platformInterfaceWrapper) OpenTun(options *tun.Options, platformOptions if len(options.IncludeAndroidUser) > 0 { return nil, E.New("android: unsupported android_user option") } - tunFd, err := w.iif.OpenTun(&tunOptions{options, platformOptions}) + routeRanges, err := options.BuildAutoRouteRanges(true) + if err != nil { + return nil, err + } + tunFd, err := w.iif.OpenTun(&tunOptions{options, routeRanges, platformOptions}) if err != nil { return nil, err } diff --git a/experimental/libbox/tun.go b/experimental/libbox/tun.go index e692a5d6..e40ad58b 100644 --- a/experimental/libbox/tun.go +++ b/experimental/libbox/tun.go @@ -60,6 +60,7 @@ var _ TunOptions = (*tunOptions)(nil) type tunOptions struct { *tun.Options + routeRanges []netip.Prefix option.TunPlatformOptions } @@ -91,11 +92,15 @@ func (o *tunOptions) GetStrictRoute() bool { } func (o *tunOptions) GetInet4RouteAddress() RoutePrefixIterator { - return mapRoutePrefix(o.Inet4RouteAddress) + return mapRoutePrefix(common.Filter(o.routeRanges, func(it netip.Prefix) bool { + return it.Addr().Is4() + })) } func (o *tunOptions) GetInet6RouteAddress() RoutePrefixIterator { - return mapRoutePrefix(o.Inet6RouteAddress) + return mapRoutePrefix(common.Filter(o.routeRanges, func(it netip.Prefix) bool { + return it.Addr().Is6() + })) } func (o *tunOptions) GetIncludePackage() StringIterator { diff --git a/go.mod b/go.mod index 4af18451..e6188952 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a github.com/sagernet/cloudflare-tls v0.0.0-20230829051644-4a68352d0c4a github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950 - github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab + github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930 github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460 github.com/sagernet/reality v0.0.0-20230406110435-ee17307e7691 github.com/sagernet/sing v0.2.18-0.20231124125253-2dcabf4bfcbc @@ -33,7 +33,7 @@ require ( github.com/sagernet/sing-shadowsocks v0.2.5 github.com/sagernet/sing-shadowsocks2 v0.1.5 github.com/sagernet/sing-shadowtls v0.1.4 - github.com/sagernet/sing-tun v0.1.20 + github.com/sagernet/sing-tun v0.1.21-0.20231119035513-f6ea97c5af71 github.com/sagernet/sing-vmess v0.1.8 github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 @@ -89,7 +89,7 @@ require ( golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/text v0.14.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/time v0.4.0 // indirect golang.org/x/tools v0.15.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect diff --git a/go.sum b/go.sum index 9ed67339..cf424208 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,8 @@ github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms= github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950 h1:hUz/2mJLgi7l2H36JGpDY+jou9FmI6kAm0ZkU+xPpgE= github.com/sagernet/gomobile v0.0.0-20230915142329-c6740b6d2950/go.mod h1:5YE39YkJkCcMsfq1jMKkjsrM2GfBoF9JVWnvU89hmvU= -github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab h1:u+xQoi/Yc6bNUvTfrDD6HhGRybn2lzrhf5vmS+wb4Ho= -github.com/sagernet/gvisor v0.0.0-20230930141345-5fef6f2e17ab/go.mod h1:3akUhSHSVtLuJaYcW5JPepUraBOW06Ibz2HKwaK5rOk= +github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930 h1:dSPgjIw0CT6ISLeEh8Q20dZMBMFCcEceo23+LncRcNQ= +github.com/sagernet/gvisor v0.0.0-20231119034329-07cfb6aaf930/go.mod h1:JpKHkOYgh4wLwrX2BhH3ZIvCvazCkTnPeEcmigZJfHY= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE= github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/quic-go v0.0.0-20231008035953-32727fef9460 h1:dAe4OIJAtE0nHOzTHhAReQteh3+sa63rvXbuIpbeOTY= @@ -128,8 +128,8 @@ github.com/sagernet/sing-shadowsocks2 v0.1.5 h1:JDeAJ4ZWlYZ7F6qEVdDKPhQEangxKw/J github.com/sagernet/sing-shadowsocks2 v0.1.5/go.mod h1:KF65y8lI5PGHyMgRZGYXYsH9ilgRc/yr+NYbSNGuBm4= github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k= github.com/sagernet/sing-shadowtls v0.1.4/go.mod h1:F8NBgsY5YN2beQavdgdm1DPlhaKQlaL6lpDdcBglGK4= -github.com/sagernet/sing-tun v0.1.20 h1:vYWo/w6fkKc8I1WP/IB8eBWZVsGIC6eoEoNR6XqEDlY= -github.com/sagernet/sing-tun v0.1.20/go.mod h1:6kkPL/u9tWcLFfu55VbwMDnO++17cUihSmImkZjdZro= +github.com/sagernet/sing-tun v0.1.21-0.20231119035513-f6ea97c5af71 h1:WQi0TwhjbSNFFbxybIgAUSjVvo7uWSsLD28ldoM2avY= +github.com/sagernet/sing-tun v0.1.21-0.20231119035513-f6ea97c5af71/go.mod h1:hyzA4gDWbeg2SXklqPDswBKa//QcjlZqKw9aPcNdQ9A= github.com/sagernet/sing-vmess v0.1.8 h1:XVWad1RpTy9b5tPxdm5MCU8cGfrTGdR8qCq6HV2aCNc= github.com/sagernet/sing-vmess v0.1.8/go.mod h1:vhx32UNzTDUkNwOyIjcZQohre1CaytquC5mPplId8uA= github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 h1:HuE6xSwco/Xed8ajZ+coeYLmioq0Qp1/Z2zczFaV8as= @@ -202,8 +202,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= +golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= diff --git a/inbound/tun.go b/inbound/tun.go index 0b57482d..7d1f5199 100644 --- a/inbound/tun.go +++ b/inbound/tun.go @@ -71,23 +71,25 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger logger: logger, inboundOptions: options.InboundOptions, tunOptions: tun.Options{ - Name: options.InterfaceName, - MTU: tunMTU, - Inet4Address: options.Inet4Address, - Inet6Address: options.Inet6Address, - AutoRoute: options.AutoRoute, - StrictRoute: options.StrictRoute, - IncludeInterface: options.IncludeInterface, - ExcludeInterface: options.ExcludeInterface, - Inet4RouteAddress: options.Inet4RouteAddress, - Inet6RouteAddress: options.Inet6RouteAddress, - IncludeUID: includeUID, - ExcludeUID: excludeUID, - IncludeAndroidUser: options.IncludeAndroidUser, - IncludePackage: options.IncludePackage, - ExcludePackage: options.ExcludePackage, - InterfaceMonitor: router.InterfaceMonitor(), - TableIndex: 2022, + Name: options.InterfaceName, + MTU: tunMTU, + Inet4Address: options.Inet4Address, + Inet6Address: options.Inet6Address, + AutoRoute: options.AutoRoute, + StrictRoute: options.StrictRoute, + IncludeInterface: options.IncludeInterface, + ExcludeInterface: options.ExcludeInterface, + Inet4RouteAddress: options.Inet4RouteAddress, + Inet6RouteAddress: options.Inet6RouteAddress, + Inet4RouteExcludeAddress: options.Inet4RouteExcludeAddress, + Inet6RouteExcludeAddress: options.Inet6RouteExcludeAddress, + IncludeUID: includeUID, + ExcludeUID: excludeUID, + IncludeAndroidUser: options.IncludeAndroidUser, + IncludePackage: options.IncludePackage, + ExcludePackage: options.ExcludePackage, + InterfaceMonitor: router.InterfaceMonitor(), + TableIndex: 2022, }, endpointIndependentNat: options.EndpointIndependentNat, udpTimeout: udpTimeout, diff --git a/option/tun.go b/option/tun.go index 4cf77804..306d4541 100644 --- a/option/tun.go +++ b/option/tun.go @@ -3,26 +3,28 @@ package option import "net/netip" type TunInboundOptions struct { - InterfaceName string `json:"interface_name,omitempty"` - MTU uint32 `json:"mtu,omitempty"` - Inet4Address Listable[netip.Prefix] `json:"inet4_address,omitempty"` - Inet6Address Listable[netip.Prefix] `json:"inet6_address,omitempty"` - AutoRoute bool `json:"auto_route,omitempty"` - StrictRoute bool `json:"strict_route,omitempty"` - Inet4RouteAddress Listable[netip.Prefix] `json:"inet4_route_address,omitempty"` - Inet6RouteAddress Listable[netip.Prefix] `json:"inet6_route_address,omitempty"` - IncludeInterface Listable[string] `json:"include_interface,omitempty"` - ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"` - IncludeUID Listable[uint32] `json:"include_uid,omitempty"` - IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"` - ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"` - ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"` - IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"` - IncludePackage Listable[string] `json:"include_package,omitempty"` - ExcludePackage Listable[string] `json:"exclude_package,omitempty"` - EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"` - UDPTimeout int64 `json:"udp_timeout,omitempty"` - Stack string `json:"stack,omitempty"` - Platform *TunPlatformOptions `json:"platform,omitempty"` + InterfaceName string `json:"interface_name,omitempty"` + MTU uint32 `json:"mtu,omitempty"` + Inet4Address Listable[netip.Prefix] `json:"inet4_address,omitempty"` + Inet6Address Listable[netip.Prefix] `json:"inet6_address,omitempty"` + AutoRoute bool `json:"auto_route,omitempty"` + StrictRoute bool `json:"strict_route,omitempty"` + Inet4RouteAddress Listable[netip.Prefix] `json:"inet4_route_address,omitempty"` + Inet6RouteAddress Listable[netip.Prefix] `json:"inet6_route_address,omitempty"` + Inet4RouteExcludeAddress Listable[netip.Prefix] `json:"inet4_route_exclude_address,omitempty"` + Inet6RouteExcludeAddress Listable[netip.Prefix] `json:"inet6_route_exclude_address,omitempty"` + IncludeInterface Listable[string] `json:"include_interface,omitempty"` + ExcludeInterface Listable[string] `json:"exclude_interface,omitempty"` + IncludeUID Listable[uint32] `json:"include_uid,omitempty"` + IncludeUIDRange Listable[string] `json:"include_uid_range,omitempty"` + ExcludeUID Listable[uint32] `json:"exclude_uid,omitempty"` + ExcludeUIDRange Listable[string] `json:"exclude_uid_range,omitempty"` + IncludeAndroidUser Listable[int] `json:"include_android_user,omitempty"` + IncludePackage Listable[string] `json:"include_package,omitempty"` + ExcludePackage Listable[string] `json:"exclude_package,omitempty"` + EndpointIndependentNat bool `json:"endpoint_independent_nat,omitempty"` + UDPTimeout int64 `json:"udp_timeout,omitempty"` + Stack string `json:"stack,omitempty"` + Platform *TunPlatformOptions `json:"platform,omitempty"` InboundOptions }