编译自带OpenClash的OpenWrt固件


简介

本文为使用编译纯净的OpenWrt固件,并集成OpenClash。使用编译环境为ubuntu 22.04.2 LTS,如果是其他操作系统可以查看openwrt官网中文

环境

  • 操作系统: ubuntu 22.04.2 LTS

正文

配置编译环境

1. 安装依赖包

主要是安装编译环境的依赖包,如果是其他操作系统可以访问openwrt官网查看

sudo apt update
sudo apt upgrade
sudo apt install build-essential clang flex bison g++ gawk \
gcc-multilib g++-multilib gettext git libncurses5-dev libssl-dev \
python3-setuptools rsync swig unzip zlib1g-dev file wget
sudo apt-get install -y mkisofs
sudo apt-get install -y tcptraceroute
# 如果想编译VDI/VMDK镜像则需要安装
sudo apt install qemu-utils

# 或者直接全部安装
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 flex gawk gettext gcc-multilib g++-multilib \
git gperf haveged help2man intltool libc6-dev-i386 libelf-dev libfuse-dev libglib2.0-dev libgmp3-dev \
libltdl-dev libmpc-dev libmpfr-dev libncurses-dev libncurses-dev libpython3-dev libreadline-dev \
libssl-dev libtool llvm lrzsz genisoimage msmtp ninja-build p7zip p7zip-full patch pkgconf python3 \
python3-pyelftools python3-setuptools qemu-utils rsync scons squashfs-tools subversion swig texinfo \
uglifyjs upx-ucl unzip vim wget xmlto xxd zlib1g-dev

2. 拉取代码

主要是拉取源码,并切换好相应固件版本版本。

# 切换到用户根目录
cd ~
# 拉取OpenWrt,切换分支<git clone -b v22.03.4 --single-branch --depth=1 https://github.com/openwrt/openwrt.git>
git clone https://github.com/openwrt/openwrt openwrt
cd openwrt && git checkout v22.03.4 --force && cd ../
# 或者使用[lede](https://github.com/coolsnowwolf/lede)
git clone https://github.com/coolsnowwolf/lede lede
cd lede && git checkout 20230609 --force && cd ../
# 下载OpenClash
wget https://github.com/vernesong/OpenClash/archive/master.zip
# 解压
unzip master.zip
# 复制OpenClash软件包到OpenWrt
cp -r OpenClash-master/luci-app-openclash openwrt/package
chmod -R 777 openwrt && chmod -R +x openwrt && cd openwrt

PS

科学上网配置:

export http_proxy="http://127.0.0.1:7890"
export https_proxy="http://127.0.0.1:7890"

3. 配置参数

此步骤主要配置编译参数。

配置第三方插件,修改源代码里的 feeds.conf.default 文件,保存着软件包订阅,执行如下命令:

sed -i '1i src-git kenzo https://github.com/kenzok8/openwrt-packages' feeds.conf.default
sed -i '2i src-git Openclash https://github.com/vernesong/OpenClash' feeds.conf.default
sed -i '2i src-git passwall2 https://github.com/xiaorouji/openwrt-passwall2.git' feeds.conf.default
# sed -i '2i src-git istore https://github.com/linkease/istore;main' feeds.conf.default

# sed -i '2i src-git small https://github.com/kenzok8/small' feeds.conf.default

修改固件初始参数

# 修改默认ip
sed -i 's/192.168.1.1/192.168.3.1/g' package/base-files/files/bin/config_generate
# 替换终端为bash
sed -i 's/\/bin\/ash/\/bin\/bash/' package/base-files/files/etc/passwd

下载插件与依赖

./scripts/feeds update -a
./scripts/feeds install -a
# 进入交互式配置界面
make menuconfig

如果遇到报错,可尝试使用下面命令修复

./scripts/feeds update -i -f 
./scripts/feeds install -a -f

配置界面修改内容

# 选择系统(以 x86_64 为例)
Target System -> x86
Subtarget -> x86_64
# 选择固件的文件系统
# https://openwrt.org/docs/techref/filesystems
Target Images -> squashfs

# 选择构建X86_X64的GRUB固件
Target Images -> Build GRUB images (Linux x86 or x86_64 host only) 

# 选择更小的压缩格式固件,方便复制
Target Images -> GZip images

# 修改软件包可用空间,默认安装会占用100M左右,建议修改扩大,为后续安装其他软件打基础
Target Images -> Root filesystem partition size

# 添加web界面
LuCI -> Collections -> Luci

# 添加中文
LuCI -> Modules -> Translations -> Chinese Simplified

# 添加openclash
LuCI -> Applications -> luci-app-openclash  

# 添加兼容性依赖
LuCI -> Modules -> luci-compat

# 添加主题
LuCI -> Themes

# 添加wget
Nerwork -> File Transfer -> wget-ssl

# 添加kmod-tun,TUN模式必须
# Kernel modules -> Network Support -> kmod-tun

# 排除dnsmasq,由于默认会安装dnsmasq-full,这里需要排除dnsmasq,否则会冲突报错。
Base system -> dnsmasq 

PS:

  • 菜单解释:

    • Target System (x86) —> 目标系统(x86)
    • Subtarget (x86_64) —> 子目标(x86_64)
    • Target Profile (Generic) —>目标配置文件(通用)
    • Target Images —> 保存目标镜像的格式
    • Global build settings —> 全局构建设置
    • Advanced configuration options (for developers) —- 高级配置选项(适用于开发人员)
    • Build the OpenWrt Image Builder 构建OpenWrt图像生成器
    • Build the OpenWrt SDK 构建OpenWrt SDK
    • Package the OpenWrt-based Toolchain 打包基于OpenWrt的工具链
    • Image configuration —>图像配置
    • Base system —> 基本系统
    • Administration —> 管理
    • Boot Loaders —> 引导加载程序
    • Development —> 开发
    • Extra packages —> 额外包
    • Firmware —>固件
    • Fonts —>字体
    • Kernel modules —> 内核模块
    • Languages —>语言
    • Libraries —> 图书馆
    • LuCI —> LuCI
    • Mail —> 邮件
    • Multimedia —>多媒体
    • Network —>网络
    • Sound —> 声音
    • Utilities —>实用程序
    • Xorg —>Xorg
  • 菜单选项

    • [] 空的,不安装
    • [M] 仅编译,不安装项(可以在部署完成后手动安装以降低固件大小)
    • [*] 即为编译并安装
  • 添加DockerMan

    • LuCI > Applications -> luci-app-dockerman
    • Utilities -> dockerd
    • Utilities -> docker-compose
  • 添加luci-app-store
    • LuCI > Applications -> luci-app-store
    • LuCI > Libraries -> luci-lib-ipkg
    • LuCI -> Modules -> luci-compat

编译

1. 初次编译

# 下载dl库(尽量科学上网),完成后检查是否有报错,如有问题可以百度或与我联系。
make -j8 download V=s
# 第一次编译推荐用单线程,如下
make -j1 V=s | tee ../compile.log
# 开始编译,预计时间在30分钟以上,最终生成固件存放位置为openwrt/bin/targets/x86/64/目录下
make -j8 V=s | tee ../compile.log

PS:

+ -j8: 为线程数,推荐第一次使用单线程编译,否则你编译错误,连调试信息都没有,根本不知道哪里错的。
+ V=s: 为故障排除目的提供更详细的信息

2. 再次编译

# 切换到用户根目录
cd ~
# 删除旧的openclash文件
rm -rf master.zip && rm -rf OpenClash-master && rm -rf openwrt/package/luci-app-openclash
cd openwrt
# 更新openwrt
git pull
# 切换版本
git checkout v22.03.4
# 回到上级目录
cd ~
# 重新下载OpenClash
wget https://github.com/vernesong/OpenClash/archive/master.zip
# 解压
unzip master.zip
# 复制OpenClash软件包到OpenWrt
cp -r OpenClash-master/luci-app-openclash openwrt/package
cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a
# 配置
make menuconfig
# 下载dl库(国内请尽量进行科学上网)
make -j8 download V=s
# 开始编译
make -j4 V=s

PS:

  • 如果源码没有变化的情况下,可以使用以下命令清除缓存
    • make clean 仅清理编译结果(bin目录)
    • make dirclean 清理所有编译文件(除了.config、dl文件夹和feeds以外都清理)
    • make distclean 清理所有编译文件以及相关依赖(完全清理干净,一键回到刚git clone下来的时候)

磁盘扩容

  • EXT4固件
# 更新
root@OpenWrt:~# opkg update
# 安装工具,有的话就不用执行了
root@OpenWrt:~# opkg install fdisk blkid losetup resize2fs losetup

# 查看所有磁盘情况,根据你的固件容量来确定磁盘,我这里是/dev/nvme0n1p2。
root@OpenWrt:~# fdisk -l 
Device            Start        End    Sectors  Size Type
/dev/nvme0n1p1      512     262655     262144  128M Linux filesystem
/dev/nvme0n1p2   262656 3907029134 3906766479  1.8T Linux filesystem
/dev/nvme0n1p128     34        511        478  239K BIOS boot
# 如果是efi的固件,需要查看磁盘UUID,内容如下,需要记住/dev/nvme0n1p2的uuid
root@OpenWrt:~# blkid
/dev/nvme0n1p1: SEC_TYPE="msdos" LABEL_FATBOOT="kernel" LABEL="kernel" UUID="1234-ABCD" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="d6b1a2a3-2779-6abf-11c0-d2ab38723801"
/dev/nvme0n1p2: LABEL="rootfs" UUID="ff313567-e9f1-5a5d-9895-3ba130b4a864" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="d6b1a2a3-2779-6abf-11c0-d2ab38723802"
/dev/nvme0n1p128: PARTUUID="d6b1a2a3-2779-6abf-11c0-d2ab38723880"
/dev/sda2: SEC_TYPE="msdos" LABEL="EFI" UUID="0F1C-07BD" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="bc6e54ce-02"
/dev/sda1: LABEL="EasyU" BLOCK_SIZE="512" UUID="40DE32A6DE32945E" TYPE="ntfs" PARTUUID="bc6e54ce-01"

# 修改磁盘,loop1为你的磁盘
root@OpenWrt:~# fdisk /dev/nvme0n1p2
# 查看磁盘的分区情况,输入p,记住/dev/nvme0n1p2的起始扇区,这里是262656
Command (m for help): p
Disk /dev/nvme0n1: 1.82 TiB, 2000398934016 bytes, 3907029168 sectors
Disk model: KIOXIA-EXCERIA PRO SSD                  
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: D6B1A2A3-2779-6ABF-11C0-D2AB38723800

Device            Start        End    Sectors  Size Type
/dev/nvme0n1p1      512     262655     262144  128M Linux filesystem
/dev/nvme0n1p2   262656 3907029134 3906766479  1.8T Linux filesystem
/dev/nvme0n1p128     34        511        478  239K BIOS boot

Partition table entries are not in disk order.

# 如果是efi的固件,这里也可以查看分区的uuid,输入命令i,然后再输入分区编号2即可查看。
Command (m for help): i
Partition number (1,2,128, default 128): 2

         Device: /dev/nvme0n1p2
          Start: 262656
            End: 3907029134
        Sectors: 3906766479
           Size: 1.8T
           Type: Linux filesystem
      Type-UUID: 0FC63DAF-8483-4772-8E79-3D69D8477DE4
           UUID: D6B1A2A3-2779-6ABF-11C0-D2AB38723802
# 删除分区,输入d,回车后输入分区编号,这里同样是2.
Command (m for help): d
Partition number (1,2,128, default 128): 2

Partition 2 has been deleted.
# 新创建分区,输入n,回车后输入要创建的分区编号2,这里与你删除的分区编号一致,回车后输入前面记住的起始扇区,然后回车输入截止扇区,直接回车为默认所有。最后提示,是否移除分区的签名,这里一定要输入n,不然镜像会出问题。
Command (m for help): n
Partition number (2-127, default 2): 2
First sector (262656-3907029134, default 264192): 262656
Last sector, +/-sectors or +/-size{K,M,G,T,P} (262656-3907029134, default 3907029134): 

Created a new partition 2 of type 'Linux filesystem' and of size 1.8 TiB.
Partition #2 contains a ext4 signature.

Do you want to remove the signature? [Y]es/[N]o: n

# 如果是efi固件,按x进入高级菜单,然后输入u,选择分区,写入UUID,把之前记录的UUID输入进去,非efi固件忽略这一步,完成后输入r退出。
Command (m for help): x

Expert command (m for help): u
Partition number (1,2,128, default 128): 2

New UUID (in 8-4-4-4-12 format): D6B1A2A3-2779-6ABF-11C0-D2AB38723802

Partition UUID changed from AF4F0401-CA06-6D4E-88D1-1F1AECE78E13 to D6B1A2A3-2779-6ABF-11C0-D2AB38723802.

Expert command (m for help): r

# 最后输入w保存分区记录到磁盘
Command (m for help): w

The partition table has been altered.
Syncing disks.


# 刷新
root@OpenWrt:~# resize2fs -f /dev/nvme0n1p2
resize2fs 1.46.5 (30-Dec-2021)
The filesystem is already 488345809 (4k) blocks long.  Nothing to do!

# 重启
reboot
  • squashfs固件

PVE安装

新建虚拟机,记住VM ID,这里以101为例;操作系统选择不使用任何介质;硬盘默认,稍后需要手动删除的;CPU、内存、网络自行配置。然后将编译好的OpenWrt固件解压(gunzip -d bin/targets/x86/64/openwrt-x86-64-generic-squashfs-combined-efi.img.gz),并把解压后的img文件通过PVE网页上传功能上传到PVE。然后登陆PVE执行以下命令

# 转换成 PVE 磁盘格式,注意其中的101替换为你的VM ID,openwrt-x86-64-generic-squashfs-combined-efi.img为你的镜像文件
qm  importdisk 101 /var/lib/vz/template/iso/openwrt-x86-64-generic-squashfs-combined-efi.img local-lvm

转换完,在虚拟机硬件界面应该会多出一个未使用磁盘。将创建虚拟机时分配的磁盘分离删除,选择转换的OpenWrt磁盘点击编辑添加,并在选项菜单选择启动项为添加的硬盘。

主机安装

主机的话需要准备一个U盘的PE工具(PE推荐优启通(EasyU,简称EU)EasyU)和phydiskwrite,并把你要写入的固件镜像文件与phydiskwrite存放到U盘里。然后通过PE的命令行到的目录执行下面命令,其中-u后面为你的固件镜像名称。回车后会出现让你选择磁盘界面,你可以根据你的硬盘大小来区分你要写入的磁盘。

phydiskwrite.exe -u openwrt-x86-64-generic-squashfs-combined-efi.img

3. 常见问题

  • 报错bash: line 1: po2lmo: command not found make package/feeds/luci/luci-base/compile V=99
  • 报错issues: ERROR: package/kernel/button-hotplug failed to build. sudo apt-get install libelf-dev
  • 报错如下: Finding targets go: ../../go.mod requires go >= 1.23 (running go 1.21.13; GOTOOLCHAIN=local)

Building targets go: ../../go.mod requires go >= 1.23 (running go 1.21.13; GOTOOLCHAIN=local)

rm -rf feeds/packages/lang/golang
git clone https://github.com/sbwml/packages_lang_golang -b 23.x feeds/packages/lang/golang

结束

PS:

openclash常用信息:

  • 项目地址:OpenClash
  • 官方文档:wiki
  • Clash内核:Clash
  • TUN模式内核:clash_tun
  • TUN游戏模式内核:clash_game (移除游戏内核和模式,TUN内核功能更全)
  • 历史版本下载:下载 注意Clash最好用amd-v3版本的,amd-v4针对的老型号CPU