最近尝试了网上找的各种OpenWRT固件(大多数都是从恩山论坛上找到的),要么是插件太多导致各种BUG与不必要的资源占用,要么就是插件少的可怜,没有自己需要的插件。其次别人编译的固件还是不太放心害怕固件作者夹带私货,网关系统如果后门将严重威胁内网网络安全。遂尝试自己拉取源码自行编译固件。本篇文章旨在记录笔者在自行编译OpenWRT固件时的流程、注意事项与遇到问题的相关解决方案。

同时我也会放出我自己编译的固件,保证安全,原汁原味,想要现成的可以直接去文末下载

2022-11-20日更新:

新构建的x86_64软路由固件,编译出来的所有文件放GitHub的Releases里了,请根据需要自行下载:https://github.com/hash070/lede/releases

1668927910515.webp

系统与环境准备

配置虚拟机

编译OpenWRT推荐使用VMWareWorkstation创建一个Ubuntu虚拟机,在本地虚拟机里编译。

我之前写过关于如何创建Ubuntu虚拟机的文章,如果你还没有Ubuntu虚拟机的话可以去看这篇文章

关于虚拟机配置:cpu核心数越多越好,硬盘应至少给划50GB,内存推荐4G以上

创建完虚拟机后,你需要配置Ubuntu的代理,有人认为应该在墙外租一台服务器专门用来编译固件,我的观点是没有必要这么麻烦,一是费钱,二是耗费时间,编译一次OpenWRT固件需要耗费大量的CPU算力,以我的8核16线程的CPU为例,首次完整的编译需要大概一小时左右,去租的小鸡单核跑估计需要一整天。

首先确保你的虚拟机里的Ubuntu能访问国际互联网。

我推荐的代理软件有:ShellClash还有Clash for Windows

前者自己去Google搜一下就找到了

后者的话我这里找到一篇教程:https://www.cnblogs.com/Jiang13537/p/15571504.html

配置好之后在虚拟机终端执行一下这一行命令可以轻松检查是否通网

curl google.com

如果有返回结果就说明没问题,可以继续下一步,如果卡住不动则说明网络有问题,请重新检查网络配置。

更新系统与安装依赖

在终端中粘贴执行以下命令

sudo apt update -y
sudo apt full-upgrade -y
sudo apt install -y ack antlr3 asciidoc autoconf automake autopoint binutils bison build-essential \
bzip2 ccache cmake cpio curl device-tree-compiler fastjar flex gawk gettext gcc-multilib g++-multilib \
git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libglib2.0-dev libgmp3-dev libltdl-dev \
libmpc-dev libmpfr-dev libncurses5-dev libncursesw5-dev libreadline-dev libssl-dev libtool lrzsz \
mkisofs msmtp nano ninja-build p7zip p7zip-full patch pkgconf python2.7 python3 python3-pip qemu-utils \
rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev

开始首次编译

不要使用root用户执行编译,会造成权限污染与报错

拉取源代码

拉取源代码到本地

git clone https://github.com/coolsnowwolf/lede.git

添加自定义源(因为默认没有留学插件,需要自己添加)

#进入刚克隆的目录
cd lede/
#添加依赖并安装依赖,然后进入菜单
sed -i '$a src-git kenzo https://github.com/kenzok8/openwrt-packages' feeds.conf.default
sed -i '$a src-git small https://github.com/kenzok8/small' feeds.conf.default
git pull
./scripts/feeds update -a
./scripts/feeds install -a
make menuconfig

选择菜单(重点)

选择目标系统与目标镜像

执行make menuconfig命令可以进入菜单

我们可以看到如下界面

image-20220610201310196

前三项如果你是x86软路由或电脑用户就不用管,如果是为了给硬路由编译的话请选择自己路由器对应的架构、芯片型号和产品型号。(光标移动到对应选项后,按下Y键勾选,按下N键取消选中)

这里重点说第四项Target Images

一般来说按我这样勾选就够用了

image-20220610201849412

注意倒数两项的参数,如果你选择的插件数量较多,建议把它们分别设为256和512

如果你的设备存储空间很小,那么就把这俩参数调小,然后少选点插件就好了。

选择插件与主题

往下翻,选择倒数第七个选项LuCI,可以看到如下界面

image-20220610204430130

其中第三项Applications就是插件目录,可以进去选择你需要的插件。(如果是硬路由务必记得勾选 luci-app-mtwifi 闭源的 Wi-Fi 驱动)

列表中插件的翻译与用途说明:https://www.right.com.cn/forum/thread-344825-1-2.html

注意:第一次选择的时候插件不要选太多,特别是留学插件,选多了可能会发生冲突报错,我在这里翻车好多次

留学插件勾选BypassPassWall2就行了,这俩用着不错

还有不要勾选fileassistant插件,会导致报错

(当光标移动到插件上时,按下Y键勾选,按下N键取消选中,按下M键表示模块化该组件)

image-20220610205123516

第四项Themes是主题目录,可以选择你喜欢的OpenWRT主题。

添加CloudFlare DDNS支持(可选)

默认OpenWRT不支持CF的ddns,就算你勾选了ddns插件也没用,你需要手动在菜单中勾选相应组件。

它的位置在Network->IP Address and Names->ddns-scripets_cloudflare.com-v4

image-20220610210149667

添加IPv6支持(可选)

随着IPv4地址的枯竭与IPv6的普及,未来运营商可能会不再提供IPv4地址,先把这个功能加上可以应对未来的需要。

勾选ipv6helper即可

位置:Extra packages->ipv6helper

添加额外的软件包(可选)

如果你想装一些依赖包里没有的其他的插件,比如说校园网认证插件,可以将源码拉取到package目录之下,然后再更新依赖。

编译

在菜单中选择并保存后,就可以开始编译了。

首先下载所需的软件包

make download -j8 V=s

然后是开始编译,这里的-j指的是线程数,你的虚拟机有几个后面写几,求稳的话写1

make -j8 V=s

二次编译

更新本地编译环境

# 更新软件列表、升级软件包
sudo sh -c "apt update && apt upgrade -y"

# 拉取最新源码
cd ~/openwrt && git pull

# 更新下载安装订阅源包含的软件包
cd ~/openwrt
./scripts/feeds update -a && ./scripts/feeds install -a

清理旧文件

# 删除/bin和/build_dir目录中的文件
make clean

如果要更换架构,例如要从 x86_64 换到 MediaTek Ralink MIPS 建议执行以下命令深度清理 /bin/build_dir 目录的中的文件 (make clean) 以及 /staging_dir/toolchain/tmp/logs 中的文件。

make dirclean

如果需要对组件重新调整,则建议先删除旧配置

rm -rf ./tmp && rm -rf .config

根据自己的定制需求,再次调整 Open­Wrt 系统组件

make menuconfig

下载编译所需的软件包

make download -j8 V=s

编译 Open­Wrt 固件

make -j8 V=s

二次编译可以优先使用多线程

关于生成的文件

编译成功后我们可以在如下目录找到生成的镜像文件

image-20220610211456685

至于怎么用就不说了,iso、img(img.gz解压出来就是)、vmdk都有了,直接用就是了。

其中带combined字样的只支持BIOS启动,带combined-efi的支持UEFI启动。

我自己编译的固件:

image-20220610213700356

image-20220610213720282

image-20220610213741640

image-20220610213801680

关于OpenWRT端口转发NAT回环问题

在本文开头放上的最新固件中已解决这个问题

这个版本的代码固件有一点点瑕疵:

防火墙端口转发,就算勾选启用 NAT 环回。最终也是无效果的。最终的影响就是无法在内网访问被映射出去的公网地址,例如把RDP远程桌面转发出去,外网可访问,内网无法访问。

原因与解决方案:

原因不是NAT loopback不起作用,而是bridge防火墙给阻挡了回流的流量,
如已经编译可以通过执行以下步骤来修复

修改/etc/sysctl.conf

vi /etc/sysctl.conf

可以看到里面只有一行注释,不用管注释,往里面插入如下内容然后保存并退出

net.bridge.bridge-nf-call-arptables=0
net.bridge.bridge-nf-call-ip6tables=0
net.bridge.bridge-nf-call-iptables=0

然后执行sysctl -p 命令即可修复问题。

Q.E.D.