无线双拨
目标
在我宿舍里,有无线校园网覆盖,校园网两个频段的 SSID 分别为 SUDA_WIFI
(2.4 GHz),以及 SUDA_WIFI_5G
(5 GHz)。在晚高峰时段,网络会存在 QoS 限流。参考家庭宽带的双拨操作,我想要在路由器上实现类似的多路无线中继以提升网速。
标题所述的无线双拨其实并非准确,无线中继和拨号没有任何关系。准确的叫法应该是双路/多路无线中继负载均衡,然而出于简洁和好听的目的,就用无线双拨/多拨这个名字好了。
准备 & 前情提要
关于前情提要,可以参考我去年写的一篇博客:小米路由器mini 自制NAS。在这篇博客中,我使用一台小米路由器 mini,刷上 PandoraBox 系统以后实现各种骚操作。
硬件
一台小米路由器 mini。官网参数说明:https://www.mi.com/miwifimini/param 。OpenWrt 设备页面:https://openwrt.org/toh/xiaomi/mini 。
简单总结:
- 联发科 MT7620A 处理器
- 16 MB ROM,128 MB RAM
- 2.4 GHz 以及 5 GHz 天线均为 2*2 MIMO
- WAN * 1,LAN * 2,USB 2.0 * 1
固件
由于在 PandoraBox 中,无线中继存在 bug(参考博客 小米路由器mini 自制NAS),因此这次准备采用更加开放的 OpenWrt 系统。在官网下载固件,链接:
稳定版(18.06.4):https://downloads.openwrt.org/releases/18.06.4/targets/ramips/mt7620/
开发预览版:https://downloads.openwrt.org/snapshots/targets/ramips/mt7620/
在页面中找到 miwifi-mini-squashfs-sysupgrade.bin
或是 xiaomi_miwifi-mini-squashfs-sysupgrade.bin
,下载固件并上传到路由器。由于我在稳定版中遇到了某些奇怪的 bug,故采用了开发预览版。
刷机流程可以参考 OpenWrt 上的设备页面,这里提供简单总结:
(如果是原生固件的话,首先需要使用小米官方工具解锁 SSH 权限,详情参考博客 小米路由器mini 自制NAS)
首先确定固件所在分区名。使用指令 cat /proc/mtd
可以查看所有分区的名字。在我的设备上,小米原生系统的固件分区名为 OS1
,PandoraBox 和 OpenWrt 的固件分区名为 firmware
。
因此,原生固件刷 PandoraBox / OpenWrt 的指令为:
mtd -r write /path/to/the/firmware.bin OS1
PandoraBox / OpenWrt 互刷指令:
mtd -r write /path/to/the/firmware.bin firmware
如果系统保持不变,则可以直接使用 LuCI 网页管理界面升级。
注:PandoraBox 刷机/重置完成后默认打开 WIFI,而 OpenWrt 默认不启用 WIFI,记得准备网线。
软件
需要安装的软件包:
- luci luci-i18n-base-zh-cn luci-theme-material
- mwan3 luci-app-mwan3 luci-i18n-mwan3-zh-cn
- coreutils-base64 curl
第一组是基础软件包,分别是网页管理界面 luci,中文语言包和 material 主题。预览版系统并不内置 luci,需要自行安装。
第二组是负载均衡所需的 mwan3,以及 luci 中的 mwan3 管理界面。
第三组是自动网关登录脚本的依赖,按需安装。
双路无线中继负载均衡
无线中继
无线中继的方法在博客 小米路由器mini 自制NAS 中已经有过说明。由于两张网卡均为 2*2 MIMO,因此无法对单个频段做多路中继,只能在两张网卡上分别中继一路信号。假如有支持更多 MIMO 的网卡,可以试着更多路的无线中继。
流程总结:
- 在
无线
选项卡中,分别在 2.4 GHz 和 5 GHz 网卡上点击添加,在无线列表中加入对应的网络。这个操作会新建一个网卡,防火墙区域
需要选在 wan 网卡所在的区域。重置无线配置
选项勾选的话会删除现有的 WIFI,如有需要可以勾选。 - 在
基本设置
选项卡中确保模式为客户端 Client
模式,在无线安全
选项卡中设置好网络的账号密码。信号的发射功率上限可以通过高级设置
中把国家代码设置成 US 来提升。 - 分别在 2.4 GHz 和 5 GHz 网卡中添加新的 WIFI,确保模式为
接入点 AP
。当然,如果没有 2.4 GHz 频段的需要的话,也可以只使用 5 GHz 的网络避免信道拥挤。(如果第一步没有删除之前存在的网络,则不用再做这一步) - 至于 IPv6 的中继,需要在网卡里另外手动添加 DHCPv6 客户端以接通 IPv6 上游。然而我校校园网的 IPv6 分配策略貌似是一个设备只分配一个地址,而非 DHCP-PD,NDP 代理也不起作用,因此中继 IPv6 唯一的方法是丑陋的 NATv6。不过 IPv6 目前还并非刚需,用 NAT6 还不如不用。
- 这时候你应该已经能够上网了。当然,只要有一张网卡已经加入无线网络,所有的 LAN 口 / WIFI 就都能够访问网络了。当设置两张网卡都进行无线中继的时候,网络流量会走哪个无线就取决于路由表了。由于不清楚固件底层的实现,路由器会使用哪个无线网络在我看来基本是个玄学。但这不重要,马上就来解决。
负载均衡
在两张网卡都加入无线网络后,就可以使用 mwan3 进行负载均衡了。进入 网络 -> 负载均衡
选项卡进行设置。在这底下一共有 6 个选项卡,我们一个一个来设置。
全局
。这个不用动,跳过即可。接口
。这里添加的是所有参与负载均衡的网络接口。我在设置无线中继的时候,SUDA_WIFI
对应的网络接口名为wwan24
,SUDA_WIFI_5G
对应的网络接口名为wwan
,因此需要把wwan
和wwan24
添加到这里。配置中需要设置跟踪的主机或 IP 地址
,也就是用来检测网络是否可用的地址,可以设置成公共 DNS。mwan3 会自动每隔一段时间 ping 一下这一个或多个地址,在失败一定次数(可以自行设置该参数)后认为接口离线。成员
。这里设置的是每个接口的权重。权重分为两种,一个叫做跃点数
,另一个叫做比重
。权重的计算规则为, “拥有较低跃点数的成员将会被优先使用,拥有相同跃点数的成员把流量进行负载均衡”。这里,我们想要的是两个接口做负载均衡,因此都把跃点数设置为 1,而比重分别设置为 1 和 3(更多的流量分给比较快一点的SUDA_WIFI_5G
)。策略
。这里是负载均衡的策略,用于对接口成员进行分组。由于这里只需要对两个接口做负载均衡,因此只需要一条策略,把两个接口成员添加进去即可。规则
。这里用于指定哪些流量使用哪些策略。我们并没有这些需求,因此简单把所有流量都转发到刚刚那条策略即可。如果有特定流量需求的则可以在这里设置。通知
。在这里可以编写一个自定义脚本/etc/mwan3.user
,用于指定特定接口事件时的操作。我们可以利用这个脚本做自动接口登录,详见下文。
完成这一系列设置后,我们的网络就成功进行了多线负载均衡。可以进入到 状态 -> 负载均衡
选项卡查看当前接口状态,流量分配情况,以及进行网络诊断。另外,也可以根据 网络 -> 接口
页面中各个接口的流量来判断负载均衡是否在正常运作。
对于更详细的配置说明,可以参考官方文档:https://openwrt.org/docs/guide-user/network/wan/multiwan/mwan3 。
自动任务
开机脚本
在 系统 -> 启动项 -> 本地启动脚本
中可以设置启动脚本。我想要的是每次开机都自动向网关发送一个登录请求,因此在启动脚本中添加以下指令:
1sleep 30 && /root/wg-login.sh
每次开机都会等待 30 秒,等待网络设备就绪后执行登录脚本。
登录脚本可以参考该 GitHub 项目:https://github.com/SteveHawk/suda-wg 。
计划任务
在 系统 -> 计划任务
中可以轻松编辑 crontab 中的计划任务。
1# Login suda wifi at 27min of every hour
227 * * * * /root/wg-login.sh
3
4# Reboot at 3:33am every day
5# Note: To avoid infinite reboot loop, wait 70 seconds and touch a file
6# in /etc so clock will be set properly to 3:34 on reboot before cron starts.
733 3 * * * sleep 70 && touch /etc/banner && reboot
两个计划任务,分别是每小时 27 分登录一次网关,以及每天 3:33 重启路由器。为了避免重启死循环,需要使用如上这样的重启指令。
不过我已经禁用了自动登录任务,因为它可以由接下来这个更好的方案来取代。
接口下线事件
仔细想想,登录网关这事情完全没必要每个小时执行一次,只需要在检测到接口下线的时候发送登录请求不就行了嘛。mwan3 的 通知
功能就正好可以用来实现这个目的。
通知页面的这个脚本 /etc/mwan3.user
会在 netifd hotplug 接口事件时执行。换句话说,任何一个接口上线 / 下线事件都会触发这个脚本执行一次。这个功能的本意是用来在接口上线 / 下线的时候给用户发送邮件等提醒,不过我们也可以拿来做自动网关登录。
脚本能够获取到三个环境变量,分别是 $ACTION
,$INTERFACE
和 $DEVICE
。$ACTION
共有四种值,分别是 ifup
,ifdown
,connected
,disconnected
。而 $INTERFACE
和 $DEVICE
可以分别用来获得当前触发脚本的接口和设备名。
利用这几个环境变量,可以编写出如下脚本:
1#!/bin/sh
2#
3# This file is interpreted as shell script.
4# Put your custom mwan3 action here, they will
5# be executed with each netifd hotplug interface event
6# on interfaces for which mwan3 is enabled.
7#
8# There are three main environment variables that are passed to this script.
9#
10# $ACTION
11# <ifup> Is called by netifd and mwan3track
12# <ifdown> Is called by netifd and mwan3track
13# <connected> Is only called by mwan3track if tracking was successful
14# <disconnected> Is only called by mwan3track if tracking has failed
15# $INTERFACE Name of the interface which went up or down (e.g. "wan" or "wwan")
16# $DEVICE Physical device name which interface went up or down (e.g. "eth0" or "wwan0")
17
18if [ $ACTION == "disconnected" ]
19then
20 if [ $INTERFACE == "wwan" ]
21 then
22 mwan3 ifdown wwan24
23 mwan3 ifup wwan
24 source /root/wg-login.sh
25 logger "Interface wwan execute login."
26 elif [ $INTERFACE == "wwan24" ]
27 then
28 mwan3 ifdown wwan
29 mwan3 ifup wwan24
30 source /root/wg-login.sh
31 logger "Interface wwan24 execute login."
32 fi
33 mwan3 ifup wwan
34 mwan3 ifup wwan24
35fi
我们想要做的事情,是在每次接口下线的时候,向这个接口发送网关登录请求。但是由于接口下线事件触发的时候,mwan3 会自动把路由表导向另一个在线的接口,这让我们无法把登录请求发向已下线的接口。所以我在这个脚本里做的,就是在一个接口下线的时候,先手动让另一个接口下线并让当前接口上线,这个时候路由表就会指向实际下线的这个接口;此时顺势发送网关登录请求,然后再让两个接口恢复上线。
于是,在任何一个接口下线的时候,路由器都会自动发送登录请求让它重新上线。只要不是触发了网关的保护措施(我校网关貌似有连接时长限制,超时不会断开,但是会没网),我的路由器就可以轻松实现 24 小时在线啦。
DNS 重绑定攻击の坑
最后,需要提一嘴踩到的一个坑。先来讲讲发生了什么。在刷完 OpenWrt 并做完单路无线中继后,我试着访问校园网网关的页面,但是怎么也上不去。到系统日志里翻看了一下,出现了非常可疑的记录:
daemon.warn dnsmasq[904]: possible DNS-rebind attack detected
欸,什么是 DNS 重绑定攻击(DNS rebinding attack)?
简单来说,在执行 DNS 重绑定攻击的时候,攻击者先会向用户发送一个 TTL 非常短的解析记录,解析到包含恶意代码的网站上。恶意代码执行后会创建第二个 DNS 请求(因为上一个记录的缓存已经超时),这时攻击者可以返回一个内网 IP 的解析记录。这样攻击者就可以轻松访问到原本无法访问的内网内容了。
为什么我会踩到这个坑?我们来仔细看一下 DNS 重绑定攻击的流程,其中有两个可以填的漏洞,一个是超短 TTL 的 DNS 记录,另一个是解析到内网 IP 的 DNS 记录。超短 TTL DNS 记录的防护可能在浏览器端进行会比较好,而路由器端能做的就是拦截解析到内网 IP 的 DNS 记录。
巧的是,我校校园网网关地址 a.suda.edu.cn
解析得到的地址是 10.9.0.30
,这是一个 A 类的内网 IP 地址。真相大白。
解决方案有两种,一个是给域名添加白名单,另一个是禁用防护。因为我们校园网内不止一个内网网站,因此直接禁用防护是更好的选择。在 网络 -> DHCP/DNS -> 基本设置
选项卡中,可以看到有一个 重绑定保护
的选项。取消勾选即可。
至此,整个路由器的配置就完成了。能够 24 小时在线,不必每个设备都手动登录网关,还有双路负载均衡,这也太爽了!😍
#tech notes
本文总字数 4369
本文阅读量
本站访客量