记录一份 OpenWrt 的配置备查,也供大家参考。

硬件

主路由

Netgear R6300 v2,家用全千兆路由器中开源固件支持比较好的一款,性价比也不错。 唯一的问题是无线芯片是 Broadcom 的,OpenWrt 所带的驱动基本等于搞笑,不如关了自带无线,下挂 AP 来提供无线服务。

AP

Netgear R6220,基本上是最便宜的 全千兆 + USB 3.0 路由器了。

ShadowSocks + DNS-Forwarder + ChinaDNS

基本按照 ShadowSocks + ChnRoute 实现 OpenWRT / LEDE 路由器自动翻墙 一文配置。
主要思路为:

  1. 从 APNIC 获取国内分配到的地址段,对该地址段 ShadowSocks 将直接连接不走代理。
  2. Dnsmasq 持有国内有加速的直接解析名单(白名单),直接使用国内 DNS 服务器解析;将解析得到的(国内)地址交给 ShadowSocks 按照第一条判断,或者直接应用直连的 ipset
  3. Dnsmasq 持有已确认无法直接连接的名单(黑名单),直接使用国外 DNS 服务器解析;将解析得到的(国外)地址交给 ShadowSocks 按照第一条判断,或者直接应用转发的 ipset
  4. 不在名单中的域名,ChinaDNS 同时连接国内和国外两处 DNS 服务器进行解析并比对结果,并以国外解析结果为准。

    这里明显看的出来有个坑,有些网站使用了 CDN,国外 DNS 解析出的结果一定会是离代理服务器更近的节点……所以 edns-client-subnet 的支持是必须的。

我部署时有以下改动:

  1. 因为一定会使用 ipset ,所以直接安装 dnsmasq-full
  2. 将 “配置 DNS 转发链的优化配置“ 和 ”China-List 强制直连“ 糅合在一起配置,即在生成 accelerated-domains.china.conf 时,对国内地址在指定 ISP 的 DNS 服务器的同时,应用 ipset ss_spec_dst_bp,强制直连。
    再新建 /etc/dnsmasq.d/bypass.conf 文件,用于手动指定需要强制直连的域名;如果需要,再新建 /etc/dnsmasq.d/forward.conf 文件,用于手动指定需要强制代理的域名。

bypass.conf

server=/synology.com/61.139.2.69
ipset=/synology.com/ss_spec_dst_bp
server=/transmissionbt.com/61.139.2.69
ipset=/transmissionbt.com/ss_spec_dst_bp

forward.conf

#server=/example.com/127.0.0.1#5311
#ipset=/example.com/ss_spec_dst_fw

vxTrans

vxTrans 是 微林 提供的链路级网络加速付费服务。价格大约为 ¥1 / GB。
(微林原域名 vnet.link 貌似已经被墙,code.so 是新的域名。)
这个服务用来解决本地电信连接 Vultr(ShadowSocks 服务器所在)速度慢的问题。
欢迎使用我的 邀请链接 注册。

添加一个连接点,指向 ShadowSocks 服务器和对应端口,再将 vxTrans 提供的加速地址(填写自行解析后的 IP 地址)和端口填入 OpenWrt 上的 ShadowSocks 服务器配置中。这样整个代理链路就是:
本地电信 -> VnetLink节点 -> Vultr -> 目标地址

vxTrans 连接点

OCServ

完成以上配置之后,还需要配置一个拨入路由器的 VPN 服务,实现:

  1. 在外使用公共 Wi-Fi 时的加密;
  2. 在外的自动科学上网需求。

这里我选择了 OpenConnect,其对应的服务端为 OCServ。
配置过程参考此文 OpenWrt路由器搭建和配置ocserv实现VPN客户端智能代理,推荐使用证书登陆。
客户端使用 Cisco AnyConnect 即可。

为了让通过 VPN 拨入的设备也能够自动科学上网,还需要配置一下 ShadowSocks 的访问控制,将 VPN 拨入的设备(vpns+)加入内网范围。
由于 VPN 拨入的设备并不在系统固有的设备列表中,所以 Luci 的配置中默认是看不到的,需要手动修改相关文件。
步骤如下:

  1. 找到 /usr/lib/lua/luci/model/cbi/shadowsocks/access-control.lua 这个文件,打开编辑。
  2. 找到如下所示的这个 for 块,下面最后一行代码就是要添加的内容。
    for _, net in ipairs(nwm:get_networks()) do
         if net:name() ~= "loopback" and string.find(net:name(), "wan") ~= 1 then
                 net = nwm:get_network(net:name())
                 local device = net and net:get_interface()
                 if device then
                         lan_ifaces[device:name()] = device:get_i18n()
                 end
         end
    end
    lan_ifaces["vpns+"] = 'Tunnel interface: "vpns+"'
    

修改完成后,在 ShadowSocks 的访问控制中勾选此项,效果如图:
ShadowSocks 访问控制
现在拨入 VPN 的设备就也可以自动科学上网了。

补充

如果使用了会自动识别外网 IP 的服务,比如群晖的 Quick Connect,或者其他的境外 DDNS 类服务,记得把对应服务的域名加入 bypass 的列表,或者指定这台设备(比如群晖 NAS)使用直连模式(见上图中“内网主机”设置)。
我自己跳过了群晖 和 Transmission 的服务,参考之前 ShadowSocks 配置那一节。
另外还可以配置定时重启或者自动检测连接重启的计划任务,可以参考 Shadowsocks for OpenWRT / LEDE 拾遗 一文。