为了在一个接口上同时使用电信和移动的宽带,这里使用NanoPiR2S,通过桥接WAN口和LAN口,配合虚拟机的方式实现双宽带同时使用。

这里的网络环境比较特殊,入户只有一个千兆以太网口,路由器上通过DHCP获取上游分配的内网IP,之后通过一个内网网页进行运营商认证,认证登录后上级路由会根据登录的账号选择出口。
已测试使用OpenWRT通过添加额外接口并修改mac地址的方式获取到了两个IP,但是这两个IP在同一个局域网网段中,因此尝试了各种设置,始终无法通过另一个IP进行网络认证,怀疑是OpenWRT的设置问题。故尝试通过虚拟机桥接网卡的方法实现该需求。又由于OpenWRT的固件未能开启aarch64的kvm,猜测需要重新编译内核或修改固件设置,避免麻烦直接使用Armbian的固件。
本文目的是通过R2S结合虚拟机,实现单WAN口得到两个不同的IP,之后在局域网配置两个网段,分别为192.168.2.0/24和192.168.3.0/24,其中192.168.2.0/24通过R2S主机连接网络,192.168.3.0/24通过R2S虚拟机连接网络。

将Armbian固件的R2S配置为路由器

安装好Armbian后,固件默认将wan口(eth0)和lan口(lan0)设置为dhcp。将任意一个网口连接上已有的路由器后,就能在已有路由器的DHCP分配表上看到R2S的IP,从而能够通过ssh连接上R2S。
按需要修改好apt配置后,安装bridge-utils软件包以支持桥接设置。

sudo apt-get update && sudo apt-get install bridge-utils

作为一个路由器,首先需要将lan0设置为静态IP,之后设置好NAT转发。这里为了便于后续虚拟机与网络的桥接,将/etc/network/interfaces按如下配置:

source /etc/network/interfaces.d/*
# Network is managed by Network manager
auto lo
iface lo inet loopback

iface eth0 inet manual

auto vmbr0
iface vmbr0 inet dhcp
        bridge-ports eth0
        bridge-stp on
        bridge-fd 0

iface lan0 inet manual

auto vmbr1
iface vmbr1 inet static
        address 192.168.2.1/24
        bridge-ports lan0
        bridge-stp on
        bridge-fd 0

dns-nameservers 119.29.29.29 223.5.5.5

其中,通过vmbr0桥接eth0,通过vmbr1桥接lan0。内网的网口设置为静态IP,地址为192.168.2.1。注意,由于同时桥接了多个网口,bridge-stp必须设置为on。改动重启后生效。
之后WAN口连接外网网口,LAN口连接局域网,就可以通过局域网地址直接连接R2S了。但注意,DHCP服务端没有安装,内网需要先使用静态IP地址。NAT也还没有配置,内网客户端尚无法直接连接外网。
首先将NAT打开。编辑/etc/sysctl.conf,启用net.ipv4.ip_forward:

net.ipv4.ip_forward=1

通过运行sysctl更新内核配置:

sudo sysctl -p

之后通过iptables命令设置NAT,将出口设置到vmbr0:

iptables -t nat -A POSTROUTING -o vmbr0 -j MASQUERADE

此时,连接到内网的设备应该已经能够ping通上级网关。
之后安装DHCP服务器,此处通过常用的dnsmasq实现,同时dnsmasq还用作局域网的DNS缓存:

sudo apt-get install dnsmasq

编辑/etc/dnsmasq.conf文件,一个参考配置如下:

port=53 #启用局域网DNS
resolv-file=/etc/resolv.dnsmasq.conf #使用dnsmasq专用的resolv文件(注意,需要单独创建,文件格式与/etc/resolv.conf一致)
server=223.5.5.5 #配置额外的DNS(使用公共DNS)
server=119.29.29.29 #配置额外的DNS(使用公共DNS)
interface=lan0 #设置绑定的接口
listen-address=192.168.2.1,127.0.0.1 #设置服务端监听地址
dhcp-range=192.168.2.50,192.168.2.250,24h #设置DHCP的地址范围,地址租期24小时
dhcp-option=3,192.168.2.1 #设置DHCP通告的网关,即本机的局域网地址
dhcp-option=6,192.168.2.1,119.29.29.29 #设置DHCP通告的DNS,可设置多个,此处一个地址为本机地址,另一个地址为公共DNS
cache-size=1500 #设置缓存DNS的条目(仅为了减少向上游DNS查询概率,可不设置)
min-cache-ttl=1200 #设置缓存的最小TTL(仅为了减少向上游DNS查询概率,可不设置)

之后重启dnsmasq服务,其他连入局域网的设备应该能够自动连接上网络了:

sudo service dnsmasq restart

安装虚拟机

aarch64构架一般都能启用KVM,在NanoPiR2S上,Armbian固件默认启用KVM,可通过ls /dev/kvm查看,如果存在kvm设备,则说明kvm已经启用。
如果不使用kvm,虚拟机的速度会慢得难以接收。
主要步骤可参考在qemu中创建arm64的debian虚拟机,此处针对该场景做了一些修改。
首先安装qemu:

sudo apt-get install qemu-system qemu-utils

此处以安装aarch64版本的debian为例。先通过qemu-img创建硬盘,此处虚拟硬盘容量为8G,已经足够使用:

qemu-img create -f qcow2 debian.qcow2 8G

之后到debian镜像源中下载安装用的内核和启动文件,以清华大学镜像源为例,目前aarch64版本的Debian10网络安装的文件路径为https://mirrors.tuna.tsinghua.edu.cn/debian/dists/stable/main/installer-arm64/current/images/netboot/debian-installer/arm64/
下载其中的linux和initrd.gz文件。
编写安装脚本,注意一定需要添加--enable-kvm以启用kvm:

qemu-system-aarch64 --enable-kvm \
-cpu host -M virt -smp 2 \
-m 384M \
-initrd initrd.gz \
-kernel linux \
-append "root=/dev/ram console=ttyAMA0" \
-global virtio-blk-device.scsi=off \
-device virtio-scsi-device,id=scsi \
-drive file=debian.qcow2,id=rootimg,cache=unsafe,if=none \
-device scsi-hd,drive=rootimg \
-netdev user,id=unet \
-device virtio-net-device,netdev=unet \
-net user \
-nographic

建议在screen命令的会话中运行qemu命令,这样可将qemu放置在后台运行,并可以随时切换回虚拟机的终端中。该配置中给虚拟机分配了两个vCPU和384M的内存,按需要修改即可。此处尚未使用桥接网络,虚拟机联网通过用户态程序实现。之后终端中就会出现debian的安装引导,按正常安装过程进行安装即可。唯一需要注意的是,安装结束引导程序会自动重启,需要通过kill命令关闭qemu,否则会再次进入安装界面。
然后需要挂载虚拟机文件,拷贝出boot文件夹里的initrd.img-4.19.0-17-arm64文件和vmlinuz-4.19.0-17-arm64文件。(由于没有使用efi,所以虚拟硬盘里没有安装如bootload或者uboot之类的引导,引导内核的过程需要通过qemu来进行)。这里通过qemu-nbd连接虚拟硬盘:

sudo qemu-nbd --connect=/dev/nbd0 ./debian.qcow2

然后将/dev/nbd0p1挂载到/mnt/nbd0p1,找到boot文件夹,将文件拷贝出即可,卸载挂载点后,将以上命令中的connect改为disconnect以断开虚拟硬盘。
之后就可以启动虚拟机了,使用桥接网络的启动脚本例子如下:

qemu-system-aarch64 --enable-kvm \
-cpu host -M virt -smp 2 \
-m 384M \
-initrd initrd.img-4.19.0-17-arm64 \
-kernel vmlinuz-4.19.0-17-arm64 \
-append "root=/dev/sda2 console=ttyAMA0" \
-global virtio-blk-device.scsi=off \
-device virtio-scsi-device,id=scsi \
-drive file=debian.qcow2,id=rootimg,cache=unsafe,if=none \
-device scsi-hd,drive=rootimg \
-netdev tap,id=net0,ifname=tap0,br=vmbr0 \
-device virtio-net-pci,mac=12:34:56:78:9a:b0,netdev=net0,id=net0 \
-netdev tap,id=net1,ifname=tap1,br=vmbr1 \
-device virtio-net-pci,mac=12:34:56:78:9a:b2,netdev=net1,id=net1 \
-nographic

注意append中的root项需要按照安装时的分区配置进行设置,通常是/dev/sda2。此外还需要注意修改mac地址,避免与其他设备冲突。正常情况下,运行之后主机应该会创建tap0连接到vmbr0,创建tap1连接到vmbr1。可通过brctl show命令查看连接情况。
如果tap位置不对(如tap1也在vmbr0中),则可以先将其移出vmbr0,再移入vmbr1:

brctl delif vmbr0 tap1
brctl addif vmbr1 tap1

此时,虚拟机中应该有enp0s1和enp0s2两张网卡,分别对应通过vmbr0桥接至eth0的tap0,和通过vmbr1桥接至lan0的tap1。
修改/etc/network/interfaces,按类似的方法设置网卡即可。参考设置如下:

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
allow-hotplug enp0s1
iface enp0s1 inet dhcp

allow-hotplug enp0s2
iface enp0s2 inet static
  address 192.168.3.1/24

dns-nameservers 119.29.29.29 223.5.5.5

之后要用和之前同样的方法设置内核的转发(修改/etc/sysctl.conf)和设置NAT(通过iptables命令)。可以用相同的方法配置和安装dnsmasq,如果不配置DHCP,将局域网中需要使用该宽带的设备的IP修改至192.168.3.0/24网段即可。
至此,NanoPiR2S设置完毕。部分内容可按需写入/etc/rc.local或配置为服务。连入局域网的设备默认通过R2S的主机网络上网,分配192.168.2.0/24段IP,需要使用另一个宽带的设备通过修改IP地址到192.168.3.0/24段即可。

标签: Linux

添加新评论