解决旁路由痛点:一种更优雅的科学上网方案

159 天前
 madsword

前几天发在了友站想想还是转载过来这里,总不能天天白看 v2 的帖子。。 顺便加点高级玩法在后面。

现在上网标配的双路由,双软路由其实很多时候配置旁路由仅仅是为了实现科学上网。有了软路由就是要各种折腾有时候折腾下分流网也 boom 了,或者旁路由装在 nas allinone ,nas 一重启一折腾也跟着 boom 了,一人折腾全家断网。还有一个常见的麻烦一旦将设备的网关指向旁路由,很多人会因为缺少 SNAT (源地址转换)的设置,导致原本通过主路由端口映射访问的设备在外网无法连接,这给日常使用带来了不便。究其原因,在于主路由通过端口映射将流量直接转发给了设备,而设备的网关却指向了旁路由。这样一来,回程的流量就被旁路由接管,但旁路由并不了解主路由的端口映射规则,最终导致连接中断,设备无法访问。关于 SNAT 的设置,网上有很多教程,这里就不再赘述。

本文将重点介绍另一种科学上网的思路:所有设备的网关都指向主路由,无需进行复杂的双网卡双 OP 配置。无论旁路由是不是 BOOM 了,都不会影响到所有设备的正常网络连接。本文推荐使用 OpenWrt 主路由搭配 AdGuard Home ( ADG )和 mihomo (进阶玩法可结合 SmartDNS 进行分流)。

考虑到 OpenWrt 系统的易用性和全面的功能,我们优先选择 OpenWrt 作为主路由。

旁路由配置:

如果已经有 OpenWrt 旁路由,可以直接运行 mihomo 、NekoRay 等软件。或者在虚拟 Debian 、LXC 、Docker 等容器环境下安装 mihomo (在 Docker 和 LXC 这类容器环境中,请务必开启 TUN 设置)。

接下来,配置 mihomo 的 config.yaml 文件:

YAML

dns:
  enable: true
  cache-algorithm: arc
  prefer-h3: true
  listen: :53
  ipv6: true
  use-hosts: true
  respect-rules: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - '+.lan'
    - '+.local'
    - "rule-set:googlefcm"
    - "rule-set:wechat"
    - "rule-set:chinamedia"
    - "rule-set:douyin"
    - "rule-set:speedtest"
    - "geosite:cn"
  default-nameserver:
    - 192.168.0.3
  nameserver-policy:
    'rule-set:google,youtube': [https://1.1.1.1/dns-query#🇺🇸美国, https://8.8.8.8/dns-query#🇺🇸美国]
  nameserver:
    - 192.168.0.3
  proxy-server-nameserver:
    - 192.168.0.3
  direct-nameserver:
    - 192.168.0.3
  fallback-filter:
    geoip: true
    geoip-code: CN
    geosite:
      - gfw
    ipcidr:
      - 240.0.0.0/4
    domain:
      - '+.google.com'
      - '+.facebook.com'
      - '+.youtube.com'

(由于我搭建了 SmartDNS 服务器,所以 mihomo 的 DNS 上游设置指向了它。这个 SmartDNS 主要用于防止 DNS 泄露并下发准确的 IP 地址。)

强烈建议在 fake-ip-filter 中包含以上规则集,以便 mihomo 能够直接下发所有国内直连域名的双栈 IP 地址。这样,内网设备可以直接通过主路由访问这些域名,无需再绕行旁路由。这里需要注意的是,由于开启了 IPv6 ,内网设备在访问境外域名时,一旦获取到 IPv6 地址,很可能会直接通过主路由网关访问而导致连接失败。因此,mihomo 对非中国大陆地区的域名一律下发 Fake IP ,配合主路由的后续设置,即可实现国内外流量各取所需。

回到 OpenWrt 的设置:

在 OpenWrt 后台,进入 网络 -> DHCP/DNS -> 设备和端口,将 DNS 服务器端口 更改为 0。这一步是为了在后续安装 AdGuard Home 时,允许 ADG 直接监听 OpenWrt 的 53 端口。

接下来,在 OpenWrt 的官方软件源中安装 AdGuard Home 。安装完成后,进入 AdGuard Home 的管理界面,点击 设置 -> DNS 设置

重要提示:OpenWrt 切记不要下发 IPv6 DNS !

进入 网络 -> 接口 -> lan,修改 DHCP 服务器 选项下的 IPv6 设置。将 已公布的 IPv6 DNS 服务器 留空,并取消勾选 本地 IPv6 DNS 服务器

完成以上两个地方的修改后,可以确保内网设备不会受到运营商下发的 IPv6 DNS 的影响,从而保证科学上网的正常进行。

设置完 DNS 后,建议重启一下 OpenWrt ,然后测试一下 DNS 是否正常工作。在终端中执行以下命令:

Bash

nslookup baidu.com
nslookup google.com

检查 baidu.com 是否解析到真实的 IP 地址,google.com 是否解析为 Fake IP 地址(198.18.x.x网段)。如果到这里没有出错,就可以进行下一步了。

在 OpenWrt 下添加静态路由:

进入 网络 -> 路由 -> 静态 IPv4 路由,添加一条新的静态路由。

完成以上设置后,你可以尝试让设备通过 DHCP 自动获取 IP 地址,或者手动指定设备的网关和 DNS 服务器为 192.168.0.1。然后测试访问国内和国外的域名,看是否能够成功访问。

====================================================================================

彩蛋时间:Telegram 用户特别优化

由于 Telegram 的特殊性,其连接主要依赖 IP 地址。如果你是 Telegram 用户,可能需要在路由表中添加以下 IP 地址段,方法与之前添加 198.18.0.0/16 的静态路由类似。你可以简单地点击复制下面的 IP 段,然后在 OpenWrt 的静态路由设置中修改目标网络 IP 地址即可:

91.108.56.0/22
91.108.4.0/22
91.108.8.0/22
91.108.16.0/22
91.108.12.0/22
149.154.160.0/20
91.105.192.0/23
91.108.20.0/22
185.76.151.0/24

同样地,Telegram 也会对 IPv6 地址段发起请求。考虑到 IPv6 配置的复杂性,我们在这里不进行 IPv6 的路由设置,而是通过在防火墙中拒绝 Telegram 请求的特定 IPv6 地址段,从而避免潜在的影响。

你可以通过编辑 OpenWrt 的防火墙配置文件 /etc/config/firewall,在文件末尾添加以下配置,或者通过 LuCI 界面手动设置防火墙规则(请务必注意目标接口是否为 wan):

config rule
        option name 'tg_v6_reject'
        option src '*'
        option dest 'wan'
        list dest_ip '2001:b28:f23d::/48'
        list dest_ip '2001:b28:f23f::/48'
        list dest_ip '2001:67c:4e8::/48'
        list dest_ip '2001:b28:f23c::/48'
        list dest_ip '2a0a:f280::/32'
        option target 'REJECT'

添加以上配置后,记得保存并应用防火墙设置。这样,你的 Telegram 应用应该也能正常使用了。

终极用法+1: 在外面的话设备不再需要找各种科学工具,只要下一个 wg ,allowed ips 写上 wg 网段,内网网段,fakeip 网段,tg 网段,然后 wg 的 dns 设置为内网主路由 ip 即可。 就能做到国内直连流量从手机直接访问,科学流量回家分流。 家里上行带宽够的话可以试试的!

8583 次点击
所在节点    宽带症候群
45 条回复
zha0w
158 天前
太专业了,之前从油管上学习一个双 adg 的方案,跑了几个测 dns 泄漏的网站,实测都没有泄漏,但会出现一些奇葩的问题,比如说我 ios 可以连上 wifi 且可以联网( wifi 助理功能已关),但三星手机连上 wifi 也说没有连通网络。
user100saysth
158 天前
太专业了,感觉门槛有点高
yeh
158 天前
adguard + mosdns + surge 1 年多了

是不是 openwrt 当主路由无所谓,硬路由可以配置网关和静态路由转发 fakeip 的就可以。

旁路由花式就多了,nas 可以,arm 的啥的都可以,反正起 docker 而已。
nguoidiqua
158 天前
可以了解下 iStoreOS 的浮动网关:

<amp-youtube data-videoid="tk9loLTyxyk" layout="responsive" width="480" height="270"></amp-youtube>
<amp-youtube data-videoid="7Z6l2VLD3l8" layout="responsive" width="480" height="270"></amp-youtube>&t=315s

简单来说就是它可以在主路由指定某些设备用旁路由作为网关,并检测旁路由状态。

如果旁路由挂了,它会自动把这些设备的网关指向自己,旁路由恢复之后它又会把这些设备的网关指向旁路由。
life90
158 天前
应该介绍下 openwrt 使用的是 x86 还是 arm 。这两者的便利性天差地别。
yyysuo
158 天前
mihomo 的 dns 不如 sing-box 自由,要更自由,上 mosdns 就行了,旁路用 linux 不好吗,用 openwrt 太复杂了。
letmefly
158 天前
还挺复杂的,有空的时候研究一下。现在对科学没什么兴趣,只要能用就够了,不想搞那么麻烦。
linyuhang24
158 天前
双软路由方案不是很成熟吗?说的就是楼主这个主路由+根据路由规则转发旁路由的思路,都用好几年了,现在怎么成了新思路?
Lentin
158 天前
看了一下 这个就是交换机的 VRRP 功能额……玩法越来越花了
playboy0
158 天前
ipv6 能正常使用吗?谢谢
madsword
158 天前
@yeh 一般硬路由没法做到不下发 v6dns ,还是会影响的
madsword
158 天前
@nguoidiqua 在主路由分流主要是为了能让 wg 回家的设备能获取到 fakeip 直接在外面分流只让科学流量回家。
madsword
158 天前
@playboy0 正常
huaxie1988
157 天前
旁路由不要开 nat 地址转换就没你说的问题了
Ipsum
157 天前
已经用了快 4 年了。之前给他们说不要指向旁路由,用 fakeip 来分流,那些人都不听的。另外记得把 fakeip 持久化,不然 clash 崩了就是灾难。
zbatman
157 天前
/t/981677

23 年发的
madsword
157 天前
@Ipsum 我 adg 这里不缓存 fakeip ,adg 有个备用 doh 崩了就由他顶上。 随时重启小猫都不怕 fakeip 错乱
madsword
157 天前
@zbatman 👍
Ipsum
157 天前
@madsword #17 不是 adg 缓存,是 clash 开持久化。
383394544
157 天前
这是正确的思路,不是新思路。你会认为新无非是以前的人不重视,没流行开而已。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1121556

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX