今天小苏为大家带来的是(咕很久的)在 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 镜像将跟随自编译固件的更新而更新。自编译固件的详细介绍请见:
https://mlapp.cn/369.html

但值得注意的是,Docker 固件没有无线及无线相关功能。在以后的文章中,小苏将给大家分享 OpenWrt 镜像的制作步骤,敬请期待~(Q:喂!你挖的坑还不够多吗?A:咕咕咕!)。

重要说明

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 功能介绍(内含下载链接):

https://github.com/openfans-community-offical/Debian-Pi-Aarch64

下载时推荐选择“无桌面基础系统加强版”(如下图),如果你有图形界面需求,也可以选择带图形界面的其他版本镜像。

下载镜像烧写到树莓派的 SD 卡并上电开机后,系统会自动完成扩展 SD 卡空间的操作,这个过程大约需要3~5分钟(期间会重启几次)。估摸着时间差不多以后,用网线将树莓派的板载网口与路由器的 Lan 口连接,之后连接树莓派的 SSH:

用户名:pi
密码:raspberry

准备工作到此结束。

步骤开始

成功登陆到树莓派的 SSH 后,在拉取镜像之前,我们还需要进行一些额外的工作:

  1. 打开网卡混杂模式

sudo ip link set eth0 promisc on
  1. 创建网络(须结合实际网络情况,不能照抄命令)

docker network create -d macvlan --subnet=192.168.123.0/24 --gateway=192.168.123.1 -o parent=eth0 macnet

这一条命令需要根据树莓派所处的网络环境来做修改,可以使用 sudo ifconfig命令来查看树莓派 eth0 网卡获得的 IP 地址,如果树莓派获得的 IP 地址为 192.168.2.154,那么说明树莓派处在 192.168.2.x网段,相应的,命令中的192.168.123.0和192.168.123.1需要被替换成 192.168.2.0和192.168.2.1:

docker network create -d macvlan --subnet=192.168.2.0/24 --gateway=192.168.2.1 -o parent=eth0 macnet

此时,我们使用 docker network ls命令可以看到网络macnet已建立成功:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
10e676133746        bridge              bridge              local
f5308b94e8fa        host                host                local
16745ea66852        macnet              macvlan             local
5e72e41ea02a        none                null                local
  1. 拉取镜像

若身处国内,为提高拉取速度,请拉取阿里云仓库中的镜像:

docker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:latest

同时小苏也提供存放在 Docker 官方仓库 中的镜像:

docker pull sulinggg/openwrt:latest

镜像拉取完成后,我们可以执行docker images命令查看现存镜像:

$ docker images
REPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZE
registry.cn-shanghai.aliyuncs.com/suling/openwrt        latest              4f4bc5dca2d9        3 hours ago         112MB

可见,镜像已成功拉取到本地。

  1. 创建并启动容器

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命令查看当前运行的容器:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a26cee7cade6        openwrt:latest      "/sbin/init"        3 hours ago         Up 3 hours                              openwrt

若容器运行信息STATUS列为 UP状态,则说明容器运行正常。

  1. 进入容器并修改相关参数

(须结合实际网络情况,不能照抄配置)

docker exec -it openwrt bash

其中:
openwrt为容器名称;
bash为进入容器后执行的命令。
执行此命令后我们便进入 OpenWrt 的命令行界面,首先,我们需要编辑 OpenWrt 的网络配置文件:

vim /etc/config/network

我们需要更改 Lan 口设置:

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,则需要这样修改:

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 冲突)。

  1. 重启网络

/etc/init.d/network restart
  1. 进入控制面板

在浏览器中输入第 5 步option ipaddr 项目中的 IP 进入 Luci 控制面板,若option ipaddr 的参数为 192.168.123.100,则可以在浏览器输入 http://192.168.123.100进入控制面板。

用户名:root
密码:password

  1. 关闭 DHCP 服务

在 “网络 - 接口 - Lan - 修改” 界面中,勾选下方的 “忽略此接口(不在此接口提供 DHCP 服务)”,并“保存&应用”。

  1. 主路由 DHCP 设置

进入路由器后台中,将主路由的 DHCP 的默认网关和 DNS 服务器设置为第 5 步中option ipaddr 项目中的 IP。

  1. 重新连接路由器

完成以上操作后,断开设备(如手机,电脑)与路由器的连接,重新连接路由器,连接路由器的设备将获取到我们设置到的 IP。

其他修复

  1. 关闭 WLAN 硬件加速

设置旁路路由后,若出现访问国内网站网速慢,不稳定的情况(多见于 Pandavan 及其改版固件,如华硕老毛子固件),请在路由器的控制面板中关闭有关 WLAN 的硬件加速,比如选择“Offload TCP/UDP for LAN”(若未出现此现象请忽略):

  1. 宿主机网络修复

OpenWrt 容器运行后,宿主机内可能无法正常连接外部网络,需要修改宿主机的 /etc/network/interfaces 文件以修复:

(须结合实际网络情况,不能照抄配置)

cp /etc/network/interfaces /etc/network/interfaces.bak # 备份文件
vim /etc/network/interfaces # 使用 vim 编辑文件

以“树莓派爱好者基地”64 位 Debian 为例,向文件末尾添加:

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

其中,所有的 192.168.123.x都需要按照树莓派所处网段更改,gateway和dns-nameservers填写路由器的 IP,若树莓派获得的 IP 为 192.168.2.154,路由器 IP 为192.168.2.1,则需要这样修改:

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参数中的地址。

  1. 手动指定网关

如果路由器固件不支持自定义 DHCP 服务的网关及 DNS 地址(常见于路由器官方固件),或者只希望局域网下的个别设备接入旁路网关时,须在接入设备上做以下配置:

安卓:

需要在安卓的 WIFI 设置内将 IP 获取方式更改为“静态”或“手动”,其中:
“IP 地址”项目需要更改为网段内不冲突的地址;
“网关”或“路由器”项目需要更改为旁路网关 IP 地址;
“前缀长度”项目填写“24”;
“DNS”项目需要更改为旁路网关 IP 地址(两个 DNS 输入框填写一个就可以)。

完成并提交设置后,关闭 WIFI 开关再打开,连接设置的 WIFI 热点,若当前网络参数为设定值,则证明设置成功。

Windows:

在无线热点的“属性”界面下,点击 “IP 设置 - 编辑”按钮,在弹出框中更改 IP 分配模式为“手动”,打开 IPV4 的开关,根据所处网段及上文安卓的相关设置填写相关参数即可。

注意事项

  1. 文章所述方案适用于光猫或路由器已完成宽带拨号的网络环境,未测试也不推荐使用 Docker 内的 OpenWrt 进行宽带拨号;
  2. OpenWrt 容器跟随树莓派系统启动,无需手动干预;
  3. 由于容器内系统内核共享宿主机内核,所以在 Luci 面板的 “内核版本”项与宿主机内核版本一致;
  4. 在对容器进行停止或删除操作时,树莓派可能会发生卡顿现象,SSH 可能会断开,1~2 分钟后会恢复正常,目前原因不明;
  5. 经测试,发现 Adblock 不工作,UnblockNeteaseMusic 需要自行设置代理,除此之外容器中的 OpenWrt 多数应用工作正常,如有发现不能正常工作的应用请评论反馈~

参考资料

  1. OpenWrt By Lean · coolsnowwolf/lede - GitHub
  2. 【小狮子编译贴】抛砖引玉,为打造N1路由神器 - 恩山无线论坛
  3. docker openwrt 踩坑的几个小问题解决过程分享 - 恩山无线论坛
  4. N1刷入LEAN OPENWRT做旁路网关,导致访问国内网站卡顿 - 恩山无线论坛