阅读视图

发现新文章,点击刷新页面。
🔲 ☆

Proxmox VE 部署 OpenWrt 实现旁路由图文说明教程

Proxmox VE 部署 OpenWrt 实现旁路由图文说明教程

系列文章:家庭服务器

前几天打算把家里小主机的服务升级一下!因为更新过程中需要访问Github等海外线上服务。但是!你懂的,经常莫名其妙无法访问!升级中断后导致源码出现了问题!

虽然博主之前分享过很多解决方案:GitHub国内加速,但在Linux上使用还是不太方便!

于是周末折腾了一下利用 Proxmox 安装OpenWrt,然后OpenWrt旁路由为其他内网服务器加速!

更多内容:家庭IDC / Proxmox

 

 

OpenWrt选择

  •  Lean 的 OpenWrt 源码(Lienol)

该源码库在 OpenWrt 社区影响力巨大,但其主仓库地址可能会根据开发者策略和平台变化而调整。

项目定位: 这是一个用于自行编译的 OpenWrt 源码,其中包含了大量的中文用户常用插件。

主流仓库地址:

GitHub: 您可以在 GitHub 上搜索 Lean openwrt 或 openwrt-lede 来找到目前活跃的仓库。由于原作者的仓库有时会关闭或变动,建议寻找社区中维护活跃且 Star 数量高的 Fork 或镜像仓库。

 

  • ImmortalWrt(不朽固件)

这是 OpenWrt 在国内社区的一个重要分支项目,旨在更好地服务中国用户,提供更多的本地化功能和硬件支持。

GitHub 源码地址:https://github.com/immortalwrt/immortalwrt

说明: 这是 ImmortalWrt 项目的官方源码仓库,可用于自行编译。

官方固件下载地址:https://downloads.immortalwrt.org/

说明: 这里提供了 ImmortalWrt 的稳定版(如 24.10.4 系列)和开发版快照。

 

  • KoolShare 固件

KoolShare 曾经是国内最知名的路由器固件社区之一,其固件以集成“软件中心”方便安装插件而闻名。

项目定位: 曾经主要以论坛和官方网站发布,现在固件下载和讨论主要集中在相关社区和论坛。

寻找方式: 由于版权和网络环境变化,KoolShare 官方网站的固件下载渠道现在非常不稳定。建议您在路由器相关的技术论坛或贴吧(如恩山无线论坛)中搜索关键词 “KoolShare OpenWrt” 或 “KoolClash”,通常会有热心网友分享针对特定机型的编译版本或下载链接。

 

博主使用了一个23年收藏的一个版本,由于作者不允许共享,这里就不多说明了!虽然这么多版本,但是操作上差不了太多!

 

部署过程

 

创建虚拟机

1,Proxmox 新建虚拟机,名称随意,注意 VM ID(后面会用到)

点击【高级】,选中 【开机自启动】(要不然选择这个做旁路由的主机可能无法上网~)

 

2,操作系统,选择【不使用任何介质】

因为OpenWrt不用ISO镜像安装,直接格式化成硬盘文件即可!

 

 

3,磁盘保持默认设置即可(因为后面会删除掉,不用担心浪费空间

CPU设置,按照自己的情况选择!如果只做旁路由2核 + 1G内存就足够了!

CPU权重,建议该值要比其他虚拟机高一些,数值越大优先级越高!

 

4,网络如图默认即可,然后提交保存即可

 

5,提交成功后,然后进行下一步

 

 

6,硬件 - 硬盘(scsi0) - 分离

7,移除【CD/DVD启动器】和 【硬盘(scsi0)】

 

上传镜像文件

访问 【local(pve)】 - 【ISO镜像】 - 上传 (选择童鞋下载的OpenWrt镜像文件)

镜像文件名称需要留意下,后面会用到!

 

导入镜像文件

点击 【pve】 - 【Shell】准备执行命令

 

 

以下命令得注意几个参数:

102  为 VM ID

xxxxxx.img 为上传的ISO镜像文件名称

替换下面的内容然后执行

qm importdisk 102 /var/lib/vz/template/iso/xxxxxx.img local-lvm

 

 

 

 

挂载硬盘

虚拟机控制台 - 硬件 - 未使用的磁盘 - 编辑

总线/设备  修改为 SATA

 

 

添加开机引导

按图将硬盘添加到引导启动中

 

 

配置OpenWRT

1,启动虚拟机后,可见控制台显示已经启动,但是IP没有

 

2,控制台输入 vi /etc/config/network 修改 lan 节点的 IP为童鞋要设置的

这里涉及到一些Linux命令行操作,不做太详细说明!

  • vi /etc/config/network
  • 按 i  (进去编辑模式)
  • 修改 IP 地址
  • 按 ESC 退出编辑模式
  • 输入 :wq 保存
  • 输入 reboot 重启主机

 

重启成功后,浏览器访问:http://你的IP

 

简单旁路由

这里说说最简单的一种旁路由形式,不同的OpenWrt版本,设置可能不太一致!

目前我家里的内网相对简单!所有设备都在同一个路由器下!网关:192.168.31.1

OpenWrt 设置IP 为 192.168.31.199

当然OpenWrt需要跑一套科学服务,毕竟咱们是要解决访问Github等问题。这部分内容这里不做详细说明!

内网的主机,手机,平板等咋走旁路由呢?

仅需将这些设备网络的网关从 192.168.31.1 改成 192.168.31.199 即可!

这样就解决我们的问题了!这样也是最简单的!其实大部分童鞋家里的网络没有那么复杂!

追求完美的童鞋说,我不想手动改网关?要无缝切换?如何这样的话网络可能略复杂了,本文暂不做说明了。

 

最后说明

1,OpenWrt的各种功能非常强大,旁路由只是其中的小部分功能

2,还有网络多播,AdGuard,DDNS,FRP 等等好玩实用的功能,有兴趣的童鞋搜索玩玩

3,还支持Docker部署服务,可自己部署签到脚本,挂机脚本等等

4,自己想玩玩?但没有小主机?没有能刷固件的路由器?其实自己的电脑安装一套虚拟机就能体验了

5,本文仅作个人纪录分享,请 '键盘侠' 免喷,劳驾绕行

6,有志同道合的童鞋,右上角可加入群组

 

 

 

 

 

 

 

🔲 ☆

mDNS:Homelab 网络的良药

在 Homelab 中折腾了一段时间后,我发现自己陷入了一个困境:随着设备数量的增加,管理 IP 地址变得越来越痛苦。

典型的场景是这样的:
– SSH 到某台服务器:ssh user@192.168.1.101,等等,101 是哪台机器来着?
– 访问某个服务:`http://192.168.2.88:8080`,这个 88 又是什么?
– 更糟糕的是,DHCP 租约过期后 IP 变了,所有的配置都要改一遍

我尝试过给每台设备绑定静态 IP,但这种方案有几个问题:

  1. IP 地址难以记住:20+ 台设备,每个都要记住对应的 IP
  2. 静态绑定不优雅:在路由器上一个个配置 DHCP 静态绑定很繁琐
  3. 缺乏灵活性:设备迁移到其他网络时需要重新配置

后来我发现了 mDNS(多播域名系统),它完美地解决了这些问题。配置完成后,我可以直接使用 server3.localpfsense.local 这样的域名来访问设备,再也不用记 IP 地址了。

这篇文章记录了我在 OpenWrt + pfSense 双层路由环境下配置 mDNS 的完整过程,包括踩过的坑和解决方案。

我的网络环境

我的网络是两层路由结构:
一级路由:OpenWrt,家庭主路由器,网段 192.168.1.0/24
二级路由:pfSense,虚拟机网络路由器,网段 192.168.2.0/24

这样设置的目的是将虚拟机网络与主网络解耦,让 VM 可以独立运行并组成一个独立的集群。但这也带来了跨网段访问的问题,mDNS 的 reflector 功能正好可以解决这个问题。

路由配置篇

我的一级路由用的是 OpenWrt,二级路由用的是 pfSense。虽然系统不同,但配置思路是类似的。

核心组件是 Avahi,一个开源的 mDNS/DNS-SD 实现。OpenWrt 和 pfSense 都可以直接安装。

OpenWrt 安装配置

安装 Avahi

opkg update
opkg install avahi-daemon-service-ssh avahi-daemon-service-http

修改配置文件

编辑 /etc/avahi/avahi-daemon.conf

[server]
use-ipv4=yes
use-ipv6=yes
check-response-ttl=no
use-iff-running=no
allow-interfaces=br-lan   # 指定监听的网络接口

[publish]
publish-addresses=yes
publish-hinfo=yes
publish-workstation=no
publish-domain=yes

[reflector]
enable-reflector=yes      # 关键:启用 reflector 功能,用于跨网段转发
reflect-ipv=no

[rlimits]
rlimit-core=0
rlimit-data=4194304
rlimit-fsize=0
rlimit-nofile=30
rlimit-stack=4194304
rlimit-nproc=3

关键配置说明
allow-interfaces=br-lan:指定 Avahi 监听的网络接口
enable-reflector=yes:启用 reflector 功能,这是实现跨网段 mDNS 的核心

参考:

  • https://openwrt.org/docs/guide-developer/mdns
  • https://openwrt.org/docs/guide-user/network/zeroconfig/zeroconf

pfSense 安装配置

安装插件

在 pfSense 的 Package Manager 中搜索并安装 avahi 插件。

关键问题:WAN 接口配置

这里我踩了个坑。pfSense 默认不允许在 WAN 接口启用 mDNS,这是出于安全考虑(如果 WAN 是公网,确实不应该暴露 mDNS)。

但在我的两层路由场景下,二级路由的 WAN 接口连接的是一级路由的 LAN,需要在 WAN 接口启用 mDNS 才能实现跨网段通信。

解决方法:修改插件源码

编辑 /usr/local/www/avahi_settings.php,找到并注释掉 WAN 过滤代码:

// vi /usr/local/www/avahi_settings.php
// 找到两处 wan 的过滤代码,注释掉:
// unset($available_interfaces['wan']);

修改后,在 Web 控制台就可以看到 WAN 选项了,同时选中 WAN 和 LAN 启用。

生成的配置文件

修改后 pfSense 会自动生成配置文件(位于 /usr/local/etc/avahi/avahi-daemon.conf):

这里需要注意:不推荐直接手动修改这个配置文件,因为它会被 GUI 覆盖。建议通过修改 PHP 源码让 GUI 支持 WAN 配置。

参考配置内容

# /usr/local/etc/avahi/avahi-daemon.conf
[server]
allow-interfaces=em0,em1    # WAN 和 LAN 接口
use-ipv4=yes
use-ipv6=no

[publish]
publish-addresses=yes
publish-domain=yes

[reflector]
enable-reflector=yes        # 启用跨网段转发

可选:启用 D-Bus

某些情况下可能需要启用 D-Bus:

mkdir -p /var/run/dbus/
dbus-daemon --system

至此 pfSense 的配置就完成了。

防火墙配置

重要:mDNS 使用 UDP 5353 端口,需要在防火墙中开放此端口。

确保允许以下流量:
– 源:LAN 主机
– 目标:路由器本机(224.0.0.251,mDNS 组播地址)
– 端口:UDP 5353

具体配置方法因路由器而异,在 OpenWrt 或 pfSense 的防火墙规则中添加即可。

主机配置

路由器配置完成后,还需要配置各个主机才能使用 mDNS。我这里以 Ubuntu Server 为例。

设置 Hostname

首先给主机设置一个有意义的 hostname:

sudo hostnamectl set-hostname server3

之后就可以通过 server3.local 访问这台主机了。

配置网络为 DHCP

mDNS 的一大优势是不需要静态 IP,所以把网络配置改为 DHCP:

# 编辑 netplan 配置
vim /etc/netplan/00-installer-config.yaml
network:
  ethernets:
    ens34:
      dhcp4: true
  version: 2
# 应用配置
netplan apply

启用 systemd-resolved 的 mDNS 功能

Ubuntu 新版本使用 systemd-resolved 管理 DNS,需要在这里启用 mDNS:

# 编辑配置文件
vim /etc/systemd/resolved.conf
[Resolve]
MulticastDNS=yes
LLMNR=yes

或者用命令一键修改:

sed -i "s|#MulticastDNS=no|MulticastDNS=yes|g" /etc/systemd/resolved.conf
sed -i "s|#LLMNR=no|LLMNR=yes|g" /etc/systemd/resolved.conf
systemctl restart systemd-resolved

踩坑:Netplan 不支持 mDNS 配置

这里有个大坑。即使修改了 resolved.conf,mDNS 在网络接口上仍然是关闭的:

# 检查接口的 mDNS 状态
resolvectl mdns ens34
# 输出:Link 2 (ens34): no

# 手动启用
resolvectl mdns ens34 yes

但这个设置重启后会失效,因为 Netplan 不支持 mDNS 配置(相关 Bug,2019 年提出至今未修复)。

Netplan 会在 /run 目录下生成配置文件,优先级高于 /etc,导致手动修改无效。

解决方案:创建 systemd 服务

既然是开机自启动的问题,那就用 systemd 来解决:

创建 systemd 服务文件:

cat << EOF > /etc/systemd/system/user-set-mdns@.service
[Unit]
Description=Enable MulticastDNS on network interface
After=systemd-resolved.service

[Service]
ExecStart=resolvectl mdns %i yes

[Install]
WantedBy=multi-user.target
EOF

启用服务(替换 ens34 为你的网卡名称):

sudo systemctl enable user-set-mdns@ens34
sudo systemctl start user-set-mdns@ens34
sudo systemctl status user-set-mdns@ens34

至此,主机的 mDNS 配置就完成了,重启后也会自动生效。

方案二:使用 Avahi(适用于老系统)

如果你的系统没有使用 systemd-resolved(比如老版本的 Ubuntu 或 Debian),可以直接安装 Avahi:

sudo apt-get install avahi-daemon libnss-mdns libnss-mymachines

安装后 Avahi 会自动启动,无需额外配置。

验收测试

配置完成后,让我们测试一下效果。

基本测试

现在可以抛弃 IP 地址,直接使用 .local 域名访问设备:

ping server3.local
ping code-env.local
ping vm-proxy.local
ping pfsense.local
ping openwrt.local

实际使用场景

SSH 连接

# 以前
ssh user@192.168.2.101

# 现在
ssh user@server3.local

访问 Web 服务

# 以前
http://192.168.2.88:8080

# 现在
http://vm-proxy.local:8080

容器配置

# docker-compose.yml
services:
  app:
    environment:
      - DATABASE_URL=postgresql://postgres@db-server.local:5432/mydb

跨网段测试

最重要的是测试跨网段访问,确认 reflector 功能正常工作:

# 从一级网络(192.168.1.x)访问二级网络设备
ping vm-server.local  # 这台设备在 192.168.2.x 网段

# 从二级网络访问一级网络设备
ping openwrt.local    # 这台设备在 192.168.1.x 网段

如果能 ping 通,说明 mDNS reflector 配置成功!

补充说明

二级路由的 IP 配置注意事项

后续重新部署时发现一个问题:如果 pfSense 二级路由使用静态 IP,会导致一级路由无法获取二级的 mDNS 记录。

解决方法
– 在一级路由(OpenWrt)上通过 DHCP 静态绑定给二级路由分配 IP
– 不要在二级路由上直接配置静态 IP
– 配置好后重启二级路由

OpenWrt 防火墙规则(命令行方式)

如果你习惯用命令行配置 OpenWrt 防火墙,可以使用以下命令:

uci -q delete firewall.mdns
uci set firewall.mdns="rule"
uci set firewall.mdns.name="Allow-mDNS"
uci set firewall.mdns.src="*"
uci set firewall.mdns.src_port="5353"
uci set firewall.mdns.dest_ip="224.0.0.251"
uci set firewall.mdns.dest_port="5353"
uci set firewall.mdns.proto="udp"
uci set firewall.mdns.target="ACCEPT"
uci commit firewall
/etc/init.d/firewall restart

配置完 mDNS 已经几个月了,现在回想起来,这是我在 Homelab 中做的最有价值的优化之一。

带来的改变

管理效率提升
– 不再需要维护一个 IP 地址清单
– 设备迁移或重启后不用担心 IP 变化
– 写配置文件时直接用域名,可读性大大提升

实际案例

最近我重装了一台服务器,以前的流程是:
1. 安装系统
2. 登录路由器配置静态 IP 绑定
3. 更新所有相关配置文件中的 IP
4. 重启依赖这台服务器的其他服务

现在的流程:
1. 安装系统
2. 设置 hostname
3. 完事

其他服务根本不需要改配置,因为它们用的是 server3.local 这样的域名,自动就能找到新的 IP。

一些建议

命名规范很重要

建议给设备起一个有意义的 hostname:
nas.local 而不是 server1.local
pve-node1.local 而不是 vm1.local
k8s-master.local 而不是 ubuntu-001.local

好的命名可以让你半年后还记得这台设备是干什么的。

文档还是要有的

虽然不用记 IP 了,但建议维护一个简单的设备清单:
– 设备名称和 hostname
– 主要用途和运行的服务
– 重要配置文件位置

安全性考虑

mDNS 只适合内网使用,不要在公网暴露:
– 路由器 WAN 口不要启用 mDNS
– 如果有公网 IP,确保防火墙规则正确
– mDNS 流量不应该离开你的局域网

总结

mDNS 确实是 Homelab 的良药。它解决了 IP 地址管理的痛点,让网络配置更加灵活和优雅。虽然配置过程有一些坑(特别是 Netplan 的问题),但一旦配置好,体验提升是显著的。

如果你也在运营 Homelab,强烈建议试试 mDNS。配置时间不会超过一个下午,但带来的便利是长期的。

希望这篇文章能够帮助你顺利配置 mDNS,少走一些弯路。

参考链接

🔲 ☆

OpenWrt如何启用DoH?让软路由下的设备使用 DNS over HTTPS

这篇文章介绍了在istoreos软路由中实现DoH(DNS over HTTPS)的步骤。由于系统仅支持IP形式的DNS,需通过安装https-dns-proxy及相关luci界面包实现。完成后可在网页“HTTPS DNS代理”中删除默认实例,新增如阿里和腾讯的服务提供商,并分别设置不同端口。引导DNS仅用于解析DoH地址,实际配置可在/etc/config/https-dns-proxy查看。文章提醒是否开启强制路由器DNS要根据实际需求决定,一般建议关闭。同时说明无需修改WAN、LAN DNS,因设备最终解析均通过DoH完成,从而实现加密安全的DNS服务。

🔲 ⭐

Cudy TR3000 吃鹅(daed)记

缘起

前不久在京东自营看到我馋了很久的 Cudy TR3000 有 ¥153 的折扣价,虽然比起 ¥130 的史低价(甚至 ¥110 的凑单史低价)还有些距离,但已经到我的可接受范围内了,于是果断下单剁手了这台我心心念念的 Cudy TR3000 迷你路由器,以此来缓解我的开学前综合症(一种精神性疾病)

这台路由器使用 Type-C 供电,拥有一个 2.5Gbps 的 WAN 口和一个 1Gbps 的 LAN 口,在此基础上还有一个 USB 口可用于打印机共享、挂载外接存储、安卓手机 USB 共享网络等多种用途。更让我心动的地方在于其小巧的体型,非常适合出差、旅行、短期租房等场景。考虑到接下来一段实习可能会有租房需求,于是便趁此机会果断下单了。

与一台小米8的宽高对比

官方系统是基于 openwrt 定制的,功能比较单一,因此考虑刷入 openwrt 原版系统增加可玩性。在恩山无限论坛上发现已经有人编译了基于 Linux 6.6 版本的 OpenWRT 系统,这已经满足了 dae 的 Bind to LAN 功能的内核版本要求( >= 5.17 ),且 512MB 的内存大小刚好达到了推荐的最小内存大小,于是这 dae 肯定是要试着吃一吃的。如果成功了,这就是我手上第一台吃上大鹅的硬路由。


开始刷机

路由器官方系统的后台管理地址是 192.168.10.1,初次进入会要求你设置密码,然后就是一路随便点,完成初始化,随后就进入到主页。我手上这台的 FW 版本号是 2.3.2-20241226,不清楚后续的版本能不能仍然使用这套方案。

过渡固件

首先我们需要先刷入所谓的「过渡固件」。刷入过渡固件的意义在于,这个过渡固件能被官方系统的升级程序所承认,这样就允许我们进行后续的操作。

过渡固件的文件名和 md5 值如下:

b8333d8eebd067fcb43bec855ac22364  cudy_tr3000-v1-sysupgrade.bin

随后我们可以在路由器的管理页面的基本设置中找到固件升级的地方,在本地更新一栏中选择过渡固件上传更新即可。

刷入解锁 FIP 分区写入权限的固件

刷入过渡固件后稍等大约一分钟,路由器的 DHCP 重新工作,我们就可以通过 192.168.1.1 进入过渡固件的管理页面。

初次登陆时没有密码,随便输就能登陆成功。考虑到后续可能会有恢复出厂的需求,建议在这一步对 FIP 分区进行备份。

这次我们需要刷入下面这个 LEDE 固件来解锁 FIP 分区的写入权限,文件名和 md5 仍然放在下面

4af5129368cbf0d556061f682b1614f2  openwrt-mediatek-filogic-cudy_tr3000-v1-squashfs-sysupgrade.bin

在下方选择刷入固件,上传我们本次需要刷入的固件,刷入。

刷入 uboot

再等待一分钟左右,电脑重新连接上路由器后,我们可以进入到这个解锁了 FIP 分区写入权限的固件,默认密码是 password

在侧栏选择文件传输,将本次要刷入的 uboot 上传,文件名和 md5 还是放在下面。注意 zip 包要解压

e5ff31bac07108b6ac6cd63189b4d113  dhcp-mt7981_cudy_tr3000-fip-fixed-parts-multi-layout.bin

随后侧栏进入 TTYD 终端,输入默认的用户名密码 root / password,执行命令刷入 uboot

mtd write /tmp/upload/dhcp-mt7981_cudy_tr3000-fip-fixed-parts-multi-layout.bin FIP

刷入自编译的 immortalwrt

刷入 uboot 以后,给路由器断电,确保网线分别连接电脑和路由器 LAN 口后,按住 reset 键再插入电源键,直至白灯闪烁四次后转为红灯后松开 reset 键,即可进入 uboot。

我编译的是 112m 的布局,因此需要选择 mod-112m 这个 mtd 布局后上传固件刷入。

8c9a44f29c8c5a0617e61d49bf8ad45d  112m-immortalwrt-cudy_tr3000-ebpf_by_zhullyb_20250325-squashfs-sysupgrade.bin

再次等待电脑重新连接路由器,这是最终吃上 daed 的系统了,依然是没有默认密码,随便输入即可进入。在连接上网络后,在系统 - 软件包页面,更新软件包列表。

随后就可以安装 dae / daed 相关软件了,可视需求选择 luci-i18n-dae-zh-cn 或者 luci-i18n-daed-zh-cn,其他包会作为依赖一同被安装。我这里安装的是 daed。

安装后刷新界面,我们就可以在顶栏的服务板块看到 daed。

daed 正常运行,能正常跑满我家的 300Mbps 宽带下行(单线程实测 250Mbps),速度峰值时 CPU 占用图如下。

多线程测速

单线程测速

文章中提到的文件

https://www.123684.com/s/gfprVv-wEQ8d

https://www.123912.com/s/gfprVv-wEQ8d

参见

🔲 ☆

从零开始!在红米AX6000路由器上刷入Openwrt

在我前两天搞定TPLINK后,近期跟我聊到路由器的同学买了个红米的AX6000,想自己刷,发现自己搞不定了求助于我,于是我们一起刷这台路由器,就有了这篇教程

准备工作

首先得把小米路由器的系统降级,这位同学拿过来的时候,他降级到了1.0.60,所以降级过程就没有什么教程啦,可以去网上找找旧版的包,然后直接通过路由器管理面板的升级部分刷就行了

打开Telnet(路由器的开发者模式)

我们降级好路由器后,先要打开telnet,才能打开SSH,打开telnet的过程不要联网!!!

实测联网会打不开telnet

首先我们要登录进路由器的管理面板,在管理面板的地址栏中有我们需要的stok,例如http://192.168.31.1/cgi-bin/luci/;stok=71871cc803318e6f85e9c73d2ed7736c,这个stok=后面的内容就是我们需要的stok,我们复制下来,替换掉下面链接中的{stok},并复制到浏览器访问(访问的结果统一会显示{code: 0},四次访问都是,不再赘述,我使用的是curl)

http://192.168.31.1/cgi-bin/luci/;stok={stok}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20zz%3D%24%28dd%20if%3D%2Fdev%2Fzero%20bs%3D1%20count%3D2%202%3E%2Fdev%2Fnull%29%20%3B%20printf%20%27%A5%5A%25c%25c%27%20%24zz%20%24zz%20%7C%20mtd%20write%20-%20crash%20%3B%20

http://192.168.31.1/cgi-bin/luci/;stok={stok}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20

访问了以后路由器会重启,重启完了以后,我们再登录到路由器管理面板,此时stok会改变,我们复制新的stok,替换下面链接中的{stok},然后丢到浏览器访问

http://192.168.31.1/cgi-bin/luci/;stok={stok}/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20set%20telnet_en%3D1%20%3B%20bdata%20set%20ssh_en%3D1%20%3B%20bdata%20set%20uart_en%3D1%20%3B%20bdata%20commit%20%3B%20

此链接跟第二条一样,都是重启用的

http://192.168.31.1/cgi-bin/luci/;stok={stok}/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20

我们打开一个能够支持telnet连接的软件,用户名和密码都是空,就可以连接进去了

自动化脚本

于是我随手撸了一个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import httpx

host = "http://192.168.31.1"

# First time
stok = input("请输入第一次的stok: ")

BASE = host + "/cgi-bin/luci/;stok="

MTD_WRITE_ROUTE = "/api/misystem/set_sys_time?timezone=%20%27%20%3B%20zz%3D%24%28dd%20if%3D%2Fdev%2Fzero%20bs%3D1%20count%3D2%202%3E%2Fdev%2Fnull%29%20%3B%20printf%20%27%A5%5A%25c%25c%27%20%24zz%20%24zz%20%7C%20mtd%20write%20-%20crash%20%3B%20"
REBOOT_ROUTE = "/api/misystem/set_sys_time?timezone=%20%27%20%3b%20reboot%20%3b%20"
ENABLE_TALNET_ROUTE = "/api/misystem/set_sys_time?timezone=%20%27%20%3B%20bdata%20set%20telnet_en%3D1%20%3B%20bdata%20set%20ssh_en%3D1%20%3B%20bdata%20set%20uart_en%3D1%20%3B%20bdata%20commit%20%3B%20"

response = httpx.get(BASE + stok + MTD_WRITE_ROUTE)
print(response.json())
response = httpx.get(BASE + stok + REBOOT_ROUTE)
print(response.json())

# Second time
stok = input("请输入第二次的stok: ")
response = httpx.get(BASE + stok + ENABLE_TALNET_ROUTE)
print(response.json())
response = httpx.get(BASE + stok + REBOOT_ROUTE)
print(response.json())

打开SSH

打开任意telnet客户端通过telnet连接后,我们需要打开SSH

设置root密码

通过下面的命令可以设置root的密码为admin

1
$ echo -e 'admin\nadmin' | passwd root

其实就是运行passwd root,然后输入了两次admin而已,你也可以自己改

打开SSH

接着我们运行下面的命令打开SSH

1
2
3
4
5
6
7
8
9
bdata set boot_wait=on
bdata commit
nvram set ssh_en=1
nvram set telnet_en=1
nvram set uart_en=1
nvram set boot_wait=on
nvram commit
sed -i 's/channel=.*/channel="debug"/g' /etc/init.d/dropbear
/etc/init.d/dropbear restart

输入后是不会有任何输出的,此时SSH就已经打开了

设置SSH开机自动启动

接着我们要设置开机开启SSH,要不然重启一下就没了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
mkdir -p /data/auto_ssh && cd /data/auto_ssh

cat <<EOF > auto_ssh.sh
#!/bin/sh

auto_ssh_dir="/data/auto_ssh"
host_key="/etc/dropbear/dropbear_rsa_host_key"
host_key_bk="${auto_ssh_dir}/dropbear_rsa_host_key"

unlock() {
# Restore the host key.
[ -f \$host_key_bk ] && ln -sf \$host_key_bk \$host_key

# Enable telnet, ssh, uart and boot_wait.
[ "\$(nvram get telnet_en)" = 0 ] && nvram set telnet_en=1 && nvram commit
[ "\$(nvram get ssh_en)" = 0 ] && nvram set ssh_en=1 && nvram commit
[ "\$(nvram get uart_en)" = 0 ] && nvram set uart_en=1 && nvram commit
[ "\$(nvram get boot_wait)" = "off" ] && nvram set boot_wait=on && nvram commit

[ "\$(uci -c /usr/share/xiaoqiang get xiaoqiang_version.version.CHANNEL)" != 'stable' ] && {
uci -c /usr/share/xiaoqiang set xiaoqiang_version.version.CHANNEL='stable'
uci -c /usr/share/xiaoqiang commit xiaoqiang_version.version 2>/dev/null
}

channel=\$(/sbin/uci get /usr/share/xiaoqiang/xiaoqiang_version.version.CHANNEL)
if [ "\$channel" = "release" ]; then
sed -i 's/channel=.*/channel="debug"/g' /etc/init.d/dropbear
fi

if [ -z "\$(pidof dropbear)" -o -z "\$(netstat -ntul | grep :22)" ]; then
/etc/init.d/dropbear restart 2>/dev/null
/etc/init.d/dropbear enable
fi
}

install() {
# unlock SSH.
unlock

# host key is empty, restart dropbear to generate the host key.
[ -s \$host_key ] || /etc/init.d/dropbear restart 2>/dev/null

# Backup the host key.
if [ ! -s \$host_key_bk ]; then
i=0
while [ \$i -le 30 ]
do
if [ -s \$host_key ]; then
cp -f \$host_key \$host_key_bk 2>/dev/null
break
fi
let i++
sleep 1s
done
fi

# Add script to system autostart
uci set firewall.auto_ssh=include
uci set firewall.auto_ssh.type='script'
uci set firewall.auto_ssh.path="\${auto_ssh_dir}/auto_ssh.sh"
uci set firewall.auto_ssh.enabled='1'
uci commit firewall
echo -e "\033[32m SSH unlock complete. \033[0m"
}

uninstall() {
# Remove scripts from system autostart
uci delete firewall.auto_ssh
uci commit firewall
echo -e "\033[33m SSH unlock has been removed. \033[0m"
}

main() {
[ -z "\$1" ] && unlock && return
case "\$1" in
install)
install
;;
uninstall)
uninstall
;;
*)
echo -e "\033[31m Unknown parameter: \$1 \033[0m"
return 1
;;
esac
}

main "\$@"
EOF

chmod +x auto_ssh.sh

# 设置自动启动
uci set firewall.auto_ssh=include
uci set firewall.auto_ssh.type='script'
uci set firewall.auto_ssh.path='/data/auto_ssh/auto_ssh.sh'
uci set firewall.auto_ssh.enabled='1'
uci commit firewall

这个文件你也可以放在别的位置,自己修改上面脚本里面的文件位置就行,不过要注意重启是否会消失,有些路由器重启会自动清除文件的(例如我前阵子弄的WAR308)

设置时区

最后一步是设置时区,使用下面的命令设置时区

1
2
3
4
uci set system.@system[0].timezone='CST-8'
uci set system.@system[0].webtimezone='CST-8'
uci set system.@system[0].timezoneindex='2.84'
uci commit

关闭开发者模式

使用下面的命令关闭开发者模式

1
mtd erase crash

最后是重启,直接打reboot就行了

通过SSH刷入uboot

当我们通过SSH连接进路由器后,我们需要保证路由器可以联网,然后运行下面的命令

1
$ cd /tmp && curl --silent -O https://fastly.jsdelivr.net/gh/miaoermua/unlock-redmi-ax6000@main/uboot.sh && chmod +x uboot.sh && ./uboot.sh

运行了以后,脚本会帮你备份你的分区文件,记得把它们弄出来,要不然没办法恢复原厂系统,分别是/tmp/mtd5_FIP.bin/tmp/mtd4_Factory.bin

拿出来以后,再运行下面的命令来刷入uboot,最后会弹出一行success,就说明完成了

1
2
3
mtd erase FIP
mtd write /tmp/mt7986_redmi_ax6000-fip-fixed-parts.bin FIP
mtd verify /tmp/mt7986_redmi_ax6000-fip-fixed-parts.bin FIP

进入uboot,刷入openwrt系统

进入uboot模式

先拔掉电源,然后用牙签/卡针之类的尖锐的东西,戳着reset键,然后插上电源等待15秒以上,就可以松开了,这个就可以用电脑访问uboot了

uboot模式下,路由器的灯不会亮

电脑访问uboot

在进入uboot之前,请先把自己的电脑的ip地址修改一下,因为uboot模式下没有DHCP

然后访问http://192.168.31.1进入uboot,界面应该是像下面这样的

我们尝试了下面的两个系统(因为我这个同学记错路由器的空间大小以为CatWrt的分区大小给小了于是刷了ImmortalWrt)

刷入系统

下载好你需要的系统包后,直接在uboot里面上传,上传后会读条,这个时候路由器在校验系统包和计算md5,直接点击update就可以了

第一次刷可能会出现下图这样的fail提示,我们返回重新上传刷一次就行了

刷好了访问系统包对应的ip地址就可以进入openwrt了

其他

进入openwrt后,发现这个机子的存储应该是256MB(图片是CatWrt的终端)

内存为512MB左右

END

怎么说呢,这次应该是我第一次真正去刷品牌路由器成功的,我以前刷过小米的AX3000T但是刷炸了;讲真,品牌路由器的内存和存储还是给得太小了

当然这次成功也离不开下面这些参考文档(注:里面有些链接是过期的,所以为什么我会综合起来写一篇文,就是避免其他人做到一半发现链接404不知道怎么做了)

ALL IN ALL,刷路由器还是很好玩的 :D

Ref:

https://docs.qq.com/doc/DS1RlUVhUYXp3YnhL

https://www.right.com.cn/forum/thread-8261104-1-1.html

https://blog.csdn.net/sxf1061700625/article/details/130328437

真正的END

因为我发现我们学校会BAN我的MAC地址,于是我顺带放出我写的MAC地址更换脚本(可以设置计划任务)

MAC备份还原脚本

避免你需要还原你路由器真正的mac的时候找不到mac,建议你用这个先备份一下你路由器的mac

如果你的网口不是eth0,请先更换一下网口!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/bin/sh

MAC_FILE="/root/mac"

# 获取当前MAC地址并保存到文件
save_mac() {
CURRENT_MAC=$(ip link show eth0 | grep ether | awk '{print $2}')
echo "当前的MAC地址是: $CURRENT_MAC"
echo "$CURRENT_MAC" > "$MAC_FILE"
echo "已保存当前MAC地址到 $MAC_FILE"
}

# 从文件中恢复MAC地址
restore_mac() {
if [ -f "$MAC_FILE" ]; then
SAVED_MAC=$(cat "$MAC_FILE")
echo "从文件恢复MAC地址: $SAVED_MAC"
ip link set dev eth0 down
ip link set dev eth0 address "$SAVED_MAC"
ip link set dev eth0 up
echo "已恢复MAC地址到eth0"
else
echo "MAC文件不存在,无法恢复MAC地址"
fi
}

# 检查参数并执行对应的操作
if [ "$1" = "save" ]; then
save_mac
elif [ "$1" = "restore" ]; then
restore_mac
else
echo "用法: $0 {save|restore}"
echo "save: 保存当前的MAC地址"
echo "restore: 恢复之前保存的MAC地址"
fi

Mac生成替换脚本

我这里设置了固定的前缀,是因为我路由器的MAC地址带了这三个,建议改成自己的

如果你的网口不是eth0,请先更换一下网口!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/sh

# 生成一个随机的MAC地址
generate_mac() {
PREFIX="c6:1f:d8"
# 使用 /dev/urandom 获取随机数
HEX1=$(hexdump -n 1 -e '1/1 "%02X"' /dev/urandom)
HEX2=$(hexdump -n 1 -e '1/1 "%02X"' /dev/urandom)
HEX3=$(hexdump -n 1 -e '1/1 "%02X"' /dev/urandom)
echo "$PREFIX:$HEX1:$HEX2:$HEX3"
}

# 获取新的MAC地址
NEW_MAC=$(generate_mac)
echo "生成的新MAC地址为: $NEW_MAC"

# 使用新的MAC地址修改eth0的MAC地址
ip link set dev eth0 down
ip link set dev eth0 address $NEW_MAC
ip link set dev eth0 up

# 验证修改是否成功
ip link show eth0 | grep ether

Openwrt备份备份恢复脚本

注意修改前两行

1
2
3
4
5
# 定义备份目录
BACKUP_DIR="/mnt/usb1-1"

# 定义 OpenWrt 系统路径
OPENWRT_MMC="/dev/mmcblk0"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
#!/bin/ash

# OpenWrt 备份与恢复管理脚本
# 支持命令行参数快速备份:--owrt-backup --config-backup --iptables-backup --firewall-backup --all-backup

# 定义备份目录
BACKUP_DIR="/mnt/usb1-1"

# 系统参数
OPENWRT_MMC="/dev/mmcblk0"
FIREWALL_CONFIG="/etc/config/firewall"

# 备份子目录
OPENWRT_BACKUP_DIR="$BACKUP_DIR/openwrt-backup"
OPENWRT_CONFIG_BACKUP_DIR="$BACKUP_DIR/openwrt-config-backup"
IPTABLES_BACKUP_DIR="$BACKUP_DIR/iptables-backup"
FIREWALL_BACKUP_DIR="$BACKUP_DIR/firewall-backup"

# 初始化目录
mkdir -p $OPENWRT_BACKUP_DIR $OPENWRT_CONFIG_BACKUP_DIR $IPTABLES_BACKUP_DIR $FIREWALL_BACKUP_DIR

# 获取当前日期
CURRENT_DATE=$(date +%Y%m%d)

# 定义颜色代码
RED='\033[31m'
GREEN='\033[32m'
YELLOW='\033[33m'
BLUE='\033[34m'
RESET='\033[0m'

#######################################
# 核心备份功能函数
#######################################

backup_full_image() {
echo -e "${BLUE}[1/4] 开始备份系统镜像...${RESET}"
local temp_bin="$OPENWRT_BACKUP_DIR/temp_${CURRENT_DATE}.bin"
local backup_file="$OPENWRT_BACKUP_DIR/openwrt-backup-${CURRENT_DATE}.tar.gz"

# 创建磁盘镜像
if ! dd if="$OPENWRT_MMC" of="$temp_bin" bs=1M; then
echo -e "${RED}错误:磁盘镜像创建失败!${RESET}"
return 1
fi

# 压缩备份
if tar -czf "$backup_file" -C "$OPENWRT_BACKUP_DIR" $(basename $temp_bin); then
md5sum $backup_file > ${backup_file}.md5
echo -e "${GREEN}系统镜像备份成功:${backup_file}${RESET}"
else
echo -e "${RED}错误:压缩备份失败!${RESET}"
fi
rm -f $temp_bin
}

restore_full_image() {
echo -e "${BLUE}[系统恢复] 请选择备份文件:${RESET}"
ls -lh $OPENWRT_BACKUP_DIR/openwrt-backup-*.tar.gz 2>/dev/null || { echo -e "${RED}未找到备份文件!${RESET}"; return; }

read -p "请输入要恢复的文件名: " backup_file
local full_path="$OPENWRT_BACKUP_DIR/$backup_file"

# 验证文件
[ ! -f "$full_path" ] && echo -e "${RED}文件不存在!${RESET}" && return
[ ! -f "${full_path}.md5" ] && echo -e "${YELLOW}警告:未找到MD5校验文件${RESET}" || (md5sum -c "${full_path}.md5" || { echo -e "${RED}MD5校验失败!${RESET}"; return; })

# 确认操作
read -p "确定要恢复系统镜像吗?此操作不可逆![y/N]: " confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && return

# 解压并恢复
echo -e "${BLUE}正在解压镜像文件...${RESET}"
local temp_bin="${full_path%.tar.gz}.bin"
tar -xzf "$full_path" -C "$OPENWRT_BACKUP_DIR" || { echo -e "${RED}解压失败!${RESET}"; return; }

echo -e "${BLUE}正在写入系统镜像...${RESET}"
if dd if="$temp_bin" of="$OPENWRT_MMC" bs=1M; then
echo -e "${GREEN}系统恢复成功,请重启设备!${RESET}"
else
echo -e "${RED}镜像写入失败!${RESET}"
fi
rm -f $temp_bin
}

backup_config() {
echo -e "${BLUE}[2/4] 备份系统配置...${RESET}"
local backup_file="$OPENWRT_CONFIG_BACKUP_DIR/openwrt-config-backup-${CURRENT_DATE}.bak"
if sysupgrade -b $backup_file; then
md5sum $backup_file > ${backup_file}.md5
echo -e "${GREEN}系统配置备份成功:${backup_file}${RESET}"
else
echo -e "${RED}错误:配置备份失败!${RESET}"
fi
}

restore_config() {
echo -e "${BLUE}[配置恢复] 请选择备份文件:${RESET}"
ls -lh $OPENWRT_CONFIG_BACKUP_DIR/openwrt-config-backup-*.bak 2>/dev/null || { echo -e "${RED}未找到备份文件!${RESET}"; return; }

read -p "请输入要恢复的文件名: " backup_file
local full_path="$OPENWRT_CONFIG_BACKUP_DIR/$backup_file"

# 验证文件
[ ! -f "$full_path" ] && echo -e "${RED}文件不存在!${RESET}" && return
[ ! -f "${full_path}.md5" ] && echo -e "${YELLOW}警告:未找到MD5校验文件${RESET}" || (md5sum -c "${full_path}.md5" || { echo -e "${RED}MD5校验失败!${RESET}"; return; })

# 确认操作
read -p "确定要恢复系统配置吗?[y/N]: " confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && return

# 创建临时备份
local current_backup="$OPENWRT_CONFIG_BACKUP_DIR/current_config_$(date +%H%M%S).bak"
sysupgrade -b $current_backup || { echo -e "${RED}当前配置备份失败,已中止恢复!${RESET}"; return; }

# 执行恢复
if sysupgrade -r $full_path; then
echo -e "${GREEN}配置恢复成功,正在重启网络服务...${RESET}"
/etc/init.d/network restart
else
echo -e "${RED}配置恢复失败!${RESET}"
fi
}

backup_iptables() {
echo -e "${BLUE}[3/4] 备份iptables规则...${RESET}"
local backup_file="$IPTABLES_BACKUP_DIR/iptables-backup-${CURRENT_DATE}.bak"
if iptables-save > $backup_file; then
md5sum $backup_file > ${backup_file}.md5
echo -e "${GREEN}iptables备份成功:${backup_file}${RESET}"
else
echo -e "${RED}错误:iptables备份失败!${RESET}"
fi
}

restore_iptables() {
echo -e "${BLUE}[iptables恢复] 请选择备份文件:${RESET}"
ls -lh $IPTABLES_BACKUP_DIR/iptables-backup-*.bak 2>/dev/null || { echo -e "${RED}未找到备份文件!${RESET}"; return; }

read -p "请输入要恢复的文件名: " backup_file
local full_path="$IPTABLES_BACKUP_DIR/$backup_file"

# 验证文件
[ ! -f "$full_path" ] && echo -e "${RED}文件不存在!${RESET}" && return
[ ! -f "${full_path}.md5" ] && echo -e "${YELLOW}警告:未找到MD5校验文件${RESET}" || (md5sum -c "${full_path}.md5" || { echo -e "${RED}MD5校验失败!${RESET}"; return; })

# 确认操作
read -p "确定要恢复iptables规则吗?[y/N]: " confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && return

if iptables-restore < $full_path; then
echo -e "${GREEN}iptables规则恢复成功!${RESET}"
else
echo -e "${RED}规则恢复失败,请检查文件格式!${RESET}"
fi
}

backup_firewall() {
echo -e "${BLUE}[4/4] 备份防火墙配置...${RESET}"
local backup_file="$FIREWALL_BACKUP_DIR/firewall-backup-${CURRENT_DATE}.bak"
if cp $FIREWALL_CONFIG $backup_file; then
md5sum $backup_file > ${backup_file}.md5
echo -e "${GREEN}防火墙配置备份成功:${backup_file}${RESET}"
else
echo -e "${RED}错误:防火墙配置备份失败!${RESET}"
fi
}

restore_firewall() {
echo -e "${BLUE}[防火墙恢复] 请选择备份文件:${RESET}"
ls -lh $FIREWALL_BACKUP_DIR/firewall-backup-*.bak 2>/dev/null || { echo -e "${RED}未找到备份文件!${RESET}"; return; }

read -p "请输入要恢复的文件名: " backup_file
local full_path="$FIREWALL_BACKUP_DIR/$backup_file"

# 验证文件
[ ! -f "$full_path" ] && echo -e "${RED}文件不存在!${RESET}" && return
[ ! -f "${full_path}.md5" ] && echo -e "${YELLOW}警告:未找到MD5校验文件${RESET}" || (md5sum -c "${full_path}.md5" || { echo -e "${RED}MD5校验失败!${RESET}"; return; })

# 确认操作
read -p "确定要恢复防火墙配置吗?[y/N]: " confirm
[[ "$confirm" != "y" && "$confirm" != "Y" ]] && return

# 备份当前配置
local current_backup="$FIREWALL_BACKUP_DIR/current_firewall_$(date +%H%M%S).bak"
cp $FIREWALL_CONFIG $current_backup || { echo -e "${RED}当前配置备份失败,已中止恢复!${RESET}"; return; }

if cp $full_path $FIREWALL_CONFIG; then
echo -e "${GREEN}防火墙配置恢复成功,正在重启服务...${RESET}"
/etc/init.d/firewall restart
else
echo -e "${RED}配置恢复失败!${RESET}"
fi
}

#######################################
# 命令行参数处理
#######################################

print_banner() {
echo -e "${YELLOW}"
echo " _ _ _ _ _"
echo " _____ ___ __| |_ _ _| |_(_) | ___| |__"
echo " / _ \ \ /\ / / '__| __|____| | | | __| | | / __| '_ \\"
echo "| (_) \ V V /| | | ||_____| |_| | |_| | |_\__ \ | | |"
echo " \___/ \_/\_/ |_| \__| \__,_|\__|_|_(_)___/_| |_|"
echo -e "${RESET}"
echo -e "${BLUE} —— OpenWrt备份工具 @GamerNoTitle${RESET}"
echo -e "${BLUE} https://bili33.top${RESET}\n"
}

if [ $# -gt 0 ]; then
print_banner
echo -e "${GREEN}检测到命令行参数,进入快速备份模式...${RESET}"

# 处理多个参数
for param in "$@"; do
case $param in
--owrt-backup) backup_full_image ;;
--config-backup) backup_config ;;
--iptables-backup) backup_iptables ;;
--firewall-backup) backup_firewall ;;
--all-backup)
backup_full_image
backup_config
backup_iptables
backup_firewall
;;
*) echo -e "${RED}错误:未知参数 $param${RESET}"; exit 1 ;;
esac
done
exit 0
fi

#######################################
# 交互式菜单系统
#######################################

show_menu() {
clear
print_banner
echo -e "${YELLOW}======================= owrt-util.sh ========================${RESET}"
echo -e "${YELLOW} OpenWrt 备份与恢复管理脚本 ${RESET}"
echo -e "${YELLOW} https://bili33.top ${RESET}"
echo -e "${YELLOW}=============================================================${RESET}"
echo "1. 完整系统备份 (磁盘镜像)"
echo "2. 系统配置备份"
echo "3. iptables规则备份"
echo "4. 防火墙配置备份"
echo "5. 一键全量备份"
echo -e "${YELLOW}-------------------------------------------------------------${RESET}"
echo "6. 恢复系统镜像"
echo "7. 恢复系统配置"
echo "8. 恢复iptables规则"
echo "9. 恢复防火墙配置"
echo -e "${YELLOW}-------------------------------------------------------------${RESET}"
echo "0. 退出"
echo -e "${YELLOW}=============================================================${RESET}"
echo -n "请输入选择: "
}


while true; do
show_menu
read choice
case $choice in
1) backup_full_image ;;
2) backup_config ;;
3) backup_iptables ;;
4) backup_firewall ;;
5)
backup_full_image
backup_config
backup_iptables
backup_firewall
;;
6) restore_full_image ;;
7) restore_config ;;
8) restore_iptables ;;
9) restore_firewall ;;
0) exit 0 ;;
*) echo -e "${RED}无效输入,请重新选择!${RESET}" ;;
esac
echo -e "\n${BLUE}按回车返回菜单...${RESET}"
read
done
🔲 ⭐

openwrt编译过程记录

前言

本文编译的为openwrt分支lede,本文主要以记录为主,因为中间有时候报错没弄,断断续续1个月左右搞好.

本文以ubuntu x86作为编译机.

编译成品: https://github.com/LanYunDev/lede_compile

安装依赖

1
2
3
4
5
6
7
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-pyelftools \
libpython3-dev qemu-utils rsync scons squashfs-tools subversion swig texinfo uglifyjs upx-ucl unzip \
vim wget xmlto xxd zlib1g-dev python3-setuptools zstd ninja-build meson

添加用户

如果你有非root用户,可跳过创建,后续都需要用非root用户进行操作.

1
2
3
4
5
6
7
8
9
10
# 添加用户
adduser openwrt
# 设定密码
passwd openwrt
# 添加 sudo 权限
usermod -a -G sudo openwrt
# 进入用户
su openwrt
# 切换目录
cd ~

编译

1
2
3
4
5
6
7
git clone https://github.com/coolsnowwolf/lede.git
cd lede
./scripts/feeds update -a
./scripts/feeds install -a
make menuconfig # 手动配下
make download -j8 || make download || make download V=s
make -j1 || make -j1 V=s

可选:

添加第三方包来源

1
2
3
4
echo >> feeds.conf.default
echo 'src-git istore https://github.com/linkease/istore;main' >> feeds.conf.default
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

更换golang版本

编译新版Sing-box和hysteria,需golang版本1.20或者以上版本.

若自带的版本过低,可用下面命令换成openwrt官方golang版本

1
2
3
pushd feeds/packages/lang
rm -rf golang && svn co https://github.com/openwrt/packages/branches/openwrt-23.05/lang/golang
popd

删除默认的 argon 主题

记得选.

choose LUCI->Theme->Luci-theme-argon

choose LUCI->Application->Luci-app-argon-config

1
2
3
4
5
6
cd ./package/lean
rm -rf luci-theme-argon
git clone -b 18.06 https://github.com/jerrykuku/luci-theme-argon.git luci-theme-argon
rm -rf luci-app-argon-config # if have
git clone -b 18.06 https://github.com/jerrykuku/luci-app-argon-config.git luci-app-argon-config
cd ../../

修改默认主题为argone

1
sed -i 's/luci-theme-bootstrap/luci-theme-argone/g' feeds/luci/collections/luci/Makefile

添加ddns-go

1
git clone https://github.com/sirpdboy/luci-app-ddns-go.git package/ddns-go

修改用户名

站内文章: OpenWrt 修改登陆用户名

二次编译

1
2
3
4
5
git pull
./scripts/feeds update -a
./scripts/feeds install -a
make -j1 || make -j1 V=s
# 不怕失败,可以用: make -j$(nproc) || make -j1 || make -j1 V=s

干净编译

编译出现问题且用make clean依然无法解决的情况.

1
2
3
4
5
6
7
8
# 也可以加上删除dl tmp staging_dir build_dir目录的操作
git pull
./scripts/feeds update -a
./scripts/feeds install -a
make dirclean;make dirclean V=s
make -j1 clean; make -j1 clean V=s
make download || make download V=s
make -j1 || make -j1 V=s

杂项

如果是ext4镜像,修改某些文件,提示:Read-only file system

用这个命令将根目录解锁即可.

1
mount -o remount,rw /

默认没有安装Git,自带的ssh没有ssh-agent功能,可以通过如下命令配置:

1
2
3
4
5
6
7
opkg update
# 安装Git
opkg remove git
opkg install git-http
opkg install ca-bundle
# 安装SSH
opkg install openssh-client openssh-keygen openssh-sftp-server

安装并信任根 CA 证书 参考

  1. 获取根 CA 证书 (若已有,可跳过,这里演示生成)
1
2
3
openssl s_client -connect ca.private-domain.tld:443 < /dev/null > /tmp/temporary.out
openssl x509 -outform PEM < /tmp/temporary.out > /tmp/ca.private-domain.tld.cert
rm /tmp/temporary.out
  1. 安装 CA 根证书

受信任的证书安装在/etc/ssl/certs,但是遵循FHS 3并用于/usr/local/share与体系结构无关的文件是一个很好的做法.

1
2
3
mkdir -p /usr/local/share/ca-certificates
mv /tmp/ca.private-domain.tld.cert /usr/local/share/ca-certificates/
ln -s /usr/local/share/ca-certificates/ca.private-domain.tld.cert /etc/ssl/certs/ca.private-domain.tld.cert
  1. 将根 CA 证书添加到系统的信任存储中

证书已安装,但尚未被信任.您需要提供证书的哈希值.

1
2
3
4
5
6
7
8
# 生成哈希值
HASH="$(openssl x509 -hash -noout -in /etc/ssl/certs/ca.private-domain.tld.cert).0"

# 显示哈希值
echo "$HASH"

# 将哈希值链接到证书
ln -s "/ect/ssl/certs/ca.private-domain.tld.cert" "/etc/ssl/certs/$HASH"

注意: 如果其他证书有相同的哈希值,请使用后缀.1.2,而不是.0.

解决配置文件无法保存问题:

临时:

1
mount -o remount rw /

永久:

1
vim /etc/rc.local

exit 0之前添加命令mount -o remount rw /然后保存,并赋权.

1
chmod +x /etc/rc.local

或者编译解决:

1
2
3
4
make menuconfig 中把 block-mount 去掉
# 按顺序取消选中
Extra packages ---> automount
Base system ---> block-mount

或者在luci中 系统 -> 挂载点 -> 挂载点 取消根目录 / 挂载点.

编译修改ssh端口:

1
2
vim ./package/network/services/dropbear/files/dropbear.config
# 将option Port '22'中22修改为想要的端口

修改内核大版本

1
vim ./target/linux/x86/Makefile # 这里以x86为例,其他平台自行参考

修改KERNEL_TESTING_PATCHVER即可.如果没有则修改KERNEL_PATCHVER

❌