Real-IP Tun Example
Real-IP 模式的复杂性主要来自于两个方面:
如何使得 Clash Outbound 还能正确的连接互联网
如何使得 DIRECT 出口的流量不要经过 Tun NIC 回到 Clash 造成回环
很显然,不能使用添加 Default 路由到 Tun NIC 的方式使用 Clash Tun 模式。否则 Clash 将无法连接远程代理服务器。
需要注意的是,当 Clash 作为网关工作,如果运行 Clash 的主机本身并不需要通过 Tun 代理,仅仅是转发其他设备的流量,那么上述两个复杂性将不会存在,相应的也会后更简单的配置方法。
本章将以运行 Clash 的 Linux 的主机本身也需要代理的条件下,给出一个使用方法。
解决思路
将 Clash 运行在一个单独的用户下,用以给操作系统一个区分网络流量是否是 Clash 发出的特征。
使用 iptables 在 mangle 表中,将流量打上 fwmark,再由 IP rule 决定将这些有 mark的 流量使用策略路由 (policy route)将流量转发给 Tun NIC。
在 mangle 表 OUTPUT 链中使用
uid-owner
排除 Clash 发出的流量在 mangle 表 PREROUTING 中,将其他设备发来的流量打上 fwmark
实施方案
假设 clash 运行在 alice 用户下,该用户的 UID 为 129,我们 fwmark 也用 129,clash 策略路由的路由表 id 也为 129。
用户 uid,fwmark ,路由表 id 是三个不相关的值。这里仅仅是为了举例方便都设置成 129.
创建NIC
配置 iptables 和 ip rule 前最好提前配置好 Tun NIC 并 bring up。创建 NIC 的方法可以参考前面的部分。
这里假设 Tun NIC 已经提前创建好,名称为 clash0
,owner 也为 alice,并且已经被 bring up.
配置 iptables
首先在 mangle 表中创建 CLASH 链,主要用于排除一些局域网地址。如果你会使用 ipset ,可以参考下面被注释的 chnroute
项,排除一些国内地址。
然后在 PREROUTING 链中,给所有转发(forward)流量打上 fwmark。PREROUTING 链的流量来自于其他设备。如果有必要,可以限制高目标端口以防止 BT 流量被转发到 Clash
最后在 OUTPUT 链中,将本机外出流量打上 fwmark。
下面添加策略路由,使得被打上 fwmark 的流量交由特定路由表(129)处理,并转发到 Clash 监听的 Tun NIC 上。
可以用 ip route
验证下策略路由是否生效
返回应和下面类似,注意加粗的部分。0x81 是 129 的 16进制表示。
1.2.3.4 dev clash0 table 129 src 192.168.31.194 mark 0x81 uid 1000 cache
排除 rp_filter 的故障
这时,如果 clash 已经启动,可以验证下 clash 能否正常工作了。如果不能,可以使用 tcpdump -n -i clash0
抓包诊断下,如果看起来 clash0
端口两个方向的包都有,有可能是 Linux 的 rp_filter
导致了问题。
rp_filter 是 Linux 的安全功能。 rp_filter 会在计算路由决策的时候,计算包的反向路由,也就是将包中的 源地址和目的地址对调再查找路由表。由本机或者其他设备流向 clash0
的 IP Packet一般不会有问题,但是当 rp_filter 检查 clash0
流出的包时,由于这些包不会带有 fwmark,检查反向路由时不会走刚才定义的策略路由,导致 rp_filter 检查失败,包被丢弃。
解决方法时关闭 clash0
NIC 的 rp_filter
功能。
将 all.rp_filter
设置为 0
是必须的。
将 all.rp_filter 设置为 0
并不会将所有其他网卡的 rp_filter
一并关闭。此时其他网卡的 rp_filter
由它们各自的rp_filter
控制。
Last updated
Was this helpful?