折腾路由器
上回给路由器配置了自动联网(也就是个Bash脚本),稳定的跑了两年,终于在我作死设IPv6过程中被搞砸了。近日被迫重新配置OpenWrt,也算是彻底解决了我在紫荆公寓区上网的所有需求;鉴于网上找到的资料鱼龙混杂,索性把自己的步骤记录一下,以飨读者。
0. 配置WAN口
由于我用的路由器是TL-WR703N,只有一个网线口,在OpenWRT初始设置下算LAN,因此首先开启Wi-Fi设置密码,然后把网线口重新设置成WAN;在此不做赘述。
参考:OpenWrt官方Wiki
进阶:折腾教程
1. 搭建DNS隧道
学校的计费系统在登录之前会限制IPv4流量,因此外网流量需要通过UDP53端口;在路由器上和外网VPS上分别从官方软件源安装iodine,即可顺利建立隧道。此时路由器出现新接口
dns0
,具有IP地址10.0.0.2
,可以直接ping通10.0.0.1
(VPS)。在VPS上需要设置一行简单地路由表:
iptables -A POSTROUTING -s 10.0.0.0/8 -j MASQUERADE
。这时,已经可以通过VPS作为路由来转发数据包。
参考:iodine官方指南
2. 配置代理隧道
理论上,这时的路由器已经可以通过把所有流量转发到
dns0
而非eth0
来直接免费上网了。不过,iodine只是使用Shared Secret来加密,并不安全,有必要再设置一层加密代理隧道。在OpenWrt上安装luci-app-shadowsocks以及各种依赖包,将目的地指向
10.0.0.1
,完成配置之后即可在路由器端开启以VPS为出口的SOCKS5代理。
参考:Github
3. 配置透明代理
大部分日常使用的校内网站(网络学堂、流量计费登录认证等)都在同一个网段。直接将
166.111.0.0/16
网段加入Bypass List(保存成一个文本文档),然后在luci界面完成设置,对所有其他网站启用透明代理。
4. 发心跳包
撰写一个简单的bash脚本,检查国内外网络联通性,并在网络故障时自动尝试重启所有隧道服务。使用Cronjob(运行
crontab -e
)添加定时任务,每五分钟检查一次,同时每周清除一次日志。
5. IPv6
除了IPv4流量经过隧道之外,还需要配置IPv6桥接;OpenWrt 15.05自带
odhcpd
,只需将相关配置全部改成relay即可使客户端获得IP。相关设置已可以直接在luci中修改,也可直接在/etc/config/networks
中修改。这时,局域网内客户端可以获取IPv6地址,并可直接ping通外网v6地址(由于透明代理只负责TCP包,未登录计费系统时IPv4 ICMP被丢包,无法ping通v4地址)。
参考:隔壁经验帖
至此,所有配置都已完成,路由器又回到了免维护状态(定期执行软件包自动升级即可)。各个客户端设备仍然可以直接上网,不需要担心登录上线问题;客户端配置不变。
最后,删除路由器端的自动拨号上线脚本——今后已经不再需要登录计费系统(也不再有监控服务器负责远程踢我下线了),可以回到手动上下线的状态。
Future Work
- 学校中遍布Double-IVI(两次双栈翻译)的试验Wi-Fi,不需要计费,原理是分配局域网IPv4地址后通过纯IPv6把数据包发到教育网官方双栈转发服务器(XXX.ivi2.org),以实现局域网内客户端可以访问外网IPv4地址。可以考虑在路由器上添加双栈翻译Kernel Patch,然后进行相同的转发,合法的绕过IPv4计费系统,相当于自己搭建了一个DIVI客户端网络。参考:RFC6219
- DNS污染暂时通过端口映射解决,将路由器53端口直接通过隧道映射至美国的公共DNS;这样每次请求的延迟太大,可以替换为本地运行dnsmasq、上行dnscrypt,并使用chinadns。
- 由于当前配置“搭积木”意味浓厚,网络流量在网络栈的不同层之间反复;简单的上网需要拆成2层(Link)->3层(UDP)->4层(DNS)->2层(iodine)->3层(TCP)->4层(SS)->3层(SOCKS5)->4层(HTTP),十分繁琐。各种操作对带宽的影响不是很大,主要是分包合包带来更高的延迟。能否修改合并两组开源项目的代码,以实现更简单的流量转发?
发表回复