本文最后更新于 2026-10-04,文章内容可能已过时,如需更新请留言。部分素材来自网络,若不小心影响到您的利益,请联系我删除。

写在前面

在 Homelab 的世界里,服务器是干活的主力,但网络架构才是那个决定你能不能优雅“连上世界”的命脉。而这个命脉的操控权,必须交给我们自己编译的 ImmortalWrt 软路由。

1. 为什么选 ImmortalWrt?

折腾软路由的人都知道,官方 OpenWrt 干净是干净,但装个驱动、配个环境常常让人化身修路工;而某些魔改固件虽然花哨,又总让人担心藏了什么不明后门。

  • 拿来即战:ImmortalWrt 完美避开了官方版“清汤寡水”的尴尬,把国内玩家最需的驱动、网卡适配和组件提前备好,省去无数编译报错的烦恼。

  • 拒绝黑盒闭源:它既没有臃肿不堪的商业包袱,也没有来历不明的闭源二进制组件。代码干净透明,每一行流量都清清白白,安全感直接拉满。

2. 为什么 Homelab 离不开软路由?

  • 别让路由器成为性能黑洞:当你在实验室跑满千兆带宽、挂着几十个 Docker 容器、还要做全流量代理和广告过滤时,普通硬路由的 CPU 早就原地过热宕机了。软路由用纯粹的 x86 算力教它们重新做“机”。

  • 网络拓扑你说了算:VLAN 划分、多网卡聚合、精细化分流规则、内网穿透与组网——硬路由做不到的骚操作,在这里全都是基本功。

接下来的课程,我们将放弃现成固件的盲盒体验,从搭建编译环境开始,亲手捏出属于你自己的 ImmortalWrt 专属固件,完成刷机并正式掌控你的数字主权。

一、准备工作:编译环境要求与检查

编译 ImmortalWrt 不挑硬件,但对系统环境有明确要求。官方推荐的配置如下

项目

最低要求

推荐配置

说明

操作系统

Debian 11

Debian 11/12 或 Ubuntu LTS

其他发行版亦可,但软件包名可能不同

CPU 架构

AMD64(x86_64)

4 核以上 AMD64

其他架构理论上可行,但需要更多技巧,官方不提供任何保证

内存

4 GB

8 GB 及以上

内存不足会导致编译进程被系统杀死

磁盘空间

25 GB 可用

50 GB 及以上

工具链、内核源码与中间产物非常占空间

网络

可访问国际互联网

境外 VPS 或带代理的网络

编译时需从全球各镜像站下载数百个源码包

最省心的方案是直接购买一台境外 VPS(如常见的美西、日本、新加坡节点),网络通畅、按量付费,编译完即可销毁。本地虚拟机同样可行。机器到手后,先用下面几条命令确认环境是否达标:

uname -a          # 查看内核与 CPU 架构,应显示 x86_64
free -h           # 查看内存,Mem 应不小于 4G
df -h /           # 查看磁盘剩余空间,Avail 应不小于 25G
nproc             # 查看 CPU 线程数,后面编译要用

编译前的四条铁律(官方明确警告)

  • 全程使用普通用户编译,不要用 root,也不要给 make 加 sudo。只有安装系统依赖这一步需要 sudo。

  • PATH 环境变量和工作目录路径中不能有空格或非 ASCII 字符(例如不要在 /home/张三/编译 目录/ 下操作)。

  • 使用 WSL 时,必须先把 Windows 目录从 PATH 中移除,详见 WSL 构建文档。

  • 不推荐用 macOS 作为编译宿主机,官方不提供保证。

如果你的 VPS 默认只有 root 账户,先创建一个普通用户并授予 sudo 权限,后续所有编译操作都在该用户下进行:

adduser builder
usermod -aG sudo builder
su - builder

二、安装编译依赖

编译需要一整套构建工具链(gcc、make、git、python3 等)。官方给出了两种等效方案,二选一即可。

方案一:通过 APT 手动安装

先更新系统,再一次性装齐全部依赖包。适合想了解到底装了什么、或需要对环境做精细控制的用户:

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 clang cmake cpio curl device-tree-compiler ecj fastjar flex gawk gettext gcc-multilib \
  g++-multilib git gnutls-dev gperf haveged help2man intltool lib32gcc-s1 libc6-dev-i386 libelf-dev \
  libglib2.0-dev libgmp3-dev libltdl-dev libmpc-dev libmpfr-dev libncurses-dev libpython3-dev \
  libreadline-dev libssl-dev libtool libyaml-dev libz-dev lld llvm lrzsz mkisofs msmtp nano \
  ninja-build p7zip p7zip-full patch pkgconf python3 python3-pip python3-ply python3-docutils \
  python3-pyelftools qemu-utils re2c rsync scons squashfs-tools subversion swig texinfo uglifyjs \
  upx-ucl unzip vim wget xmlto xxd zlib1g-dev zstd

方案二:官方一键脚本

项目维护了一个自动识别发行版并安装依赖的脚本,一行命令搞定,适合追求效率的用户:

sudo bash -c 'bash <(curl -s https://build-scripts.immortalwrt.org/init_build_environment.sh)'

提示

full-upgrade 可能升级了内核,建议执行 sudo reboot 重启一次再继续。若方案一提示个别包找不到(如 lib32gcc-s1),通常是系统版本差异导致包名变化,先 apt search 关键词 找到对应包名再安装即可。

三、克隆源码与分支选择

使用 git 将源码克隆到本地(后续命令均在普通用户下执行):

git clone -b openwrt-25.12 --single-branch --filter=blob:none https://github.com/immortalwrt/immortalwrt
cd immortalwrt

这条命令的三个参数各有用途:

  • -b <branch>:指定要克隆的分支,替换为你想编译的版本;

  • --single-branch:只克隆这一个分支,不拉取全部分支历史;

  • --filter=blob:none:按需下载文件内容(部分克隆),显著减少克隆体积和耗时

分支

定位

适合人群

openwrt-25.12

最新稳定分支

想要新特性又追求稳定的用户

openwrt-24.10

成熟稳定分支

新手首选,社区资料最丰富

openwrt-23.05 及更早

历史维护分支

老设备或有特定版本需求

master

开发前沿分支

开发者,可能遇到编译失败

国内网络提示

如果 GitHub 克隆速度过慢,可以为 git 配置代理,或使用可靠的 GitHub 镜像/加速服务。克隆慢只是第一步,后续 make download 阶段还需从全球镜像站下载数 GB 源码包,网络质量对整体耗时影响很大——这也是推荐境外 VPS 的主要原因。

四、更新并安装 feeds

ImmortalWrt 主仓库只包含构建系统与核心组件,绝大多数软件包(LuCI 网页界面、网络工具、驱动等)都由独立的 feeds 源仓库维护,定义在 feeds.conf.default 文件中。因此克隆完源码后必须先同步 feeds:

./scripts/feeds update -a     # 拉取 feeds.conf.default 中定义的所有软件包定义
./scripts/feeds install -a    # 将所有软件包以符号链接安装到 package/feeds/ 目录

两条命令的分工:update 相当于「更新软件源列表」,install 相当于「把软件包注册进构建系统」。只有 install 过的包才会出现在后续的 menuconfig 菜单里。

添加第三方软件源(可选)

如果需要官方源之外的插件(例如社区维护的 LuCI 应用集),可以在 feeds.conf.default 末尾追加一行 src-git 源名 仓库地址;分支,再重新执行上面两条命令:

# 格式:src-git <源名称> <git仓库地址>;<分支>(分支可省略)
src-git openclash https://github.com/vernesong/OpenClash.git;master

注意

第三方源的质量与安全性参差不齐,添加前请确认来源可信。另外,每次更新源码(git pull)之后,都必须重新执行这两条 feeds 命令,否则 menuconfig 中的包定义会与源码不同步,可能导致编译失败。

五、make menuconfig 配置详解

这是整个流程中最关键的一步。运行:

make menuconfig

首次运行会先编译配置工具本身,等待一两分钟即可进入蓝底菜单界面。所有配置最终保存为源码根目录下的 .config 文件。

界面操作按键

按键

作用

↑ ↓ ← →

移动光标 / 切换底部按钮

Enter

进入子菜单 / 确认选择

Y

选中,标记为 *(编译进固件)

M

标记为 M(仅编译成 ipk 模块,不装进固件)

N

取消选中(不编译)

空格

在 * / M / 空 之间循环切换

/

全局搜索配置项(找包神器)

Esc 连按两次

返回上一级菜单;在顶层退出时提示保存

三层目标选择:让固件匹配你的设备

菜单最上方的三个选项决定了固件为谁而编译,必须按顺序依次选择[3]:

  • Target System(目标系统):设备 SoC 所属的平台大类,例如 x86、MediaTek Ralink MIPS、MediaTek ARM、Qualcomm Atheros IPQ807x 等;

  • Subtarget(子目标):平台下更细的芯片分组,例如 x86 下的 x86_64,联发科 ARM 下的 Filogic 8x0 (MT798x);

  • Target Profile(目标机型):具体设备型号,例如 Generic x86/64(软路由虚拟机通用)或你的路由器具体型号。

不确定设备属于哪个平台?在 Firmware Selector 搜索你的设备型号,下载页 URL 中的 /targets/xx/yy/ 即对应 Target System 和 Subtarget[4]。也可以在 menuconfig 里按 / 直接搜索设备型号关键词。

常用配置菜单一览

菜单路径

内容

典型用途

Target Images

固件镜像格式

x86 平台勾选 squashfs / ext4,是否生成 EFI 镜像

LuCI → Collections

网页界面套件

必选 luci,否则无网页后台

LuCI → Applications

各类 LuCI 插件

按需勾选 UPnP、DDNS、SQM、WOL 等应用

Kernel modules

内核驱动模块

USB 网卡/存储驱动、文件系统支持

Network

网络工具

VPN 客户端、iperf3 测速等

Utilities

系统工具

磁盘分区工具、lsblk、htop 等

在 make menuconfig 的 Target Images 菜单下最好把Root filesystem partition size (in MB)和Loop device size (in MB)修改大一些,防止因为空间不够造成的编译失败,分别改称2048和4096基本就够用了。

分类

软件包名称 (Package Name)

备注与说明

核心网络与安全

tailscale / tailscaled

异地组网工具(官方 feeds 自带)

kmod-wireguard / wireguard-tools

内核态 WireGuard VPN 支持

luci-app-openclash

代理客户端(需第三方 feed)

kmod-tun / kmod-nft-tproxy

OpenClash 必需依赖组件

luci-ssl

后台 HTTPS 加密访问支持

流控与过滤

luci-app-sqm

智能流控(自动带 kmod-sched-cake, tc)

luci-app-adguardhome

DNS 广告拦截与防污染网关

基础运维与诊断

luci-app-wol

网络唤醒插件

luci-app-upnp

UPnP 端口自动映射

luci-app-ddns

动态 DNS 客户端及服务商脚本

iperf3 / htop / ethtool / iftop

性能、网络基准测试与系统监视工具

ss / mtr-nojson / tcpdump-mini

网络诊断与抓包工具

netdata / luci-app-netdata

高性能实时系统监控图表

luci-app-nlbwmon

IP 流量统计分析

luci-app-ttyd

网页端终端命令行

存储与界面美化

luci-app-diskman

硬盘分区及磁盘管理工具

luci-theme-argon

现代毛玻璃/深色高颜值主题

luci-app-argon-config

Argon 主题个性化配置插件

选包原则:宁少勿多。固件体积受设备闪存限制,不确定的包可以先不选,编译成 ipk(按 M)或事后用 opkg 在线安装。全部选好后连按 Esc 退出,选择 Yes 保存。建议顺手备份一份配置:

cp .config .config.bak
./scripts/diffconfig.sh > diffconfig.txt   # 导出与默认配置的差异,便于跨机器复用

六、下载依赖包与开始编译

先预下载源码包

正式编译前,建议先把所有需要的源码包下载到本地 dl/ 目录。这样可以把「网络问题」和「编译问题」分开排查,中途断网重跑命令会自动续传:

make download -j$(nproc) V=s

开始编译

make -j$(nproc) V=s

参数说明:-j$(nproc) 让编译任务跑满全部 CPU 线程;V=s 输出完整编译日志,出错时能看到具体原因。编译会自动完成三件事:下载校验源码、构建交叉编译工具链、交叉编译内核与所有选中的软件包[1]。

  • 首次编译约 1–3 小时(取决于 CPU、内存与网络),大部分时间花在工具链与内核上;

  • 之后修改配置再编译是增量编译,通常几分钟到十几分钟;

  • 官方依赖里已包含 ccache,二次编译会命中缓存进一步提速。

编译报错的正确排查姿势

多线程编译时,真正的错误信息会被其他线程的日志淹没。一旦失败,改用单线程重跑:make -j1 V=s,日志末尾就是第一个真实错误。排错思路可参考 OpenWrt 构建系统文档,修复后再切回多线程继续。

七、获取固件产物

编译顺利完成(日志末尾无 Error)后,固件位于 bin/targets/<目标系统>/<子目标>/ 目录下,例如 x86/64 平台的产物在 bin/targets/x86/64/:

ls -lh bin/targets/*/*/

文件类型

使用场景

*-factory(.img / .bin)

从原厂固件第一次刷入 ImmortalWrt 时使用

*-sysupgrade(.bin / .img.gz)

已经是 OpenWrt/ImmortalWrt 系统时,在网页后台或命令行升级使用

sha256sums

各镜像的校验值,下载到本地后建议先校验完整性再刷机

packages/ 目录

所有编译出的 ipk 软件包,可搭建本地 opkg 源

用 scp 或 rsync 把固件从 VPS 拉回本地(以 x86 EFI 镜像为例):

scp builder@<VPS地址>:~/immortalwrt/bin/targets/x86/64/*-squashfs-combined-efi.img.gz ./

刷机提醒

刷机有风险,操作前请确认固件与设备型号严格匹配,并提前了解设备的救砖/恢复方式(如 Breed、U-Boot、TTL 串口)。 factory 与 sysupgrade 用错场景是常见的变砖原因之一。

八、更新源码与二次编译

官方会持续修复漏洞、更新软件包,建议每隔一段时间同步源码编译新固件:

git pull                        # 拉取最新源码
./scripts/feeds update -a       # 同步 feeds(必做)
./scripts/feeds install -a      # 重新安装 feeds(必做)
make menuconfig                 # 检查/调整配置,退出时保存
make download -j$(nproc) && make -j$(nproc) V=s

当编译出现解释不清的怪异错误时,往往需要清理构建缓存。三个清理级别从轻到重:

命令

清理范围

保留

典型场景

make clean

编译输出目录 bin/ 与 build_dir/

工具链、.config、dl 缓存

个别包编译异常后的常规重编

make dirclean

在 clean 基础上加删交叉编译工具链等

.config、dl 缓存

源码大版本更新后,相当于全新编译

make distclean

一切,包括 .config 与 feeds 链接

dl 下载缓存

彻底推倒重来(务必备份 .config)

效率技巧

  • 只重编某个软件包:make package/<包名>/{clean,compile} V=s,无需整树重编;

  • 需要调整内核参数时可用 make kernel_menuconfig 进入内核配置界面;

  • 把 .config.bak 或 diffconfig.txt 存到本地,换 VPS 后放回源码根目录执行 make defconfig 即可还原配置。