配图: grey metal chain on white background photo – Free Chain Image on Unsplash
家里的宽带给了 IPv6,就开了,开了之后发现访问一些国外有 AAAA 记录的网站特别慢,因为用的 OpenClash,所有看了一下,OpenClash 并没有代理 IPv6 流量,作者也确认了,这样就导致这些有 IPv6 地址的网站走了直连,而直连被干扰不说,IPv6 的国际出口目前(2021 年初)不到 100Gbps,实在是小水管,所以直连不靠谱。
关了 IPv6 就不行了?作为一个尝新党,不太想关掉,国内网站像豆瓣斗鱼等 IPv6 支持都不错,那还是想办法让 Clash 接管 IPv6 流量吧,最后就有了这个 PR
做这个 PR 的时候,看到这个场景的资料比较少,一方面是 IPv6 现在还不是很普及吧,另外就是 REDIRECT 对 UDP 的支持似乎不太好,各种工具对 UDP 的支持都不约而同的选择了 TProxy,而 Clash 添加 TProxy 支持比较晚,相关资料不多,,因为之前用过一段时间 Passwalll,这个的 IPv6 支持很完善,所以参考 Passwall 做了一版,第一次适配的时候步子迈大了又不熟悉 iptables,失败了,第二次一点点试,发现也用不了几条命令,总结如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
# TProxy 监听端口,接收使用 TProxy 转发过来的流量
tproxy_port=xxxx
# 需要被转发的流量打上这个标记
PROXY_FWMARK="0x162"
PROXY_ROUTE_TABLE="0x162"
# 不转发的 IP,这里只收集了局域网 IP,同理可以过滤掉大陆 IP
ipset create localnetwork6 hash:net family inet6
ipset add localnetwork6 ::/128
ipset add localnetwork6 ::1/128
ipset add localnetwork6 ::ffff:0:0/96
ipset add localnetwork6 ::ffff:0:0:0/96
ipset add localnetwork6 64:ff9b::/96
ipset add localnetwork6 100::/64
ipset add localnetwork6 2001::/32
ipset add localnetwork6 2001:20::/28
ipset add localnetwork6 2001:db8::/32
ipset add localnetwork6 2002::/16
ipset add localnetwork6 fc00::/7
ipset add localnetwork6 fe80::/10
ipset add localnetwork6 ff00::/8
ip6tables -t mangle -N openclash
ip6tables -t mangle -F openclash
ip6tables -t mangle -A openclash -m set --match-set localnetwork6 dst -j RETURN
ip6tables -t mangle -A PREROUTING -j openclash
ip6tables -t mangle -N openclash_output
ip6tables -t mangle -F openclash_output
ip6tables -t mangle -A openclash_output -m set --match-set localnetwork6 dst -j RETURN
ip6tables -t mangle -A OUTPUT -j openclash_output
ip -6 rule add fwmark "$PROXY_FWMARK" table "$PROXY_ROUTE_TABLE"
ip -6 route add local ::/0 dev lo table "$PROXY_ROUTE_TABLE"
# 防止出现死循环
ip6tables -t mangle -A openclash_output -p tcp -m owner ! --uid-owner 65534 -j MARK --set-xmark "$PROXY_FWMARK"
ip6tables -t mangle -A openclash_output -p udp -m owner ! --uid-owner 65534 -j MARK --set-xmark "$PROXY_FWMARK"
ip6tables -t mangle -A openclash -p tcp -m comment --comment "\'默认\'" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
ip6tables -t mangle -A openclash -p udp -m comment --comment "\'默认\'" -j TPROXY --on-port "$tproxy_port" --tproxy-mark "$PROXY_FWMARK"
|
在 openclash 链上,进行一些过滤操作,如局域网和大陆 IP 段 RETURN 掉,对需要转发的流量进行转发,在 openclash_output 链上,进行打标记操作,这里需要注意的是做了一个特殊的操作,过滤掉了 65534 这个 uid 的流量,而 65534 就是运行 Clash 的用户,避免出现 Clash 接管流量匹配规则等一通操作过后,给代理发的包再次被转发,形成死循环,这只是一种方法,还有一些方案通过不转发特定端口,都可以吧,避免死循环就可以。