docs: 客户端可配置分流设计+原型(并入 v2 作开发基线) #7
@@ -113,6 +113,12 @@ func BuildClientConfig(node *nodes.NodeRow, dpUUID, deriveKey string, opts Clien
|
||||
"auto_route": true,
|
||||
"strict_route": true,
|
||||
"stack": "system",
|
||||
// 私有 LAN 直连:strict_route 会在 OS 层把所有流量(含 LAN)强抓进隧道,
|
||||
// 光靠 route.rules 的 ip_cidr→direct 在 macOS 不生效(direct 出站的包被
|
||||
// strict_route 重新捕回隧道)。route_exclude_address 在 auto_route 层就把这些
|
||||
// 网段排除出隧道,LAN 走系统直连(修「隧道开着连不上局域网/NAS/家里机器」)。
|
||||
// **不含 172.16.0.0/12**:隧道自身地址与 DNS(172.19.x)在此段,排除会断 DNS。
|
||||
"route_exclude_address": []string{"192.168.0.0/16", "10.0.0.0/8"},
|
||||
}
|
||||
|
||||
// 代理出站集合:REALITY 必有;Hy2 仅在启用时加入(否则不进配置/探测组)。
|
||||
|
||||
@@ -193,3 +193,45 @@ func TestRulesHandler(t *testing.T) {
|
||||
t.Errorf("allowed but missing file: code=%d, want 404", code)
|
||||
}
|
||||
}
|
||||
|
||||
// TUN 入站必须把私有 LAN 网段从隧道排除(route_exclude_address),否则 strict_route
|
||||
// 会在 macOS 把 LAN 强抓进隧道 → 隧道开着连不上局域网/NAS。不得含 172.16/12
|
||||
// (隧道自身 172.19.x 在此段,排除会断 DNS)。
|
||||
func TestBuildClientConfigLANExclude(t *testing.T) {
|
||||
cfg, err := BuildClientConfig(testNode(), "uuid-1", "k", ClientConfigOpts{})
|
||||
if err != nil {
|
||||
t.Fatalf("build: %v", err)
|
||||
}
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal(cfg, &m); err != nil {
|
||||
t.Fatalf("unmarshal: %v", err)
|
||||
}
|
||||
var tun map[string]any
|
||||
for _, in := range m["inbounds"].([]any) {
|
||||
im := in.(map[string]any)
|
||||
if im["type"] == "tun" {
|
||||
tun = im
|
||||
break
|
||||
}
|
||||
}
|
||||
if tun == nil {
|
||||
t.Fatal("no tun inbound")
|
||||
}
|
||||
exRaw, ok := tun["route_exclude_address"]
|
||||
if !ok {
|
||||
t.Fatal("tun inbound missing route_exclude_address (LAN would be captured by strict_route)")
|
||||
}
|
||||
got := map[string]bool{}
|
||||
for _, v := range exRaw.([]any) {
|
||||
got[v.(string)] = true
|
||||
}
|
||||
if !got["192.168.0.0/16"] {
|
||||
t.Error("route_exclude_address must contain 192.168.0.0/16")
|
||||
}
|
||||
if !got["10.0.0.0/8"] {
|
||||
t.Error("route_exclude_address must contain 10.0.0.0/8")
|
||||
}
|
||||
if got["172.16.0.0/12"] {
|
||||
t.Error("route_exclude_address must NOT contain 172.16.0.0/12 (tunnel DNS 172.19.x lives there)")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user