最近新入手了一台J4125+4*i220的软路由,在上面安装了ESXi 7.0虚拟机作为底层;Mikrotik的RouterOS作为主路由,负责拨号、QoS和对外防火墙;ESir编译OpenWRT固件作为旁路网关,负责分流去往不同地方的流量走你懂的线路,SmartDNS进行国内DNS解析并优选IP,FakeDNS加快境外DNS解析和防止DNS污染;Debian作为服务器,安装有AdguardHome进行DNS去广告以及反追踪(效果一般),以及其他一些服务。
软路由的挑选
首先毋庸置疑x86平台可玩性绝对比ARM平台要高,可选的固件、插件、软件包都是更多的,性能也会更强,特别是需要魔法上网时x86一般都自带硬件AES加解密。
本来此时已经有i225和8125B这种2.5G网卡,但是思索了一下短期宽带突破千兆概率不大,内网也没必要用路由器来交换,看中了i220的稳定,以及实际上它就是比i225更贵,于是还是买了i220。至于更新的CPU有N5105和N5005,发热太大,感觉意义不大反正都是性能过剩。
最后那天选软路由选到凌晨两点,没发现合适的,可刚要睡觉,突然一位闲鱼卖家上线了它,价格600,立马下了单,然后配了一个64G SSD和8GB内存。
准备工作
系统安装都是正常步骤,就不多说了,此处提几个关键点。
ESXi需要注意的是ESXi7会占用一个超大的128G的虚拟闪存,需要在安装引导时通过指令将其减小,否则很占用硬盘空间。
OpenWRT我选用了eSir编译的固件,可以去他的Google Drive中找,而RouterOS目前使用的是网上的破解版(日后再考虑补票),这种虚拟机破解版要注意安装时不能修改磁盘大小否则授权会失效。
此外就是设置网卡直通,建议将除了ETH0以外的网卡直通给RouterOS,并保持RouterOS的唯一一个虚拟网卡是vmxnet3以获取更好的性能(若无法设置可以将虚拟机操作系统设置为Linux的最高版本)。
在此要注意,需要开启ROS相关联端口组或者虚拟交换机的伪传输和混淆模式才使ROS作为软交换机时正常从虚拟网卡交换数据。
系统启动后进行正常设置,RouterOS将LAN端口绑定在同一bridge下(假设为bridge1),然后WAN上创建PPPoE拨号(假设为pppoe-out1),bridge开启DHCP分配局域网IP,注意将网关指向OpenWRT,而OpenWRT网关指向主路由,然后防火墙NAT表中添加去往pppoe的srcnat链masquerade项即可上网。
VRRP双路由热备
OpenWRT由于具有众多插件,导致系统有时候会不稳定,通过网关热备份可以使得当OpenWRT崩溃时快速切换到ROS主路由器。
此处采用VRRP协议进行热备份,VRRP在RouterOS上设置非常的简单,先在Interfaces中新建一个VRRP网卡,绑定到局域网bridge1,然后随意设置一个VRID例如51,版本改成3,开启Preemotion Mode,其余保持默认即可。最后不要忘记为网卡分配一个IP地址,此处我分配同一网段的192.168.32.1/24
。
接下来设置OpenWRT,这个设置有点点复杂,因为需要用到命令行,并且有一些坑。OpenWRT下实现VRRP的软件包为Keepalived,先在软件包中刷新列表,然后搜索后进行安装,或者在之后的命令行中通过opkg update
和opkg install keepalived
进行安装。然后登陆命令行,注意网页版命令行不可以通过https登陆不然会出错,我们需要修改Keepalived的init.d下的配置文件,因为这个保持服务运行的配置文件每次开机或者重启都会将我们的配置文件清空导致设置失效。
通过nano /etc/init.d/keepalived
打开配置文件,如果你熟悉vim也可以直接用vim,否则网页版命令行无法使用查找功能。
开头找到KEEPALIVED_CONF
变量,修改内容为配置文件路径/etc/keepalived/keepalived.conf
找到start_service()
函数,修改内容如下:
start_service() {
procd_open_instance
procd_set_param command /usr/sbin/keepalived
procd_append_param command -n # don't daemonize, procd will handle that for us
procd_append_param command -f "$KEEPALIVED_CONF"
# process_config
# set auto respawn behavior
# procd_set_param respawn
procd_close_instance
}
找到reload_service()
函数,修改内容如下:
reload_service() {
#process_config
#SIGHUP is used by keepalived to do init.d reload
procd_send_signal keepalived
}
保存文件,如果你使用nano
那么按Ctrl+O
回车,如果是vim
那么按ESC
然后输入:wq!
回车。
通过/etc/init.d/keepalived enable
将服务设为自启动。
接下来类似方法打开配置文件/etc/keepalived/keepalived.conf
,然后输入如下配置,此配置中填入刚刚的VRRP网卡相同IP,与VRID相同的virtual_router_id,比刚刚优先级100更高的priority,以及设置你的网卡名interface,和与刚刚name不同的router_id
global_defs {
router_id VRRP_OPENWRT
vrrp_version 3
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 110
advert_int 1
virtual_ipaddress {
192.168.32.1/24
}
}
保存退出,执行/etc/init.d/keepalived start
启动服务,此时通过浏览器访问你设置的IP能打开OpenWRT管理界面以及RouterOS上显示VRRP状态为B,那么设置就成功了,你可以将OPWRT关闭,访问相同IP看看能否打开ROS管理界面。
DNS优化
此处DNS优化涉及一些较敏感的内容,不便作深入展开,简单提一些要点。
着重强调一下SmartDNS的设置,如果你使用的话。可以将dnsmasq端口改为0禁用DNS,然后SmartDNS端口改为53。
至于境外DNS我强烈推荐FakeDNS,FakeDNS将域名映射到192.18.0.0/16的地址,然后当你访问这些地址时再做反向映射并进行代理或直连,好处在于走代理时本地完全没有DNS查询,一方面也避免了DNS泄露,目前没发现不兼容情况,关键网站秒解析,用起来很流畅的。
国内是否使用加密DNS取决于你对隐私的关注程度,而且即使加密了也只是运营商不知道你的访问。少部分情况下,加密DNS阻止了中国移动这样的运营商强制重定向或者抢答UDP 53请求导致一些网站打不开,但加密DNS会带来性能损耗,不过在缓存帮助下并不是很影响,而且似乎DOH还有HTTP2长连接的优势,可以避免反复建立连接,所以我认为延迟完全可以接受(偏远地区基本平均在50ms以内,上海平均17ms)。
如果使用加密DNS,那么我推荐腾讯DNSPod和AliDNS,并且要在接口中填写不加密DNS的地址,才能解析加密DNS的域名(据我测试即使不使用域名形式也需要填写,不然会出问题)。
目前的SmartDNS最新版已经支持返回多个IP,但第一个IP保持最快,可以优化一些下载网站和视频网站体验,配置文件加入max-reply-ip-num 3
即可设置返回3个IP,如果你有苹果设备那么还需要设置force-qtype-SOA 65
屏蔽https类型的DNS查询,避免绕开内网DNS服务器。
由于SmartDNS的53端口默认没有绑定VRRP, 我们还需要添加防火墙规则
# Smart DNS VRRP redirect
iptables -t nat -A PREROUTING -p udp --dport 53 -d 192.168.32.1 -j REDIRECT --to-ports 53
iptables -t nat -A PREROUTING -p tcp --dport 53 -d 192.168.32.1 -j REDIRECT --to-ports 53
然后下游将AdguardHome的DNS指向SmartDNS即可,Adg需要自己导入一些规则,且不要开启浏览安全和家长控制。否则因为每个地址都要去联网检查解析速度非常的慢。但是你会发现微信和QQ以及少数国产应用的广告依然还在,这是因为他们内置了DNS,根本不走你的DNS服务器,在ROS的防火墙中添加dns
地址列表(包括了国内常用的DNS)
然后在防火墙的Filter表中Reject除了你的OPWRT外转发到这些地址的所有请求(包括TCP和UDP,以防httpDNS和加密DNS请求)
然后我们在NAT表中将转发到其他地址的DNS重定向到你的下游DNS服务器(我这里是192.168.32.13),首先添加dstnat重定向目的地
再添加srcnat使得DNS请求结果能够正常返回,在这里同网段流量是不会被路由的,如果被路由肯定是出现刚刚那样的重定向,因此我们可以统一设置修改整个网段
这样一来就把所有应用的DNS都给劫持了。
单线多拨
单线多拨即在同一个WAN口上创建两条拨号线路,同一个账号多拨并不是在所有地区都支持,即使在支持的情况下最好也咨询一下电信客服是否会被额外扣费或者使用时间缩短,以免造成损失。
在我的宿舍中,同一个账号使用同一个MAC地址多拨可以拨号两次(有的地方需要用不同MAC地址),并且能够正常叠加宽带,因此我不需要创建VRRP虚拟网卡拨号,直接再创建一个用户名密码全都一模一样的PPPoE连接即可。
注意设置时候将原有PPPoE连接和新的连接的Add Default Route取消勾选,因为我们需要手动配置PCC路由以便进行负载均衡。PCC负载均衡可以在同一条线路上保持某个连接,连接一些银行或金融网站时可以避免出错。
ROS7需要先在Routing/Tables中添加路由表route_table1和route_table2并启用FIB。
在Mangle表中添加如下配置,配置MSS钳制和PCC路由
/ip firewall mangle
add action=change-mss chain=forward comment="Change MSS" new-mss=1452 \
out-interface-list=pppoe protocol=tcp tcp-flags=syn
add action=change-mss chain=forward new-mss=1452 out-interface-list=pppoe \
protocol=tcp tcp-flags=syn
add action=accept chain=prerouting comment="Bypass local" dst-address-list=\
local in-interface-list=local
add action=mark-connection chain=prerouting comment="Connection mark" \
connection-mark=no-mark in-interface=pppoe-out1 new-connection-mark=\
pppoe1_mark
add action=mark-connection chain=prerouting connection-mark=no-mark \
dst-address-type=!local in-interface-list=local new-connection-mark=\
pppoe1_mark per-connection-classifier=both-addresses:2/0
add action=mark-connection chain=prerouting connection-mark=no-mark \
dst-address-type=!local in-interface-list=local new-connection-mark=\
pppoe2_mark per-connection-classifier=both-addresses:2/1
add action=mark-connection chain=input connection-mark=no-mark in-interface=\
pppoe-out1 new-connection-mark=pppoe1_mark
add action=mark-connection chain=input connection-mark=no-mark in-interface=\
pppoe-out2 new-connection-mark=pppoe2_mark
add action=mark-routing chain=prerouting comment="Route mark" connection-mark=\
pppoe1_mark in-interface-list=local new-routing-mark=route_table1
add action=mark-routing chain=prerouting connection-mark=pppoe2_mark \
in-interface-list=local new-routing-mark=route_table2
add action=mark-routing chain=output connection-mark=pppoe1_mark \
new-routing-mark=route_table1
add action=mark-routing chain=output connection-mark=pppoe2_mark \
new-routing-mark=route_table2
此处使用的负载均衡策略是both addresses,也就是当源地址和目的地址一致时走同一线路,保证好的兼容性,如果你想获得更快网速可以尝试both addresses and ports,这样当端口不同时也会尝试走不同线路。
然后在IP/route中添加路由表,首先是策略路由,目的地址是0.0.0.0/0,gateway分别是pppoe-out1和pppoe-out2,然后路由标记按你刚刚填的那两个依次tables填入routing tables中。
然后默认路由分别再次添加路由,目的地址和gateway不变,然后distance分别填1和2,这样负载均衡就设置好了。
QoS限速
这里我限速采用的是PCQ限速和FTB优先级,以下是防火墙配置,分别在Mangle表按服务类型和包大小进行优先级标记
/ip firewall mangle
add action=jump chain=forward comment="QoS classifying" in-interface-list=local \
jump-target=up-qos-1 out-interface=pppoe-out1
add action=jump chain=forward in-interface-list=local jump-target=up-qos-2 \
out-interface=pppoe-out2
add action=mark-packet chain=forward in-interface=pppoe-out1 new-packet-mark=\
down_1 out-interface-list=local packet-mark=no-mark passthrough=yes
add action=mark-packet chain=forward in-interface=pppoe-out2 new-packet-mark=\
down_2 out-interface-list=local packet-mark=no-mark passthrough=yes
add action=mark-packet chain=up-qos-1 comment="Packet purpose QoS" \
new-packet-mark=vital_up_1 packet-mark=no-mark passthrough=yes protocol=\
icmp
add action=mark-packet chain=up-qos-2 new-packet-mark=vital_up_2 packet-mark=\
no-mark passthrough=yes protocol=icmp
add action=mark-packet chain=up-qos-1 dst-address-list=dns new-packet-mark=\
vital_up_1 packet-mark=no-mark passthrough=yes
add action=mark-packet chain=up-qos-2 dst-address-list=dns new-packet-mark=\
vital_up_2 packet-mark=no-mark passthrough=yes
add action=mark-packet chain=up-qos-1 comment="Packet size QoS" \
new-packet-mark=high_up_1 packet-mark=no-mark packet-size=0-256 \
passthrough=yes
add action=mark-packet chain=up-qos-2 new-packet-mark=high_up_2 packet-mark=\
no-mark packet-size=0-256 passthrough=yes
add action=mark-packet chain=up-qos-1 new-packet-mark=mid_up_1 packet-mark=\
no-mark packet-size=257-512 passthrough=yes
add action=mark-packet chain=up-qos-2 new-packet-mark=mid_up_2 packet-mark=\
no-mark packet-size=257-512 passthrough=yes
add action=mark-packet chain=up-qos-1 new-packet-mark=low_up_1 packet-mark=\
no-mark packet-size=513-1518 passthrough=yes
add action=mark-packet chain=up-qos-2 new-packet-mark=low_up_2 packet-mark=\
no-mark packet-size=513-1518 passthrough=yes
然后在Queue/Tree中设置限制和优先级即可,注意在download和upload两条线路中分别填入你的线路上传下载带宽,可以通过Speedtest测速后减去一点点留作冗余后填入。
PCQ原理是一人使用或者多人使用且没跑到限制时保证想要的带宽,达到限制后均分带宽,我测试结果是如果不设置QoS如果有人下载那么其他人延迟会波动60-80ms,设置后就没有波动了(BT下载开三四千连接时时虽然没有波动但是不知道为什么会丢包)。