背景
之前一直使用新三路由器刷了OpenWRT来启用如广告过滤之类的高级功能,但自从前段时间宽带升级到200M后新三的MT6721就严重力不从心了。在X86软路由和R2S之间考虑了很久没有决断,于是就决定先对手上已有的N1改造一下。
事实上这台N1在之前已经作为旁路由来使用了,只不过我给家里划分了两个vLAN隔离的网络A和B,A是家里的主网路,本人的主力PC、群晖、玩客云等等都挂在这个网络下,而N1则是刷了Armbain并且起了一个docker版OpenWRT在副网路B中充当旁路由。这样的好处是A网络是个正常的网络,而B网络则带有广告过滤等高级功能,手机、平板什么的可以根据需要选择连接哪个网络的热点。具体拓扑如下:
网络拓扑
但这样就有个坏处,就是主网络A只能利用MT6721那可怜的性能来跑一些网络高级功能,常常感到力不从心,现在宽带升级后就更是如此了。
方案
因而我决定对N1进行改造,让它可以同时联通两个网络并充当旁路由。改造后的网络拓扑如下:
新网络拓扑
从逻辑上来说就是在网路A里又增加了一个旁路由,但实际上A和B两个网络中的旁路由都是同一个N1,只不是起了两个Openwrt的docker分别接入两个vLAN而已。
这里面唯一的技术难点就是如何在N1的docker网络中启用多vLAN并且与主路由联通。最开始我设想的是使用Open Vswitch,这是最标准的虚拟网络使用方法,但是考虑到N1 CPU的能力,我对开启了Open Vswitch后的整体性能非常不看好。经过研究,最终还是选定了在N1物理网卡上建立vLAN子网卡,再给docker建立两个macvlan子网并且分别挂在这两个子网卡下面的方式,这种模式下没有vSwitch的那些二层网络的高级功能,理论上对CPU的压力很小。
具体步骤
1.主路由的配置
我的主路由的vLAN1是对应的是主网络A,vLAN3对应的是副网络B,vLAN2则对应的是上连WAN口。
首先将主路由与N1互联的端口把vLAN1和vLAN3置为tagged(已标记)模式,此时此端口实际上变成了一个trunk口。
主路由交换机配置
2.N1物理环境配置
此时N1的网络应该已经断开,需要使用显示器、键鼠接入N1进行配置。对N1的有线网卡eth0创建两个vLAN子网卡eth0.1和eth0.3,分别与vLAN1和vLAN3连接。
- 在eth0网卡上创建对应vLAN1和vLAN3的子网卡
zz@aml:~$ sudo vconfig add eth0 1
zz@aml:~$ sudo vconfig add eth0 3
注:若提示没有vconfig命令则需要先安装vlan软件包并启动8021q内核模块,命令如下
apt-get install vlan
modprobe 8021q
zz@aml:~$ sudo vconfig set_flag eth0.1 1 1
zz@aml:~$ sudo vconfig set_flag eth0.3 1 1
zz@aml:~$ sudo ifconfig eth0.1 up
zz@aml:~$ sudo ifconfig eth0.3 up
正常的话此时通过ifconfig命令查看两张子网卡eth0.1和eth0.2已经能够获取到主路由DHCP分配的IP了。应该分列于两个子网之中,如在博主的网络环境下两个网卡分别获取到的应该是192.168.31.x和192.168.2.x两个网址。
3.为docker创建vLAN网络
由于我是让docker内的OpenWRT做旁路由,因而需要它在网络上与所有设备存在于同一个子网之中,也就是要与物理机器的网络同级,标准的bridge模式docker网络是无法实现的,这就需要借助于docker的macvlan网络模式(注意,macvlan和vLAN是两码事)。为docker创建两个macvlan网络,分别挂在eth0.1和eth0.3下面。
zz@aml:~$ sudo ip link add link eth0.1 mac1 type macvlan mode bridge
zz@aml:~$ sudo ip link add link eth0.3 mac3 type macvlan mode bridge
此时网络部分的配置完成。
4.启动两个OP旁路由
博主的旁路由docker镜像是由OpenWRT官网的image导入生成的,分别用如下命令启用两个OpenWRT容器,两个容器分别挂载在mac0网桥和mac3两个macvlan类型的网桥上。
zz@aml:~$ sudo docker run --restart always --name op4v1 -d --network mac1 --privileged openwrt /sbin/init
zz@aml:~$ sudo docker run --restart always --name op4v3 -d --network mac3 --privileged openwrt /sbin/init
这样这两个OP旁路由就各自与主路由中vLAN1和vLAN3接通。此时可以在主路由上查找此时DHCP服务分配给两个OP容器的IP,再通过ssh或web服务直接进入旁路由完成配置。(当然也可以在N1的命令行中通过docker命令进入OP容器进行配置,这样更加方便)。博主一般将两个旁路由分别配置为静态IP地址192.168.31.2和192.168.2.2,再回到主路由将两个子网192.168.31.0/24和192.168.2.0/24对应的网关分别设为192.168.31.2和192.168.2.2从而将流量导向旁路由处理。192.168.31.0/24子网(vLAN1)的配置如下(vLAN3也类似):
192.168.31.0/24子网(vLAN1)的旁路由配置
192.168.31.0/24子网(vLAN1)的主路由配置
此时配置就完成啦,现在可以尽情的在两个OP旁路由上安装插件实现高级功能了。
补充
此时其实还有个小小的问题,当然这个问题并不是博主的网络拓扑引入的,而是docker的macvlan网络模式的天生限制。即N1本身的网卡无法连接两个旁路由使用的macvlan网卡,这样当N1获取到DHCP下发的网关为旁路由IP时其会因无法连接而不能访问外网。此时的解决方法有两个,一是强行配置N1的网关为主路由,即192.168.31.1或192.168.2.1。另一个方法则是在N1主机上的vlan接口中再创建macvlan子网卡,因为同为macvlan子网卡是可以互联的,N1就可以通过maclvan子网卡和docker内的旁路由连通了。具体配置方法如下:
zz@aml:~$ vi /etc/network/interfaces
Wired Adapter
auto eth0
iface eth0 inet manual
up ip link set eth0 promisc on
Wireless Adapter
auto wlan0
iface wlan0 inet manual
Wired Adapter vLAN 1
auto eth0.1
iface eth0.1 inet manual
Wired Adapter vLAN 3
auto eth0.3
iface eth0.3 inet manual
auto macvlan
iface macvlan inet static
address 192.168.2.11
netmask 255.255.255.0
gateway 192.168.2.2
dns-nameservers 192.168.2.2
pre-up ip link add macvlan link eth0.3 type macvlan mode bridge
post-down ip link del macvlan link eth0.3 type macvlan mode bridge
Local loopback
auto lo
iface lo inet loopback
修改完成后重启N1,此时N1的有线网卡、无线网卡和其vLAN子网卡均置为manual状态不会自动获取IP,且在网络启动时会创建与vLAN3连通的名为macvlan的子网卡,通过将此网卡配置为静态IP 192.168.2.11,网关为192.168.2.2即可以使N1网络可以正常使用。
到此为止所有配置便都完成啦,可以在旁路由中尽情的折腾高级功能了。