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

161 天前
 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 即可。 就能做到国内直连流量从手机直接访问,科学流量回家分流。 家里上行带宽够的话可以试试的!

8634 次点击
所在节点    宽带症候群
45 条回复
madsword
158 天前
@383394544 没人认为是新思路吧
chenbin36255
158 天前
这个就是 paopaodns+paopaogateway 那一套的思路
madsword
158 天前
@chenbin36255 不一样的 paopao 本质上它就是一个旁路由 再分流
AxaIA
157 天前
请问在你的环境下,hsr.hoyoverse.com 这个域名解析到 fakeip 上了吗
madsword
157 天前
@AxaIA 没有 fakeip
root@debian:~# nslookup baidu.com
Server: 192.168.10.1
Address: 192.168.10.1#53

Non-authoritative answer:
Name: baidu.com
Address: 39.156.66.10
Name: baidu.com
Address: 110.242.68.66

root@debian:~# nslookup hsr.hoyoverse.com
Server: 192.168.10.1
Address: 192.168.10.1#53

Non-authoritative answer:
hsr.hoyoverse.com canonical name = d3mo07nxll2mjb.cloudfront.net.
Name: d3mo07nxll2mjb.cloudfront.net
Address: 3.165.39.50
Name: d3mo07nxll2mjb.cloudfront.net
Address: 3.165.39.65
Name: d3mo07nxll2mjb.cloudfront.net
Address: 3.165.39.117
Name: d3mo07nxll2mjb.cloudfront.net
Address: 3.165.39.100

root@debian:~# nslookup google.com
Server: 192.168.10.1
Address: 192.168.10.1#53

Non-authoritative answer:
Name: google.com
Address: 198.18.1.187
rulagiti
157 天前
乱七八糟的,看的头痛。
htfcuddles
157 天前
fakeip 有点多此一举,兼容性差,而且上游梯子 boom 了,国外访问照样 boom 。直接用 mwan3 规则转发就行了,注意避免环路就行。
madsword
157 天前
@htfcuddles mwan3 怎么做到梯子炸了国外照样访问的
htfcuddles
156 天前
@madsword #28 可以做 4or7 层健康检查,failover 到 ISP 出口。
titanium98118
156 天前
我用 OSPF
https://github.com/povsister/v2ray-core
旁路由挂了,流量自动回到主路由的 ISP 出口出去
jianv3
156 天前
说白了就是一个 clash 客户端的配置问题 , 一个 openclash 就能搞定的事, 哥们你复杂了
madsword
156 天前
@titanium98118 研究过这个 就是 ipv6 有点头疼
titanium98118
156 天前
@madsword #32 这个应该无解,作者魔改的 v2ray, 除非作者某天加上 ipv6 支持。我自己修改了一下配置:普通域名返回 a 和 aaaa ,gfwlist 的域名只返回 a 。用着也挺好。
warcraft1236
156 天前
说实话我一直觉得在自己的设备上开翻墙软件是最简单且容易控制的方式
Miary
156 天前
粗看了下和 PaoPaoDNS+PaoPaoGateWay 的方案有点像,都是基于 fakeip ,这个方案我用了大半年最后还是放弃了,浏览器访问经常会遇到 Google 无法打开的情况。
starryloki
156 天前
@madsword #32
@titanium98118 #33
IPv6 可以用 OSPFv3 吧
a56143575
156 天前
玩法越来越花了
a56143575
156 天前
mihomo 听说很耗内存
SakuraYuki
155 天前
现在换成 mac mini+surge 了,配置起来方便几个数量级
povsister
155 天前
@starryloki
话是这么说,但是哥们… ospfv3 的库哪有 go 版本的啊?
ospfv2 我手搓了一个部分实现的版本,看 rfc 写协议还是有点头秃的…

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

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

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

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

© 2021 V2EX