透明代理下,給 DNS 與探針留一條真網之路
昔年玩軟路由,常有一惑:若 Clash TUN 接管全家流量,smartdns 又當如何優選?
DNS 欲優選,須見真網;TUN 欲接管,則要攔流。二者若不分道,smartdns 所見,已非底層網路,而是代理之後的影子。以影測形,必生玄學。
今日終於想明白:問題不在 TUN 與 smartdns 不可共存,而在控制面與數據面混作一處。
一、TUN 不是原罪
TUN 所為,不過截流:
1 | app packet -> policy route / nft -> tun0 -> sing-box -> direct/proxy |
若規則寫得好,國內地址可排除,境外地址可接管,特定域名可直連。這是數據面。
但測量、DNS、探針、優選,另屬控制面。控制面若也入 TUN,便會自噬:
1 | 用被代理污染之路,測是否該代理 |
此事一亂,症狀便成:
1 | ping 看似不通 |
非工具不行,乃路未分。
二、要訣在 mark 與路
Linux 之妙,在於 packet 可被標記,可入異表,可行異路。
例如 sing-box 常有 bypass mark:
1 | fwmark 0x2024 -> goto nop |
若一股流量帶此 mark,便不再入 TUN。此即免代理之符。
故有三法:
1 | mark 其流,使其免 TUN |
第一法輕,第二法正,第三法最清。
三、淨土之形
我後來取第三法:造一個 Linux network namespace。
1 | netflaplab netns |
其 nft 規則大意如下:
1 | iifname "veth-netflap" meta mark set 0x2024 |
於是,在淨土中執行:
1 | sudo net-flap-lab run curl -4 --noproxy '*' https://timicc.com |
其流向不經 host app OUTPUT,不入 sing-box TUN,不吃代理環境。它只走底層 Wi-Fi 與運營商出口。
此時再測,方可知真相:
1 | host probe 異常,lab probe 正常 -> TUN / 本機策略污染 |
四、smartdns 亦同理
若置於 OpenWrt,法亦相同。
smartdns 不應被全局代理吞掉。它該見真網,方能作真優選。
可用:
1 | iptables/nft mark |
核心不是某插件,而是這幾問:
1 | packet 從何來? |
能答此五問,TUN 與 smartdns 便不再相剋。
五、為何不直接用容器
Docker、Podman、systemd-nspawn、bubblewrap、unshare 皆可借力,然皆非終局。
因真正要定者,是本機之路:
1 | 出口網卡是 wlp4s0 |
通用工具不知此機之法。故只需薄封裝:
1 | ip netns + veth + nft mark + NAT |
小而明,可查,可刪,可復現。
六、今日所悟
昔日在恩山翻帖,常見眾人言:裝此插件,套彼規則,改某 DNS,玄學可解。其實多半未觸其本。
真本不玄:
1 | 欲測真網,先造真網之路。 |
TUN 可全局接管,smartdns 亦可真網優選。二者可共存,只須分道。
道分,則不亂。