树莓派 4B 容器方式安装 OpenWrt 作为软路由
在树莓派 4B,基于 Ubuntu 22.04,使用 Docker 容器的方式运行 Openwrt 作为软路由,基于 SuLingGG/OpenWrt-Docker 的方案
- 什么是软路由
硬路由以特有的硬设备,包括处理器、电源供应、嵌入式软件,提供设定的路由器功能,如常用的路由器;软路由则是指利用台式机或服务器配合软件形成路由解决方案,主要靠软件的设置,达成路由器的功能;
普通路由器因为硬件性能限制,无法支持长时间处理大量流量,当家中有 NAS 等设备时,通常无法跑满带宽;通过软路由,可以让路由器只处理流量的转发,其他的功能由软路由实现
通常我们使用软路由用于多线负载、宽带叠加、为局域网内的其他设备过滤广告、自定义 DNS 等扩展功能
安装依赖
需要保证安装了linux-modules-extra-raspi,否则会导致在运行容器后出现Error response from daemon: failed to create the macvlan port: operation not supported错误
linux-modules-extra-raspi 是树莓派 Ubuntu Arm 的不常用扩展,Ubuntu 最新的包管理中默认不包含扩展;因此需要单独安装
1 | sudo apt install linux-modules-extra-raspi |
安装之后需要重启树莓派
1 | sudo reboot |
配置网络
- 开启网卡混杂模式
默认情况下网卡只会将发送给本机的包传递到上层服务,其他的包一律丢弃;开启混杂模式后机器的网卡能够接收所有流经过它的数据流,而无论其目的地址是否是它,一般用于网络分析和路由节点;
树莓派只有一个有线接口,地址为 eth0,所以在 eth0 接口开启混杂模式
1 | sudo ip link set eth0 promisc on |
执行以下命令检查结果
1 | ifconfig eth0 |
网卡 flag 信息有 PROMISC 表示开启成功
1 | eth0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST> mtu 1500 |
配置 OpenWrt 容器
- 创建
macvlan
macvlan 是一种网卡虚拟化技术,允许在同一个物理网卡上配置多个 MAC 地址,即多个 interface,每个 interface 可以配置自己的 IP;macvlan直接通过以太网的 interface 连接到物理网络,因此性能极好
因此,软路由需要使用 macvlan 配合混杂模式在容器中实现路由功能
Docker 创建 macvlan 时要确定所在的网段,可以在路由器后台进行确认;如小米路由器常用的是 192.168.31.0/24网段;在创建网络时需要保证子网网段subnet和网关地址gateway参数与当前网络一致
1 | docker network create -d macvlan --subnet=192.168.31.0/24 --gateway=192.168.31.1 -o parent=eth0 macnet |
- 创建容器
创建容器时需要指定网络为刚才创建的 macnet
1 | docker run --restart always --name openwrt -d --network macnet --privileged sulinggg/openwrt:rpi4 /sbin/init |
- 修改容器网络配置
容器成功运行后还无法直接使用,需要进入到容器中修改 OpenWrt 的网络配置
1 | docker exec -it openwrt bash |
修改网络
1 | vi /etc/config/network |
-
ipaddr为 OpenWrt 分配 IP 地址,因为 OpenWrt 使用了独立的 Mac 地址,所以这个 IP 地址不能和树莓派的相同,否则会无法访问;如树莓派的 IP 地址为192.168.31.2,可以将 OpenWrt 的 IP 改为192.168.31.4 gateway为当前局域网的网关地址,即192.168.31.1dns需要指定 DNS,否则无法将域名解析为 IP,建议使用路由器的地址,或者使用114.114.114.114等常用 DNS 服务器
需要注意的是,使用到的 IP 都应该是固定的,可以在路由器中配置 DHCP 进行 Mac 地址绑定
1 | config interface 'lan' |
修改完成后重启容器的网络
1 | /etc/init.d/network restart |
重启完成后访问 http://192.168.31.4,使用账户 root 和密码 password 即可进入管理页面
- OpenWrt 配置
登录后在 网络-接口中修改 LAN 接口,在底层基本设置中选择忽略此接口,使用默认路由器做 DHCP 服务器
使用 OpenWrt
有两种使用方式:
一种是将 OpenWrt 作为路由器的网关,这样所有使用路由器的设备的流量都会被 OpenWrt 处理,这种方式要求路由器支持指定网关(辣鸡小米路由器没有 root 不支持指定,且官方已不支持 root),并且 OpenWrt 足够稳定,否则会影响使用;
另一种方式是通过在设备端指定 OpenWrt 作为网关,只有这些设备的流量会被软路由处理,这种方式需要设备端支持(大部分 IoT 设备无法配置)
配置重启后网卡默认使用混杂模式
网卡的混杂模式会在系统重启后失效,需要在系统启动后自定配置混杂模式,参考 How to enable Promiscuous Mode permanently on a NIC managed by NetworkManager?,通过注册一个单独的服务启用网卡混杂模式
- 添加
oneshot服务,在网络启动之后执行,配置eth0网卡为混杂模式
1 | sudo bash -c 'cat > /etc/systemd/system/eth0-promisc.service' <<'EOS' |
- 启用注册的服务
1 | sudo systemctl enable eth0-promisc |
这样,在系统重启后依然可以正常使用 OpenWrt
修复宿主机与 OpenWrt 无法通信问题
Docker 的 macvlan 为了安全禁止宿主机与容器通信,因此宿主机和 OpenWrt 无法互相访问,导致宿主机上的一些监控无法从 OpenWrt 拉取数据;可以通过在宿主机上再创建一个 macvlan 接口,修改路由规则解决该问题
配置 macvlan 接口
- 宿主机创建
macvlan接口
在宿主机上添加了一个新的 macvlan 桥接 eth0 的接口,名称为 openwrt-bridge
1 | ip link add openwrt-bridge link eth0 type macvlan mode bridge |
- 为
openwrt-bridge接口配置 IP 并启用
为 openwrt-bridge 接口配置不冲突的 IP地址 192.168.31.6,并启用该接口
1 | ip addr add 192.168.31.6 dev openwrt-bridge |
- 配置路由规则,添加 OpenWrt
将 OpenWrt 的 IP 地址添加到 openwrt-bridge 接口的路由规则中,即可实现宿主机与 OpenWrt 容器的互相通信
1 | ip route add 192.168.31.4 dev openwrt-bridge |
配置重启后自动使用 macvlan 接口
同样通过添加一个 oneshot服务的方式配置
- 添加
oneshot服务,在网络启动之后执行,添加macvlan网卡
1 | sudo bash -c 'cat > /etc/systemd/system/openwrt-bridge.service' <<'EOS' |
- 启用注册的服务
1 | sudo systemctl enable openwrt-bridge |