树莓派 | Docker上运行 OpenWrt 做旁路由
场景1
众所周知,OpenWrt 是面向嵌入型设备的 Linux 发行版,所以 OpenWrt 系统运行时的资源占用率会很低。而树莓派的硬件性能要比普通路由器要高很多。虽然树莓派在硬件配置上的绝对优势能让 OpenWrt 有更大的施展空间,但相应的,硬件上的优势也带来了资源的浪费(OpenWrt 在树莓派上正常运行时,资源占用率只有不到 1/10)。再加上 OpenWrt 的可扩展性不是很强,所以很多能在 Raspbian/Debian 上能做的事情在 OpenWrt 上往往无法实现。
所以,可不可以让 OpenWrt 与我们常用的系统共存呢?这样,我们可以享受到 OpenWrt 的功能,又可以让在我们常用的系统中完成一般性的 Linux 工作。
通过 Docker,完全可以。
场景2
OpenWrt 的功能固然强大,但是树莓派的板载网卡无线吞吐能力实在是无力吐槽,能否将现有路由器与树莓派结合使用,同时发挥现有路由器的信号优势与 OpenWrt 的软件优势呢?
通过旁路网关,完全可以。
旁路网关
那么,什么是旁路网关呢?
普通的路由器往往集无线信号转发、网关、DNS 服务器等角色为一身,其中的“网关”角色负责路由器内部数据的处理。但因为一般家用的路由器硬件性能很有限,在运行一些比较吃资源的应用(如酸酸乳、去广告等)时,几乎会占满所有硬件资源,导致路由器网络/系统不稳定等诸多问题。既然路由器的硬件性能有限,那可不可以把网关的重任交给硬件性能更好的设备去做,让路由器安安心心地做好它的老本行 – 无线转发呢?
完全可以。
所谓的旁路网关,就是在路由器之外的其他硬件设备上搭建一个网关环境,把路由器肩负的网关重任交给其他更适合的设备来做,同时,旁路网关处理完的结果会返回给路由器,由路由器继续进行无线转发。
这样,每个角色各司其职,路由器肩上的任务轻了,即使是油管 4K 也能轻松跑满网速了,而旁路由(树莓派)也结束了它吃灰的命运。由此资源的充分利用,一举两得。
在接下来的文章中,我们将在 Docker 容器中运行 OpenWrt,并通过设置,让 Docker 容器中的 OpenWrt 网关接管路由器自身的网关,减轻路由器的负担,同时,由于网关被 OpenWrt 接管,所以 OpenWrt 中的大部分应用都是可用的,比如酸酸乳,V2ray,去广告等。做个不恰当的比喻, OpenWrt 网关接管路由器自身的网关后,你可以理解为路由器是 OpenWrt 的一块外置网卡。
镜像介绍
为大家提供的 OpenWrt 镜像所用系统为基于 Lean 大源码编译的 32位/ IPV4 Only 固件,基本功能与之前的自编译固件相同,并且 Docker 镜像将跟随自编译固件的更新而更新。自编译固件的详细介绍请见:
重要说明
1.此教程中提到的 Docker 镜像只适用于树莓派 2B/3B/3B+/4B,在其他设备上理论上不能正常使用。但文中所述内容对其他设备应该有参考意义。
2.在 Docker 中运行 OpenWrt ,树莓派将工作在旁路网关模式下,在这种工作模式下,树莓派的板载无线网卡不会工作(同时在 OpenWrt 的控制面板中也找不到有关 WIFI 的设置)。所以,需要将树莓派与路由器通过网线连接来使用。
前期准备
既然需要在 Docker 中运行 OpenWrt ,那么首先需要在树莓派的现有系统上安装 Docker,在不同发行版上安装 Docker 的教程有很多,大家可以自行在搜索引擎中搜索相关内容以完成 Docker 的安装。
如果你的设备是 3B/3B+/4B,推荐使用“树莓派爱好者基地”编译的 64 位 Debian,此版本 Debian 可以充分发挥 64 位 CPU 的性能,同时默认开启 Docker,KVM 等功能,其中,Docker 功能开箱即用,非常方便。
如果你的设备是树莓派2B,那么你可能需要在其他发行版上手动安装 Docker了,但是提供的 Docker 镜像是支持 2B~4B 设备的,换句话说,只要在其他发行版上成功安装了 Docker,也是可以用我提供的 OpenWrt 镜像的。
为了方便叙述以及为大家提供一个参考的宿主机环境,下文内容基于“树莓派爱好者基地”编译的 64 位 Debian。当然,如果你在你使用的发行版上安装了 Docker,步骤是一样的。
“树莓派爱好者基地”专版64位 Debian 功能介绍(内含下载链接):
下载时推荐选择“无桌面基础系统加强版”(如下图),如果你有图形界面需求,也可以选择带图形界面的其他版本镜像。
建议选择“无桌面基础系统加强版”
下载镜像烧写到树莓派的 SD 卡并上电开机后,系统会自动完成扩展 SD 卡空间的操作,这个过程大约需要3~5分钟(期间会重启几次)。估摸着时间差不多以后,用网线将树莓派的板载网口与路由器的 Lan 口连接,之后连接树莓派的 SSH:
用户名:pi
密码:raspberry
准备工作到此结束。
步骤开始
成功登陆到树莓派的 SSH 后,在拉取镜像之前,我们还需要进行一些额外的工作:
1.打开网卡混杂模式
XML/HTML代码
- sudo ip link set eth0 promisc on
(须结合实际网络情况,不能照抄命令)
XML/HTML代码
- docker network create -d macvlan --subnet=192.168.123.0/24 --gateway=192.168.123.1 -o parent=eth0 macnet
XML/HTML代码
- docker network create -d macvlan --subnet=192.168.2.0/24 --gateway=192.168.2.1 -o parent=eth0 macnet
XML/HTML代码
- $ docker network ls
- NETWORK ID NAME DRIVER SCOPE
- 10e676133746 bridge bridge local
- f5308b94e8fa host host local
- 16745ea66852 macnet macvlan local
- 5e72e41ea02a none null local
3.拉取镜像
若身处国内,为提高拉取速度,请拉取阿里云仓库中的镜像:
XML/HTML代码
- docker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest
同时小苏也提供存放在 Docker 官方仓库 中的镜像:
XML/HTML代码
- docker pull sulinggg/openwrt:latest
XML/HTML代码
- $ docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- registry.cn-shanghai.aliyuncs.com/suling/openwrt latest 4f4bc5dca2d9 3 hours ago 112MB
可见,镜像已成功拉取到本地。
4.创建并启动容器
XML/HTML代码
- docker run --restart always --name openwrt -d --network macnet --privileged registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest /sbin/init
其中:
--restart always参数表示容器退出时始终重启,使服务尽量保持始终可用;
--name openwrt参数定义了容器的名称;
-d参数定义使容器运行在 Daemon 模式;
--network macnet参数定义将容器加入 maxnet网络;
--privileged 参数定义容器运行在特权模式下;
registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest为 Docker 镜像名,因容器托管在阿里云 Docker 镜像仓库内,所以在镜像名中含有阿里云仓库信息;
/sbin/init定义容器启动后执行的命令。
启动容器后,我们可以使用 docker ps -a命令查看当前运行的容器:
XML/HTML代码
- $ docker ps -a
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORT NAMES
- a26cee7cade6 openwrt:latest "/sbin/init" 3 hours ago Up 3 hour openwrt
若容器运行信息STATUS列为 UP状态,则说明容器运行正常。
5.进入容器并修改相关参数
(须结合实际网络情况,不能照抄配置)
XML/HTML代码
- docker exec -it openwrt bash
openwrt为容器名称;
bash为进入容器后执行的命令。
执行此命令后我们便进入 OpenWrt 的命令行界面,首先,我们需要编辑 OpenWrt 的网络配置文件:
XML/HTML代码
- vim /etc/config/network
XML/HTML代码
- config interface 'lan'
- option type 'bridge'
- option ifname 'eth0'
- option proto 'static'
- option ipaddr '192.168.123.100'
- option netmask '255.255.255.0'
- option ip6assign '60'
- option gateway '192.168.123.1'
- option broadcast '192.168.123.255'
- option dns '192.168.123.1'
其中:
所有的 192.168.123.x 需要根据树莓派所处网段修改,option gateway和option dns填写路由器的 IP,若树莓派获得的 IP 为 192.168.2.154,路由器 IP 为192.168.2.1,则需要这样修改:
XML/HTML代码
- config interface 'lan'
- option type 'bridge'
- option ifname 'eth0'
- option proto 'static'
- option ipaddr '192.168.2.100'
- option netmask '255.255.255.0'
- option ip6assign '60'
- option gateway '192.168.2.1'
- option broadcast '192.168.2.255'
- option dns '192.168.2.1'
option ipaddr 项目定义了 OpenWrt 的 IP 地址,在完成网段设置后,IP最后一段可根据自己的爱好修改(前提是符合规则且不和现有已分配 IP 冲突)。
6.重启网络
XML/HTML代码
- /etc/init.d/network restart
7.进入控制面板
在浏览器中输入第 5 步option ipaddr 项目中的 IP 进入 Luci 控制面板,若option ipaddr 的参数为 192.168.123.100,则可以在浏览器输入 http://192.168.123.100进入控制面板。
用户名:root
密码:password
8.关闭 DHCP 服务
在 “网络 - 接口 - Lan - 修改” 界面中,勾选下方的 “忽略此接口(不在此接口提供 DHCP 服务)”,并“保存&应用”。
关闭 “DHCP 服务”
9.主路由 DHCP 设置
进入路由器后台中,将主路由的 DHCP 的默认网关和 DNS 服务器设置为第 5 步中option ipaddr 项目中的 IP。
主路由 DHCP 设置
10.重新连接路由器
完成以上操作后,断开设备(如手机,电脑)与路由器的连接,重新连接路由器,连接路由器的设备将获取到我们设置到的 IP。
其他修复
1.关闭 WLAN 硬件加速
设置旁路路由后,若出现访问国内网站网速慢,不稳定的情况(多见于 Pandavan 及其改版固件,如华硕老毛子固件),请在路由器的控制面板中关闭有关 WLAN 的硬件加速,比如选择“Offload TCP/UDP for LAN”(若未出现此现象请忽略):
关闭 WLAN 硬件加速
2.宿主机网络修复
OpenWrt 容器运行后,宿主机内可能无法正常连接外部网络,需要修改宿主机的 /etc/network/interfaces 文件以修复:
(须结合实际网络情况,不能照抄配置)
XML/HTML代码
- cp /etc/network/interfaces /etc/network/interfaces.bak # 备份文件
- vim /etc/network/interfaces # 使用 vim 编辑文件
XML/HTML代码
- auto eth0
- iface eth0 inet manual
- auto macvlan
- iface macvlan inet static
- address 192.168.123.200
- netmask 255.255.255.0
- gateway 192.168.123.1
- dns-nameservers 192.168.123.1
- pre-up ip link add macvlan link eth0 type macvlan mode bridge
- post-down ip link del macvlan link eth0 type macvlan mode bridge
XML/HTML代码
- auto eth0
- iface eth0 inet manual
- auto macvlan
- iface macvlan inet static
- address 192.168.2.200
- netmask 255.255.255.0
- gateway 192.168.2.1
- dns-nameservers 192.168.2.1
- pre-up ip link add macvlan link eth0 type macvlan mode bridge
- post-down ip link del macvlan link eth0 type macvlan mode bridge
修改后重启树莓派,之后树莓派的局域网 IP 地址将会固定为/etc/network/interfaces文件中address参数中的地址。
3.手动指定网关
如果路由器固件不支持自定义 DHCP 服务的网关及 DNS 地址(常见于路由器官方固件),或者只希望局域网下的个别设备接入旁路网关时,须在接入设备上做以下配置:
安卓:
安卓设置
需要在安卓的 WIFI 设置内将 IP 获取方式更改为“静态”或“手动”,其中:
“IP 地址”项目需要更改为网段内不冲突的地址;
“网关”或“路由器”项目需要更改为旁路网关 IP 地址;
“前缀长度”项目填写“24”;
“DNS”项目需要更改为旁路网关 IP 地址(两个 DNS 输入框填写一个就可以)。
完成并提交设置后,关闭 WIFI 开关再打开,连接设置的 WIFI 热点,若当前网络参数为设定值,则证明设置成功。
Windows:
Windows 设置
在无线热点的“属性”界面下,点击 “IP 设置 - 编辑”按钮,在弹出框中更改 IP 分配模式为“手动”,打开 IPV4 的开关,根据所处网段及上文安卓的相关设置填写相关参数即可。
注意事项
文章所述方案适用于光猫或路由器已完成宽带拨号的网络环境,未测试也不推荐使用 Docker 内的 OpenWrt 进行宽带拨号;
OpenWrt 容器跟随树莓派系统启动,无需手动干预;
由于容器内系统内核共享宿主机内核,所以在 Luci 面板的 “内核版本”项与宿主机内核版本一致;
在对容器进行停止或删除操作时,树莓派可能会发生卡顿现象,SSH 可能会断开,1~2 分钟后会恢复正常,目前原因不明;
经测试,发现 Adblock 不工作,UnblockNeteaseMusic 需要自行设置代理,除此之外容器中的 OpenWrt 多数应用工作正常。
参考资料
1.OpenWrt By Lean · coolsnowwolf/lede - GitHub
2.【小狮子编译贴】抛砖引玉,为打造N1路由神器 - 恩山无线论坛
3.docker openwrt 踩坑的几个小问题解决过程分享 - 恩山无线论坛
4.N1刷入LEAN OPENWRT做旁路网关,导致访问国内网站卡顿 - 恩山无线论坛
其他Docker镜像:
OpenWrt-Docker(amd64)
Dockerhub:https://hub.docker.com/r/zzsrv/openwrt
OpenWrt-Docker(arm64)