前言
自从使用PVE搭建双软路由系统(iKuai+OpenWRT),使用DHCP分段使用不同网关通过旁路由的方式实现了家里不同设备分段上网的方案之后,家里的网络一直稳定运行,各司其职,没出什么大问题。直至我购买了TP-Link的摄像头安装在老家,并在尝试将老家接人到深圳的NVR时,出现了问题。
问题
NVR无法接入异地摄像头
国庆回老家安装好摄像头之后,就想着用深圳的NVR
把新装的摄像头接入管理,为了安全考虑,深圳的NVR
网关指向的是iKuai
而不是安装有WireGuard
的OpenWRT
,于是乎发现想要接入老家这边新安装的摄像头时提示找不到对应设备的情况:
经过检查,老家的摄像头接的网关是安装有WireGuard
的OpenWRT
,深圳的NVR
接的网关也是安装有WireGuard
的OpenWRT
,于是想到有可能是ACL
影响到了。为了防止IPC
和NVR
联网,深圳的iKuai
我是加了阻断出站的ACL
规则:
知道原因那就好办了,只需要增加允许出站到老家网络的网段(我这里是10.0.1.0/24
)即可:
iKuai限制NVR和IPC联网的ACL不生效
在老家安装好摄像头并接入到TP-Link
物联APP之后,顺手启用了iKuai
阻断摄像头出站的ACL
规则。但是启用后再打开APP发现居然还能通过外网访问摄像头。经排查发现,原来是因为老家网络默认将网关指向了OpenWRT
,这导致流量没有先流到iKuai
,所以导致了阻断摄像头出站的ACL
规则不生效。那么解决的办法只有将网关改为指向iKuai
,但是因为WireGuard
是安装在OpenWRT
上,流量不能不流经OpenWRT
,经过搜索发现了iKuai ByPass
。原理是网关统一指向iKuai
,然后由iKuai
的分流规则再将流量流向OpenWRT
,这样就能完美解决我遇到的问题,而且还能将不需要代理的流量直接拦截在iKuai
处理,不需要再通过不同网关的这种旁路模式实现科学上网,同时即使OpenWRT
宕机也不影响直连网络的访问,妙哉妙哉。找到解决方案之后,接下来当然是想办法实施了。
方案
iKuai ByPass
有两种方式可以实现,分别是多WAN负载和指定下一跳网关。两种分流方式主要区别是:指定下一跳不需要多WAN,OpenWRT
不需要多网口,但是只支持纯IP分流规则;多WAN负载需要多WAN口,OpenWRT
需要一WAN一LAN,优势是支持域名和IP分流规则。我这里选择的是多WAN分流,也即iKuai
上的多线负载。全程不会导致网络失联,在重启的时候会加上保底机制。
iKuai方面设置
增加WAN口用来做负载出口
那么第一步当然是先在iKuai
上先增加一个用来做分流国外流量的WAN口,如果你是远程操作异地的iKuai
的话,这里切记不要勾选设此线路为默认网关
,以免断网;IP不重要,随意定义一个就行,网关的IP需要给OpenWRT
的LAN口用;其他保持默认即可:
同步域名和IP规则
我这里选择了使用joyanhui/ikuai-bypass这个项目来做规则自动同步,你也可以直接维护规则。
设置分流规则
首先在端口分流里面添加防止环回的策略:
其他的分流规则上面的自动脚本会同步,只需要修改对应的网口名为自己iKuai
中的网口名即可。这是我使用的配置文件:
1 | ikuai-url: http://10.0.0.254 # 爱快网页控制台登陆地址 结尾不要加 "/",如在爱快docker内运行,网关就是爱快地址,可以不写,如不填写,则使用第一个接口的网关地址, |
执行一下写入命令:
1 | ./ikuai-bypass -r nocron -c config.yaml |
执行成功后就会自动在iKuai
的分流规则中添加对应的分流规则,然后我们还需要在多线负载这里引入一下规则进行分流,把国内的IP绑定到iKuai
的WAN1出口,我这里命名是adsl1
,改为你自己的对应网口即可:
如果你像我一样有玩PT,又不希望PT的流量流到OpenWRT
中,防止被标盒的话,那可以自己在域名分流中添加对应的域名:
照猫画虎,如果还有其他需要直连不需要流经OpenWRT
的流量都可以在这里配置一下。这里为什么需要特殊设置走国内流量的域名呢?因为国外的规则集比较大,所以取国内域名相对较少,这是一种取巧的方式。
如果需要持续更新分流规则,那么把这个命令加到守护进程中常驻运行即可,下面是systemd
的配置示例:
1 | [Unit] |
再多提供一个OpenWRT
的service
的配置示例:
1 | #!/bin/sh /etc/rc.common |
创建新的虚拟机安装新的OpenWRT系统
创建虚拟机首先需要确定需要使用的系统。我们都知道,OpenWRT
百花齐放,有各路大神制作了各式各样的固件,我这里选择了不自带各种插件但是已经编译好各种依赖的ImmortalWRT
,只需要按自己需求安装对应的软件包即可。
General
这里需要记住VM ID
,因为下面的镜像导入操作时需要用到。其他配置项建议保持默认,切记不要勾选Start at boot
,千万不要手欠:
OS
这里选择Do not use any media
,因为等下我们会通过qm importdisk
命令将OpenWRT
的镜像导入到这个VM
中来:
System
这里选q35
和OVMF(UEFI)
,不要添加EFI的磁盘,Add EFI Disk
不勾选,其他保持默认即可:
Disks
我们不需要虚拟磁盘,因为OpenWRT
镜像里面已经有了,所以这里的磁盘我选择删掉,你也可以先点下一步,后面再删掉:
CPU
CPU按需分配即可,我是拉满,直接host
给4个Cores
(因为我是J4125
,所以只有可怜的4 Cores
和 1 Sockets
),其他保持默认即可:
Memory
我只用来跑OpenClash+DDNS+WireGuard
,所以我只分配了最高512M
,最低256M
,够用了:
Network
网卡可以先不启用,后面再一起添加,因为使用iKuai ByPass
,OpenWRT
需要两个网口:
Confirm
这里点Finish
就好,你也可以自行检查一下是否都符合自己的配置:
导入OpenWRT镜像
首先下载对应版本的系统镜像,我这里选择的是ImmortalWRT
;因为我是J4125
的处理器,所以我这里选择的是x86_64
的版本;至于ext4
和squashfs
的区别,查了一些资料说是ext4
是可修改的,而squashfs
是只读的,我这里选择的是熟悉的ext4
;需要下载img.gz
结尾的文件:
下载后传到PVE
上:
上传之后登录PVE,然后解压镜像:
然后进行磁盘导入操作:
看到导入成功的提示:
然后到PVE
的Web UI
上找到这个未使用的硬盘:
双击Unused Disk 0
,其他保持默认,点Add
:
添加虚拟网卡
因为我网口有限,但是使用ByPass
的方案需要多一个网口,故我这里使用虚拟网卡节约真实网口,所以你如果只有两个网口也不用担心,一样适用。如果你网口超级多,也不用担心,你只需要把虚拟网卡改成直通网卡即可。
点左上角的Add
添加硬件:
添加两个虚拟网卡,这里选默认即可:
到这网卡就添加完成了,检查一下:
修改启动项
点击Options
,然后点Boot Order
修改启动项,选择上面导入的镜像:
到这安装OpenWRT
的步骤就走完了,接下来就需要启动系统修改系统的网络设置。
网络配置
为了避免IP冲突,我这里LAN口IP设置为192.168.10.1
,这个无所谓,因为只有iKuai
的WAN2
口会需要用到,只要不跟其他设备的IP冲突即可:
WAN口我这里偷懒设置为了DHCP,如果你需要固定IP,也可以参照LAN口的设置,将WAN口设置为静态IP,比如我iKuai
的网关地址是10.0.0.254
,如果需要科学上网,因为我原来的OpenWRT
是已经配置好科学上网的,所以我这里网关还可以设置为OpenWRT
的IP10.0.0.253
。这里我将新安装的OpenWRT
的IP设置为10.0.0.249
,因为启动后还需要安装一些软件,所以这里切记不要与现有的OpenWRT
的IP一样,避免断网:
这里需要注意netmask不要忘了设置,我就是因为忘记设置netmask导致上不了网,折腾了一会儿才发现是因为这个没有设置导致的;还有就是DNS地址最好设置一下,因为在另一台机器上我设置的时候发现没有设置DNS导致重启OpenWRT
之后无法访问网络。WAN6就用DHCPV6
就好,如果不需要IPV6也可以删掉。
设置完成之后,执行/etc/init.d/network restart
命令重启网络即可。
防火墙配置
设置完网络之后,还需要设置一下防火墙,编辑防火墙配置文件/etc/config/firewall
,把input
(入站)、output
(出站)以及forward
(转发)都改为ACCEPT
:
设置好防火墙之后,不要忘记重启一下防火墙,执行/etc/init.d/firewall restart
命令重启即可。不出意外的话,此时只需要在浏览器打开10.0.0.249
即可进入OpenWRT
的Web访问页面:
ImmortalWRT
默认没有设置密码,点击登录即可:
测试一下网络:
软件安装
上面测试发现网络是OK的,那么我们就开始安装必备的软件。我个人需要WireGuard
(组网)、DDNS-GO
(DDNS)以及OpenClash
,这些可以按需安装。可以很方便的到Web界面上安装,入口是系统-软件包
:
点一下更新列表:
更新列表完成后直接过滤自己需要安装的软件包即可:
如果你熟悉命令行,记得包名,你也可以自己在命令行中用opkg
包管理命令执行安装命令,此处不多赘述。
配置WireGuard
如果你没有在OpenWRT
中使用WireGuard
的话,跳过这一步即可。因为我是组网需求,原来的OpenWRT
中也已经配置好了,所以我这里直接从原来OpenWRT
中WireGuard
的网络配置直接搬过来,打开/etc/config/network
文件,复制WireGuard
相关的配置,然后到新装的OpenWRT
中一样打开/etc/config/network
文件,然后把配置贴进去即可:
然后当然还需要设置一下WireGuard
接口的防火墙,打开/etc/config/firewall
文件,然后在wan口的区域添加wg0
接口,当然还要记得把input
(入站)、output
(出站)以及forward
(转发)都改为ACCEPT
:
变更网络配置
软件包安装配置好之后,我们就可以将新的OpenWRT
中的网络改成跟原有的OpenWRT
中的IP一样,作为替代项了。因为不确定是否一次成功,所以这里先不要将新安装的OpenWRT
虚拟机改成开机自启动,因为我们需要利用这个特性做保底策略,防止我们彻底失联。这里只需要变更WAN口的IP即可,将WAN口协议改为静态IP,IP改为10.0.0.253
,网关改为10.0.0.254
,然后保存。我自建了内网DNS,所以首选的DNS是内网DNS服务器IP,这个可以按需设置:
移花接木
那么我们就准备开始替换操作,首先我们需要设置保底机制,也就是PVE
延时重启,我这里设置20分钟后重启:
1 | shutdown -h +20 |
然后需要找到两个虚拟机对应的VMID用来做启用和停用操作:
1 | qm list |
记住新旧虚拟机的VMID,然后就可以开始移花接木了:
1 | 比如我这里新的VMID是107,旧的VMID是101 |
回车之后如果没有意外,那么只有等WireGuard
重新上线即可。如果有意外,那么20分钟后重启PVE
也会将网络设置回滚回去。我一次成功,所以我没有等待PVE
重启,我等待新OpenWRT
的WireGuard
上线后就登录查看是否有问题,确认没有问题后就可以取消PVE
的重启计划:
1 | shutdown -c |
然后将VMID=101的虚拟机自启动停掉,开启VMID=107的虚拟机的自启动选项即可完成本次迁移工作。这个时候前往TP-Link物联
APP查看摄像头就会发现已经离线,说明我们的ACL规则终于生效了,喜大普奔。然后我们需要测试一下墙外分流是否正常(此处假设上面已经配置好了OpenClash
等科学上网工具),如果也正常,那就说明已经大功告成!
Happy Ending
费了很大劲才终于把文章写完,折腾网络其实只花了满打满算2天时间。折腾完之后本来想着写个备忘录给自己,方便后面还有设备需要迁移的时候做参考,不过没想到写作对我来说已经如此艰难,前后花了半个月才终于把文章写完。临写完还发现自己前面思路不对,没有把全程不失联这个关键因素加进来,于是乎只能大改。还好终于在历时17天后,终于把文章写完了,希望对你有帮助。Happy Life!