Prechádzať zdrojové kódy

Add custom options for TUN `auto-route` and `auto-redirect`

世界 1 rok pred
rodič
commit
7a2cd77798

+ 63 - 19
docs/configuration/inbound/tun.md

@@ -13,7 +13,11 @@ icon: material/new-box
     :material-plus: [route_exclude_address](#route_address)  
     :material-delete-clock: [inet4_route_exclude_address](#inet4_route_exclude_address)  
     :material-delete-clock: [inet6_route_exclude_address](#inet6_route_exclude_address)  
+    :material-plus: [iproute2_table_index](#iproute2_table_index)  
+    :material-plus: [iproute2_rule_index](#iproute2_table_index)  
     :material-plus: [auto_redirect](#auto_redirect)  
+    :material-plus: [auto_redirect_input_mark](#auto_redirect_input_mark)  
+    :material-plus: [auto_redirect_output_mark](#auto_redirect_output_mark)  
     :material-plus: [route_address_set](#route_address_set)  
     :material-plus: [route_exclude_address_set](#route_address_set)
 
@@ -53,8 +57,12 @@ icon: material/new-box
   "mtu": 9000,
   "gso": false,
   "auto_route": true,
-  "strict_route": true,
+  "iproute2_table_index": 2022,
+  "iproute2_rule_index": 9000,
   "auto_redirect": false,
+  "auto_redirect_input_mark": "0x2023",
+  "auto_redirect_output_mark": "0x2024",
+  "strict_route": true,
   "route_address": [
     "0.0.0.0/1",
     "128.0.0.0/1",
@@ -129,8 +137,8 @@ icon: material/new-box
       "match_domain": []
     }
   },
-  
-  ... // Listen Fields
+  ...
+  // Listen Fields
 }
 ```
 
@@ -180,7 +188,7 @@ The maximum transmission unit.
 
 !!! quote ""
 
-    Only supported on Linux.
+    Only supported on Linux with `auto_route` enabled.
 
 Enable generic segmentation offload.
 
@@ -196,24 +204,21 @@ Set the default route to the Tun.
 
     By default, VPN takes precedence over tun. To make tun go through VPN, enable `route.override_android_vpn`.
 
-#### strict_route
+#### iproute2_table_index
 
-Enforce strict routing rules when `auto_route` is enabled:
+!!! question "Since sing-box 1.10.0"
 
-*In Linux*:
+Linux iproute2 table index generated by `auto_route`.
 
-* Let unsupported network unreachable
-* Make ICMP traffic route to tun instead of upstream interfaces
-* Route all connections to tun
+`2022` is used by default.
 
-It prevents IP address leaks and makes DNS hijacking work on Android.
+#### iproute2_rule_index
 
-*In Windows*:
+!!! question "Since sing-box 1.10.0"
 
-* Add firewall rules to prevent DNS leak caused by
-  Windows' [ordinary multihomed DNS resolution behavior](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29)
+Linux iproute2 rule start index generated by `auto_route`.
 
-It may prevent some applications (such as VirtualBox) from working properly in certain situations.
+`9000` is used by default.
 
 #### auto_redirect
 
@@ -234,6 +239,41 @@ use [VPNHotspot](https://github.com/Mygod/VPNHotspot).
 
 `auto_route` with `auto_redirect` now works as expected on routers **without intervention**.
 
+#### auto_redirect_input_mark
+
+!!! question "Since sing-box 1.10.0"
+
+Connection input mark used by `route_address_set` and `route_exclude_address_set`.
+
+`0x2023` is used by default.
+
+#### auto_redirect_output_mark
+
+!!! question "Since sing-box 1.10.0"
+
+Connection output mark used by `route_address_set` and `route_exclude_address_set`.
+
+`0x2024` is used by default.
+
+#### strict_route
+
+Enforce strict routing rules when `auto_route` is enabled:
+
+*In Linux*:
+
+* Let unsupported network unreachable
+* Make ICMP traffic route to tun instead of upstream interfaces
+* Route all connections to tun
+
+It prevents IP address leaks and makes DNS hijacking work on Android.
+
+*In Windows*:
+
+* Add firewall rules to prevent DNS leak caused by
+  Windows' [ordinary multihomed DNS resolution behavior](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29)
+
+It may prevent some applications (such as VirtualBox) from working properly in certain situations.
+
 #### route_address
 
 !!! question "Since sing-box 1.10.0"
@@ -244,7 +284,8 @@ Use custom routes instead of default when `auto_route` is enabled.
 
 !!! failure "Deprecated in sing-box 1.10.0"
 
-   `inet4_route_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_address](#route_address) instead.
+`inet4_route_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_address](#route_address)
+instead.
 
 Use custom routes instead of default when `auto_route` is enabled.
 
@@ -252,7 +293,8 @@ Use custom routes instead of default when `auto_route` is enabled.
 
 !!! failure "Deprecated in sing-box 1.10.0"
 
-   `inet6_route_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_address](#route_address) instead.
+`inet6_route_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_address](#route_address)
+instead.
 
 Use custom routes instead of default when `auto_route` is enabled.
 
@@ -266,7 +308,8 @@ Exclude custom routes when `auto_route` is enabled.
 
 !!! failure "Deprecated in sing-box 1.10.0"
 
-   `inet4_route_exclude_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_exclude_address](#route_exclude_address) instead.
+`inet4_route_exclude_address` is deprecated and will be removed in sing-box 1.11.0, please
+use [route_exclude_address](#route_exclude_address) instead.
 
 Exclude custom routes when `auto_route` is enabled.
 
@@ -274,7 +317,8 @@ Exclude custom routes when `auto_route` is enabled.
 
 !!! failure "Deprecated in sing-box 1.10.0"
 
-   `inet6_route_exclude_address` is deprecated and will be removed in sing-box 1.11.0, please use [route_exclude_address](#route_exclude_address) instead.
+`inet6_route_exclude_address` is deprecated and will be removed in sing-box 1.11.0, please
+use [route_exclude_address](#route_exclude_address) instead.
 
 Exclude custom routes when `auto_route` is enabled.
 

+ 55 - 15
docs/configuration/inbound/tun.zh.md

@@ -12,8 +12,12 @@ icon: material/new-box
     :material-delete-clock: [inet6_route_address](#inet6_route_address)  
     :material-plus: [route_exclude_address](#route_address)  
     :material-delete-clock: [inet4_route_exclude_address](#inet4_route_exclude_address)  
-    :material-delete-clock: [inet6_route_exclude_address](#inet6_route_exclude_address)  
+    :material-delete-clock: [inet6_route_exclude_address](#inet6_route_exclude_address)   
+    :material-plus: [iproute2_table_index](#iproute2_table_index)  
+    :material-plus: [iproute2_rule_index](#iproute2_table_index)  
     :material-plus: [auto_redirect](#auto_redirect)  
+    :material-plus: [auto_redirect_input_mark](#auto_redirect_input_mark)  
+    :material-plus: [auto_redirect_output_mark](#auto_redirect_output_mark)  
     :material-plus: [route_address_set](#route_address_set)  
     :material-plus: [route_exclude_address_set](#route_address_set)
 
@@ -53,8 +57,12 @@ icon: material/new-box
   "mtu": 9000,
   "gso": false,
   "auto_route": true,
-  "strict_route": true,
+  "iproute2_table_index": 2022,
+  "iproute2_rule_index": 9000,
   "auto_redirect": false,
+  "auto_redirect_input_mark": "0x2023",
+  "auto_redirect_output_mark": "0x2024",
+  "strict_route": true,
   "route_address": [
     "0.0.0.0/1",
     "128.0.0.0/1",
@@ -200,25 +208,21 @@ tun 接口的 IPv6 前缀。
 
     VPN 默认优先于 tun。要使 tun 经过 VPN,启用 `route.override_android_vpn`。
 
-#### strict_route
+#### iproute2_table_index
 
-启用 `auto_route` 时执行严格的路由规则。
+!!! question "自 sing-box 1.10.0 起"
 
-*在 Linux 中*:
+`auto_route` 生成的 iproute2 路由表索引。
 
-* 让不支持的网络无法到达
-* 使 ICMP 流量路由到 tun 而不是上游接口
-* 将所有连接路由到 tun
+默认使用 `2022`。
 
-它可以防止 IP 地址泄漏,并使 DNS 劫持在 Android 上工作。
+#### iproute2_rule_index
 
-*在 Windows 中*:
+!!! question "自 sing-box 1.10.0 起"
 
-* 添加防火墙规则以阻止 Windows
-  的 [普通多宿主 DNS 解析行为](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29)
-  造成的 DNS 泄露
+`auto_route` 生成的 iproute2 规则起始索引。
 
-它可能会使某些应用程序(如 VirtualBox)在某些情况下无法正常工作
+默认使用 `9000`。
 
 #### auto_redirect
 
@@ -226,7 +230,7 @@ tun 接口的 IPv6 前缀。
 
 !!! quote ""
 
-    仅支持 Linux。
+    仅支持 Linux,且需要 `auto_route` 已启用 
 
 自动配置 iptables 以重定向 TCP 连接。
 
@@ -238,6 +242,42 @@ tun 接口的 IPv6 前缀。
 
 带有 `auto_redirect `的 `auto_route` 现在可以在路由器上按预期工作,**无需干预**。
 
+#### auto_redirect_input_mark
+
+!!! question "自 sing-box 1.10.0 起"
+
+`route_address_set` 和 `route_exclude_address_set` 使用的连接输入标记。
+
+默认使用 `0x2023`。
+
+#### auto_redirect_output_mark
+
+!!! question "自 sing-box 1.10.0 起"
+
+`route_address_set` 和 `route_exclude_address_set` 使用的连接输出标记。
+
+默认使用 `0x2024`。
+
+#### strict_route
+
+启用 `auto_route` 时执行严格的路由规则。
+
+*在 Linux 中*:
+
+* 让不支持的网络无法到达
+* 使 ICMP 流量路由到 tun 而不是上游接口
+* 将所有连接路由到 tun
+
+它可以防止 IP 地址泄漏,并使 DNS 劫持在 Android 上工作。
+
+*在 Windows 中*:
+
+* 添加防火墙规则以阻止 Windows
+  的 [普通多宿主 DNS 解析行为](https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd197552%28v%3Dws.10%29)
+  造成的 DNS 泄露
+
+它可能会使某些应用程序(如 VirtualBox)在某些情况下无法正常工作。
+
 #### route_address
 
 !!! question "自 sing-box 1.10.0 起"

+ 2 - 2
inbound/tun.go

@@ -141,11 +141,11 @@ func NewTun(ctx context.Context, router adapter.Router, logger log.ContextLogger
 	if ruleIndex == 0 {
 		ruleIndex = tun.DefaultIPRoute2RuleIndex
 	}
-	inputMark := options.AutoRedirectInputMark
+	inputMark := uint32(options.AutoRedirectInputMark)
 	if inputMark == 0 {
 		inputMark = tun.DefaultAutoRedirectInputMark
 	}
-	outputMark := options.AutoRedirectOutputMark
+	outputMark := uint32(options.AutoRedirectOutputMark)
 	if outputMark == 0 {
 		outputMark = tun.DefaultAutoRedirectOutputMark
 	}

+ 33 - 3
option/tun.go

@@ -1,6 +1,13 @@
 package option
 
-import "net/netip"
+import (
+	"net/netip"
+	"strconv"
+
+	E "github.com/sagernet/sing/common/exceptions"
+	F "github.com/sagernet/sing/common/format"
+	"github.com/sagernet/sing/common/json"
+)
 
 type TunInboundOptions struct {
 	InterfaceName          string                 `json:"interface_name,omitempty"`
@@ -11,8 +18,8 @@ type TunInboundOptions struct {
 	IPRoute2TableIndex     int                    `json:"iproute2_table_index,omitempty"`
 	IPRoute2RuleIndex      int                    `json:"iproute2_rule_index,omitempty"`
 	AutoRedirect           bool                   `json:"auto_redirect,omitempty"`
-	AutoRedirectInputMark  uint32                 `json:"auto_redirect_input_mark,omitempty"`
-	AutoRedirectOutputMark uint32                 `json:"auto_redirect_output_mark,omitempty"`
+	AutoRedirectInputMark  FwMark                 `json:"auto_redirect_input_mark,omitempty"`
+	AutoRedirectOutputMark FwMark                 `json:"auto_redirect_output_mark,omitempty"`
 	StrictRoute            bool                   `json:"strict_route,omitempty"`
 	RouteAddress           Listable[netip.Prefix] `json:"route_address,omitempty"`
 	RouteAddressSet        Listable[string]       `json:"route_address_set,omitempty"`
@@ -46,3 +53,26 @@ type TunInboundOptions struct {
 	// Deprecated: merged to RouteExcludeAddress
 	Inet6RouteExcludeAddress Listable[netip.Prefix] `json:"inet6_route_exclude_address,omitempty"`
 }
+
+type FwMark uint32
+
+func (f FwMark) MarshalJSON() ([]byte, error) {
+	return json.Marshal(F.ToString("0x", strconv.FormatUint(uint64(f), 16)))
+}
+
+func (f *FwMark) UnmarshalJSON(bytes []byte) error {
+	var stringValue string
+	err := json.Unmarshal(bytes, &stringValue)
+	if err != nil {
+		if rawErr := json.Unmarshal(bytes, (*uint32)(f)); rawErr == nil {
+			return nil
+		}
+		return E.Cause(err, "invalid number or string mark")
+	}
+	intValue, err := strconv.ParseUint(stringValue, 0, 32)
+	if err != nil {
+		return err
+	}
+	*f = FwMark(intValue)
+	return nil
+}