问题现象
在我的局域网中跑了一台DebianNAS192.168.0.102以及一台OpenWrt192.168.0.101旁路由,其中NAS网络接口配置如下:
auto lo
iface lo inet loopback
auto ens18
iface ens18 inet static
address 192.168.0.102/24
gateway 192.168.0.101
dns-nameservers 192.168.0.101可以看到网关和DNS服务器地址均指向192.168.0.101(软路由地址),然而在我尝试Ping Google.com时却出现以下问题:

何为ICMP Redirect
可以从图中清晰看到 Redirect Host(New nexthop: 192.168.0.1) ,ICMP Redirect 可以理解成路由器发给主机的一种“路线纠正通知”。
DebianNAS -> OpenWrt -> Router
<————————————|发现捷径 回报网关IP我们可以这样理解:手工配置的上级网关在进行下一跳转发时发现了可达的捷径,于是乎通过ICMP协议向请求主机返回这一推荐网关。
普通网络场景下的ICMP Redirect是合理的
ICMP Redirect作为一种路由优化机制,在特定场景下可以削减路由转发次数进而提升网络转发效率。但在本文实践当中极有可能会使NAS中的网络请求绕过旁路由网关,我们本意是想让OpenWrt旁路由代理NAS流量,由于ICMP Redirect的出现使得NAS中的数据报绕过预先设定好的转发路线直接到达最终网关,最终导致Clash代理服务失效。
解决方案(2选1)
代理主机(NAS)侧
cat > /etc/sysctl.d/99-no-icmp-redirect.conf <<'EOF'
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.default.accept_redirects=0
net.ipv4.conf.ens18.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.ipv4.conf.default.secure_redirects=0
net.ipv4.conf.ens18.secure_redirects=0
EOF
sysctl --system其中ens18为网卡名称,可以通过ip a进行查看。
旁路由侧(推荐)
cat > /etc/sysctl.d/99-no-send-redirect.conf <<'EOF'
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.default.send_redirects=0
net.ipv4.conf.br-lan.send_redirects=0
EOF
sysctl --system其中br-lan为网卡名称,可以通过ip a进行查看。
最终效果

fake-ip 模式下,域名会被解析到一个虚拟 IP,Clash 主要接管 TCP/UDP 连接;而 ping 使用 ICMP,所以 ping google.com 超时不能说明 HTTPS 不通。
这不能直接证明代理已经完全生效,但可以说明 NAS 的 DNS 解析已经进入了旁路由Clash 的 fake-ip 处理链路。
接下来需要更加严谨的测试:
curl https://www.google.com响应如下:
<!doctype html>
<html itemscope="" itemtype="http://schema.org/WebPage" lang="ko">
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<title>Google</title>旁路由不是最短路:ICMP Redirect 在 Clash 网关场景里的坑
https://blog.oceanparadise.cn/archives/FFoYCKGh
评论