这篇文章,聊聊前一阵折腾小米路由器 BE3600 Pro 的一些事情,包括初步分析整套软硬件,以及使用 Docker 快速运行 Alist 这类好用,但体积较大的容器应用。

写在前面

我是小米路由器的相对早期用户,线上线下买过很多台小米路由器,线上能够翻到的订单记录,最早的一台是 2015 年的小米 Mini 路由器。

小米路由器部分历史订单

随后,陆陆续续的买过许多款不同的小米路由器,其中有很多经典款:青春版、R3G、AC2100、AX1800、4A,最近一台是小米的 BE6500 Pro。目前,家里还在使用的小米路由器是 2023 年双十一前购入的 BE6500 Pro,搭配之前购入的米家中枢网关,专门提供各种智能家居设备进行联网和管理使用。

知乎来信!

3月初的时候,再次收到了“知乎来信”,这次能够不给厂商面子,随便折腾和吐槽的设备是我入手的 “BE6500 Pro 的青春版”:BE3600 Pro。

哦豁,“双子星”

相比较之前的路由器,尤其是同系列的 BE6500 Pro,这台路由器单个尺寸会看起来稍小一些(矮胖一些),整体造型比较致敬十年前的经典款 R1D(只是没有硬盘)。

家里的路由器们(小爱音箱乱入)

因为我家里已经有管理智能家居 IoT 设备的路由器(BE6500 Pro),所以在我拿到这台设备后的第一想法,并不是测试和折腾它的智能家居的功能,而是把想试试把它作为一个轻量服务器使用。

毕竟小米整套智能家居想更换网关,需要集体先解绑,再重新绑定,是一个巨大的工程(实在是太多体力活了)。这个经验是从之前的教训中得来的:家里原本用的小米 BE6500 Pro 经常出现断流问题,为了不影响正常上网体验,所以我不得不单独将小米路由器和本地网关重新组网,把所有智能家居设备都迁移到专用网络上,把智能家居和生活网络区分开来。希望后续米家的产品经理能够改进这个糟糕的体验,并且给想要帮助探索路由器问题的用户一个调试模式。

在这次折腾 BE3600 Pro 的时候,我在网上搜索了一圈,在一些视频博主的评论区中看到了一些类似 BE6500 Pro 的断流反馈,虽然购物平台基本上都会换货协助解决问题,但我觉得有限的折腾时间,应该花在刀刃上。

所以,当看着这款颜值在线、很像当年米家第一代带硬盘的R1D(路由轻NAS)的盒子组合时,我觉得用它来打造迷你服务器可能会很有趣:它原生支持Docker,性能不错又省电,特别是当它关掉作为路由器最耗性能的无线功能后,应该能发挥出更好的功耗表现。

准备工作

想要拿这个设备当轻量服务器使用,第一件事是获取设备的硬件信息和了解有哪些合适的 Linux 操作系统。

官方的路由器参数页

官方路由器的参数页里,没有体现使用的 SoC 的硬件参数。不过,还可以通过两个方式来获取信息:

  • 第一种是拆机,对照芯片丝印来确认硬件信息。
  • 第二种是使用网上公开的方法,敲开路由器软件的 SSH 服务的门,在路由设备它的操作系统中获取到想要的各种信息。

虽然我最后会拆掉这台设备,但是现在我选择第二种方法,主要因为需要对这台设备进行资料备份,以便出现极端情况下,能够有机会救活这套设备。并且,如果想要这台设备运行一些其他的系统,也需要更多的有效信息,而不仅仅是一个“芯片 ID 名称”。

强制设备初始化

两台路由器是有区别的

两台路由器看起来外观一致,但其实设备是分主路由和子路由的。因为主路由的配置更好,所以操作一律先从主路由开始折腾。

为了确保设备环境可以复现,在开始折腾设备之前,我为设备做了强制恢复出厂设置:长按设备后部网线接口上的“重置键”,然后插上电源,等待设备橙灯快速闪烁,直至灯熄灭后,重新插上连接网络的网线和连接笔记本的网线,以及电源,耐心等待 LED 灯又长亮橙色变为漂亮的青色。

设备“越狱”:解开 SSH 权限

为了更方便后续的操作,当设备初始化之后,需要对设备进行简单的初始化。

通过 Web 界面完成路由初始化

特别提醒,本文使用的路由固件是 1.0.56,如果你使用了更高版本的固件,无法复现,尝试回滚到这个版本即可。

验证设备可访问

通过在浏览器里访问 192.168.31.1 或使用 curl 先来判断设备是否连接正常,并处于就绪状态。

curl 192.168.31.1 -v

*   Trying 192.168.31.1:80...
* Connected to 192.168.31.1 (192.168.31.1) port 80
> GET / HTTP/1.1
> Host: 192.168.31.1
> User-Agent: curl/8.7.1
> Accept: */*
> 
* Request completely sent off
< HTTP/1.1 200 OK
< Server: nginx
< Date: Wed, 26 Mar 2025 11:49:36 GMT
< Content-Type: text/html; charset=UTF-8
< Content-Length: 1770
< Last-Modified: Tue, 26 Nov 2024 02:21:15 GMT
< Connection: keep-alive
< ETag: "6745309b-6ea"
< Expires: Thu, 01 Jan 1970 00:00:01 GMT
< Cache-Control: no-cache
< X-Frame-Options: sameorigin
< Accept-Ranges: bytes
< 

curl 命令执行完毕之后,除了 “200 OK” 之外,还能够看到小米路由器的 HTML 页面信息。

<!DOCTYPE html>
<!--[if lt IE 7]><html class="ie6 oldie" lang="zh"><![endif]-->
<!--[if IE 7]><html class="ie7 oldie" lang="zh"><![endif]-->
<!--[if IE 8]><html class="ie8 oldie" lang="zh"><![endif]-->
<!--[if gt IE 8]><!--> <html lang="zh"> <!--<![endif]-->
<head>
<meta http-equiv="x-ua-compatible" content="IE=9" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>小米路由器</title>
...

构建工具镜像

有网友将小米的越狱工具进行了开源,为了不影响本地的环境,并且能够进行更简单的复现,可以编写一个 Dockerfile 来构建一个工具镜像:

FROM python:3.10-slim
RUN sed -i 's#http://deb.debian.org#https://mirrors.tuna.tsinghua.edu.cn#g' /etc/apt/sources.list.d/debian.sources && \
    apt-get update && apt-get install git -y && \
    rm -rf /var/lib/apt/lists/*
# https://github.com/openwrt-xiaomi/xmir-patcher
RUN git clone https://github.com/openwrt-xiaomi/xmir-patcher.git /app/xmir-patcher
WORKDIR /app/xmir-patcher
RUN git checkout 5e3bc719deab2db364098ed83affa33c5d3b73bd
RUN python -m pip install -r requirements.txt
ENV PYTHONUNBUFFERED=TRUE
CMD ["python3", "menu.py"]

将上面的内容保存为 Dockerfile 后,使用 docker build -t xiaomi-patcher .,可以完成镜像的构建:

# docker build -t xiaomi-patcher .

[+] Building 0.0s (10/10) FINISHED                                                                                        docker:desktop-linux
 => [internal] load build definition from Dockerfile                                                                                      0.0s
 => => transferring dockerfile: 562B                                                                                                      0.0s
 => [internal] load metadata for docker.io/library/python:3.10-slim                                                                       0.0s
 => [internal] load .dockerignore                                                                                                         0.0s
 => => transferring context: 2B                                                                                                           0.0s
 => [1/6] FROM docker.io/library/python:3.10-slim                                                                                         0.0s
 => CACHED [2/6] RUN sed -i 's#http://deb.debian.org#https://mirrors.tuna.tsinghua.edu.cn#g' /etc/apt/sources.list.d/debian.sources &&    0.0s
 => CACHED [3/6] RUN git clone https://github.com/openwrt-xiaomi/xmir-patcher.git /app/xmir-patcher                                       0.0s
 => CACHED [4/6] WORKDIR /app/xmir-patcher                                                                                                0.0s
 => CACHED [5/6] RUN git checkout 5e3bc719deab2db364098ed83affa33c5d3b73bd                                                                0.0s
 => CACHED [6/6] RUN python -m pip install -r requirements.txt                                                                            0.0s
 => exporting to image                                                                                                                    0.0s
 => => exporting layers                                                                                                                   0.0s
 => => writing image sha256:ff897f8ca1fbc59b9c986aff2cbee7ed83ff3619f26e0642ed7113f5fcdd3757                                              0.0s
 => => naming to docker.io/library/xiaomi-patcher                                                                                         0.0s

在完成镜像构建后,执行 docker run 命令,并将本地目录的 backup 目录映射到容器中的 /app/xmir-patcher/backups 目录中:

# docker run --rm -it -v `pwd`/backup:/app/xmir-patcher/backups xiaomi-patcher

==========================================================

Xiaomi MiR Patcher  


 1 - Set IP-address (current value: 192.168.31.1)
 2 - Connect to device (install exploit)
 3 - Read full device info
 4 - Create full backup
 5 - Install EN/RU languages
 6 - Install Breed bootloader
 7 - Install firmware (from directory "firmware")
 8 - {{{ Other functions }}}
 9 - [[ Reboot device ]]
 0 - Exit

Select: 

顺利的话,将能够看到上面的文字界面,提醒可以输入不同的数字,来完成对应的操作。

解开设备的 SSH 访问权限

输入 “2”,并敲下回车进行确认,很快就能够看到设备的 SSH 服务被启动的信息啦:

# Select: 2

device_name = RN04
rom_version = 1.0.56 release
mac_address = 00:e0:4c:xx:xx:xx
CountryCode = CN
Enter device WEB password: soulteary
Exploit "start_binding" detected!
Run SSH server on port 22 ...
#### SSH server are activated! ####

获取设备基础信息

在解除 SSH 权限后,可以先进行基础信息的获取和原始数据备份。输入“3”,并敲下回车后,程序会尝试进行设备各种信息的获取:

# Select: 3

Detect valid SSH server on port 22 (auth OK)
Download file: "/tmp/dmesg.log" ....
Download file: "/tmp/mtd_list.txt" ....
Download file: "/tmp/mtd_info.txt" ....
Download file: "/tmp/mtd_fdt.txt" ....
...

设备分区表信息

为了更好的使用这台设备,或许需要耐心从路由的固件处,开始了解这台路由,以及官方开发团队的一些设计。

个人认为,作为一台路由器来说,它的设备分区表算是比较复杂的了,足足有 35 项内容:

MTD partitions:
   0 > addr: 0x00000000  size: 0x00180000  ro:0  name: "0:SBL1"
   1 > addr: 0x00180000  size: 0x00180000  ro:0  name: "0:SBL1_1"
   2 > addr: 0x00300000  size: 0x00100000  ro:0  name: "0:MIBIB"
   3 > addr: 0x00400000  size: 0x00080000  ro:0  name: "0:BOOTCONFIG"
   4 > addr: 0x00480000  size: 0x00080000  ro:0  name: "0:BOOTCONFIG1"
   5 > addr: 0x00500000  size: 0x00380000  ro:0  name: "0:QSEE"
   6 > addr: 0x00880000  size: 0x00380000  ro:0  name: "0:QSEE_1"
   7 > addr: 0x00C00000  size: 0x00080000  ro:0  name: "0:DEVCFG"
   8 > addr: 0x00C80000  size: 0x00080000  ro:0  name: "0:DEVCFG_1"
   9 > addr: 0x00D00000  size: 0x00080000  ro:0  name: "0:TME"
  10 > addr: 0x00D80000  size: 0x00080000  ro:0  name: "0:TME_1"
  11 > addr: 0x00E00000  size: 0x00080000  ro:0  name: "0:CDT"
  12 > addr: 0x00E80000  size: 0x00080000  ro:0  name: "0:CDT_1"
  13 > addr: 0x00F00000  size: 0x00080000  ro:0  name: "0:APPSBLENV"
  14 > addr: 0x00F80000  size: 0x00180000  ro:0  name: "0:APPSBL"
  15 > addr: 0x01100000  size: 0x00180000  ro:0  name: "0:APPSBL_1"
  16 > addr: 0x01280000  size: 0x00200000  ro:0  name: "0:ART"
  17 > addr: 0x01480000  size: 0x00080000  ro:0  name: "0:TRAINING"
  18 > addr: 0x01500000  size: 0x00040000  ro:0  name: "0:LICENSE"
  19 > addr: 0x01540000  size: 0x02D00000  ro:0  name: "rootfs"
  20 > addr: 0x04240000  size: 0x02D00000  ro:0  name: "rootfs_1"
  21 > addr: 0x06F40000  size: 0x00080000  ro:0  name: "bdata"
  22 > addr: 0x06FC0000  size: 0x00080000  ro:0  name: "crash"
  23 > addr: 0x07040000  size: 0x02F40000  ro:0  name: "overlay"
  24 > addr: 0x09F80000  size: 0x02000000  ro:0  name: "central"
  25 > addr: 0x0BF80000  size: 0x04000000  ro:0  name: "docker"
  26 > addr: 0x0FF80000  size: 0x00800000  ro:0  name: "app_data"
  27 > addr: 0x10780000  size: 0x0F880000  ro:0  name: "other"
  28 > addr: 0xFFFFFFFF  size: 0x00363E16  ro:0  name: "kernel"
  29 > addr: 0xFFFFFFFF  size: 0x0175F000  ro:0  name: "ubi_rootfs"
  30 > addr: 0xFFFFFFFF  size: 0x00C1C000  ro:0  name: "cfg"
  31 > addr: 0xFFFFFFFF  size: 0x00C1C000  ro:0  name: "user"
  32 > addr: 0xFFFFFFFF  size: 0x00B62000  ro:0  name: "plugin"
  33 > addr: 0xFFFFFFFF  size: 0x033F3000  ro:0  name: "ubi_docker"
  34 > addr: 0xFFFFFFFF  size: 0x007A1000  ro:0  name: "ubi_central"
  35 > addr: 0xFFFFFFFF  size: 0x0EB68000  ro:0  name: "data"

上面获得的一些分区地址为 0xFFFFFFFF,这些分区可能由 UBI 动态分配或程序逻辑映射,实际物理地址应该是在系统运行时确定,而非固定的物理地址。从命名和分区设置规律来看,分区后缀 _1 表示设备采用类似 Android 的冗余(双镜像)机制,便于在升级失败或损坏时自动回退到备份版本。

如果对上面的分区进行分类,大概可以得到三类功能。

Bootloader 和启动相关分区

  • Secondary Boot Loader:0:SBL10:SBL1_1,辅助引导加载程序,用于设备启动,存在两套说明路由使用了类似 Android 手机的 A/B 分区引导类似的设计。
  • 多镜像启动信息块(Multi-Image Boot Information Block): 0:MIBIB,记录镜像加载的配置信息。
  • 启动配置区域:0:BOOTCONFIG0:BOOTCONFIG1,保存设备两种不同版本固件引导时使用的配置数据。
  • Qualcomm 安全执行环境 (Qualcomm Secure Execution Environment):0:QSEE0:QSEE_1:,用于安全启动和安全计算。
  • 设备配置: 0:DEVCFG0:DEVCFG_1,存储设备硬件相关的配置信息。
  • 可信管理引擎(Trusted Management Engine):0:TME0:TME_1,用于设备安全管理,估计是保存配对后的米家设备。
  • 配置数据表(Configuration Data Table):0:CDT0:CDT_1,设备硬件配置参数。
  • 应用引导加载程序环境: 0:APPSBLENV,存储 U-Boot 或其他 Bootloader 环境变量。
  • 路由器的 Bootloader(如 U-Boot):0:APPSBL0:APPSBL_1,用于加载内核。
  • 无线射频校准数据分区:0:ART,存储无线芯片的校准数据。
  • 可能是根据环境自适应学习的配置或程序数据:0:TRAINING
  • 相关开源、闭源项目的许可证信息: 0:LICENSE

系统和根文件系统相关分区:

  • 存储主系统的根文件系统镜像:rootfsrootfs_1,类似 Android 的双镜像布局用于系统升级和回滚。
  • Overlay 文件系统分区:overlay,存放设备运行过程中用户写入的修改和数据。
  • 基于 UBI 格式的根文件系统分区:ubi_rootfs,设备实际启动时使用的根文件系统可能位于此处。
  • 存储 Linux 内核镜像:kernel

数据和应用相关分区:

  • 设备特有标识信息(如 MAC 地址、序列号)或其他基础数据:bdata
  • 存储设备异常崩溃时的日志和调试信息:crash
  • 可能存储设备的核心应用或服务的数据:central
  • Docker 相关分区:dockerubi_docker,存储镜像或容器相关数据。
  • 存储第三方应用、插件或相关配置信息:app_dataplugin
  • 设备用户配置、个性化数据存储区域:cfguser
  • 基于 UBI 格式存储的设备核心服务(中枢网关)或应用数据:ubi_central
  • 不确定存储的内容:other

设备内核信息

继续阅读程序获取的设备信息,可以获得非常多有趣的信息:

Kernel command line:
  ubi.mtd=rootfs root=mtd:ubi_rootfs rootfstype=squashfs cnss2.enable_mlo_support=1 rootwait clk_ignore_unused vmalloc=1G
RootFS info:
  num = 0
  mtd_num = None
  mtd_dev = "None"
  partition = "rootfs"
 
Base info:
  Linux version: None
  DISTRIB_TARGET = ipq53xx/ipq53xx_32
  DISTRIB_ARCH = arm_cortex-a7_neon-vfpv4
  CPU arch: armv7
  CPU name: ipq53xx
 
Version info:
  UBoot: None
  OpenWrt: unknown
  Firmware: 1.0.56
  Channel: release
  BuildTime: Tue, 26 Nov 2024 03:23:06 +0000
  Hardware: RN04
  UBoot(2): 1.0.2
  • ubi.mtd=rootfs:说明使用 UBI(无排序块设备)机制,将名为 rootfs 的分区作为根文件系统。
  • root=mtd:ubi_rootfs:根文件系统位于名为 ubi_rootfs 的MTD(Memory Technology Device)分区中。
  • rootfstype=squashfs:根文件系统采用 SquashFS 类型,这是一个只读、压缩的文件系统,常用于嵌入式设备。
  • cnss2.enable_mlo_support=1:启用了 Qualcomm Wi-Fi 芯片(CNSS2)的 MLO(Multi-Link Operation,多链路操作)功能。
  • rootwait:内核启动时会等待根文件系统设备准备好后再继续启动。
  • clk_ignore_unused:忽略未使用的时钟,避免某些时钟被关闭,从而确保系统稳定运行。
  • vmalloc=1G:预留1GB虚拟内存用于动态分配内存,通常用于加载较大模块或驱动。(这台设备支持 Docker,或许相关)
  • ipq53xx 如果要自行构建系统,需要找到高通 IPQ53xx 芯片相关的资料。
  • armv7 设备使用和支持 32 位的程序,构建程序的时候,需要指定 32 位程序相关参数。
  • BuildTime: Tue, 26 Nov 2024 03:23:06 +0000:我手头的这台设备的初始系统版本,构建于去年的 11 月 26 日。
  • Hardware: RN04,设备代号为 RN04,或许说明再次之前还有三个不同的方案。
  • UBoot: 1.0.2,使用的引导程序版本为 1.0.2,这至少是第二个小的修订版本。

NVRam 、Bootloader、ENV 信息

继续分析最后三项打印出来的设备信息,同样可以获得有趣的内容:

NVRam params:
  flag_boot_rootfs=0
  flag_boot_success=1
  flag_boot_type=2
  flag_last_success=0
  flag_ota_reboot=0
  flag_try_sys1_failed=0
  flag_try_sys2_failed=0
  ipaddr=192.168.31.1
  serverip=192.168.31.100
 
Bootloader info:
Download file: "/tmp/bl_0SBL1.bin" ....
  addr: 0x00000000 (size: 0x00180000)
    image size: 12 bytes
    type: None
Download file: "/tmp/bl_0APPSBL.bin" ....
  addr: 0x00F80000 (size: 0x00180000)
    image size: 177 bytes
    type: None

ENV info:
Download file: "/tmp/env_0APPSBLENV.bin" ....
  addr: 0x00F00000 (size: 0x00080000)  
    CRC32: 0x599E156B
    max size: 0x10000
Download file: "/tmp/env_bdata.bin" ....
  addr: 0x06F40000 (size: 0x00080000)  
    CRC32: 0x546267BE
    max size: 0x10000
Download file: "/tmp/env_0SBL1.bin" ....
  addr: 0x00060000 (size: 0x00120000)  breed

NVRAM (Non-Volatile RAM) 标志类信息和网络参数

  • 启动标志(flag)类参数:flag_boot_rootfs=0,当前使用根文件系统编号为0,表示设备启动时默认使用第一个根文件系统分区。
  • 设备上一次启动是否正常:flag_boot_success=1,推测这里是 0 的时候,程序将调整上面的 flag_boot_rootfs 为两个分区中的另外一个。
  • 启动类型设定:flag_boot_type=2 不太清楚这里的定义,这里的 2 代表正常启动或等待初始化都有可能。
  • 上次正常启动分区号:flag_last_success=0,上一次成功启动的分区编号,这里表示上次启动的是系统的第一个分区。
  • OTA 升级后是否需要重启:flag_ota_reboot=0,OTA(远程升级)后是否需要重启,当前 0 表示不需要。
  • 两套系统是否启动失败:flag_try_sys1_failed=0 应该表示两套系统都正常,均为出现启动失败。
  • ipaddr=192.168.31.1,设备启动时的默认 IP 地址。
  • serverip=192.168.31.100,DHCP 开始提供服务的 IP 地址。

Bootloader信息

设备 Bootloader 镜像分区和镜像文件:

  • 文件 /tmp/bl_0SBL1.bin:地址 0x00000000,分区大小 0x00180000(1.5MB),得到的镜像大小仅 12 字节,有可能只存了某个数值或文件占位符。
  • 文件 /tmp/bl_0APPSBL.bin:地址 0x00F80000,分区大小 0x00180000(1.5MB),得到镜像大小 177 字节,和上面类似,并非包含完整的引导程序,大概率是占位文件。

环境变量(ENV)信息:

  • 文件 /tmp/env_0APPSBLENV.bin:地址 0x00F00000,分区大小 0x00080000(512KB),最大可用大小为 0x10000(64KB),存放Bootloader环境变量,比如启动参数等。
  • 文件 /tmp/env_bdata.bin:地址 0x06F40000,分区大小 0x00080000(512KB),最大可用大小同样为64KB,存放设备基础信息(如序列号、MAC地址、出厂信息等)。
  • 文件 /tmp/env_0SBL1.bin:地址 0x00060000,分区大小 0x00120000(约1.1MB),默认的注释为 breed,这说明路由器可能在使用 Breed 作为引导程序,或者魔改后兼容 Breed 的引导程序。

备份设备原始固件

输入 “4”,敲下回车,Docker 工具程序会将路由的原始固件备份到本地的 backup 目录中:

# Select: 4

Detect valid SSH server on port 22 (auth OK)
Download file: "/tmp/dmesg.log" ....
Download file: "/tmp/mtd_list.txt" ....
Download file: "/tmp/mtd_info.txt" ....
Download file: "/tmp/mtd_fdt.txt" ....
Download file: "/tmp/kcmdline.log" ....
Download file: "/tmp/kver.txt" ....
Download file: "/tmp/dmesg.log" ....
Download file: "/tmp/mtd_list.txt" ....
Download file: "/tmp/mtd_info.txt" ....
Download file: "/tmp/mtd_fdt.txt" ....
Full backup creating...
Download file "./backups/dump_mtd0_0.bin"...
File "backups/mtd0_0SBL1.bin" created!"
Backup of "0SBL1" saved to file "./backups/mtd0_0SBL1.bin"
Download file "./backups/dump_mtd1_0.bin"...
File "backups/mtd1_0SBL11.bin" created!"
Backup of "0SBL11" saved to file "./backups/mtd1_0SBL11.bin"
Download file "./backups/dump_mtd2_0.bin"...
File "backups/mtd2_0MIBIB.bin" created!"
Backup of "0MIBIB" saved to file "./backups/mtd2_0MIBIB.bin"
Download file "./backups/dump_mtd3_0.bin"...
File "backups/mtd3_0BOOTCONFIG.bin" created!"
Backup of "0BOOTCONFIG" saved to file "./backups/mtd3_0BOOTCONFIG.bin"
Download file "./backups/dump_mtd4_0.bin"...
...

耐心等待固件备份完毕,将得到一堆 bin 文件(未压缩时有 600MB+):

ls backup
mtd0_0SBL1.bin        mtd15_0APPSBL1.bin    mtd20_rootfs1.bin     mtd26_appdata.bin     mtd31_user.bin        mtd4_0BOOTCONFIG1.bin
mtd10_0TME1.bin       mtd16_0ART.bin        mtd21_bdata.bin       mtd27_other.bin       mtd32_plugin.bin      mtd5_0QSEE.bin
mtd11_0CDT.bin        mtd17_0TRAINING.bin   mtd22_crash.bin       mtd28_kernel.bin      mtd33_ubidocker.bin   mtd6_0QSEE1.bin
mtd12_0CDT1.bin       mtd18_0LICENSE.bin    mtd23_overlay.bin     mtd29_ubirootfs.bin   mtd34_ubicentral.bin  mtd7_0DEVCFG.bin
mtd13_0APPSBLENV.bin  mtd19_rootfs.bin      mtd24_central.bin     mtd2_0MIBIB.bin       mtd35_data.bin        mtd8_0DEVCFG1.bin
mtd14_0APPSBL.bin     mtd1_0SBL11.bin       mtd25_docker.bin      mtd30_cfg.bin         mtd3_0BOOTCONFIG.bin  mtd9_0TME.bin

将文件保存好,后面可以开始进一步的信息分析。

使用 SSH 命令连接设备

如果仔细翻阅上面 Docker 镜像工具中使用的开源 Python 项目,能够发现工具为了操作简单,会将 root 密码进行修改,改为相同的内容 root 字符串:

# change password for root
echo -e "root\nroot" | (passwd root) 

所以,可以通过下面的命令,来快速连接设备:

# ssh root@192.168.31.1     
The authenticity of host '192.168.31.1 (192.168.31.1)' can't be established.
RSA key fingerprint is SHA256:L23dIByGO5DsfaNxAHAzuSd0eBa9TilmhdMzY3qYh9o.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.31.1' (RSA) to the list of known hosts.
root@192.168.31.1's password: 


BusyBox v1.36.1 (2024-11-26 02:21:15 UTC) built-in shell (ash)

 -----------------------------------------------------
       Welcome to XiaoQiang!
 -----------------------------------------------------
  $$$$$$\  $$$$$$$\  $$$$$$$$\      $$\      $$\        $$$$$$\  $$\   $$\
 $$  __$$\ $$  __$$\ $$  _____|     $$ |     $$ |      $$  __$$\ $$ | $$  |
 $$ /  $$ |$$ |  $$ |$$ |           $$ |     $$ |      $$ /  $$ |$$ |$$  /
 $$$$$$$$ |$$$$$$$  |$$$$$\         $$ |     $$ |      $$ |  $$ |$$$$$  /
 $$  __$$ |$$  __$$< $$  __|        $$ |     $$ |      $$ |  $$ |$$  $$<
 $$ |  $$ |$$ |  $$ |$$ |           $$ |     $$ |      $$ |  $$ |$$ |\$$\
 $$ |  $$ |$$ |  $$ |$$$$$$$$\       $$$$$$$$$  |       $$$$$$  |$$ | \$$\
 \__|  \__|\__|  \__|\________|      \_________/        \______/ \__|  \__|


root@XiaoQiang:~# 

登录路由之后,能够看到巨大的 “ARE U OK” 艺术字,这个“习俗”在十年前的小米设备中就有了,算是一个约定俗成的无害的彩蛋吧。

获取设备硬件信息

在上文中从固件中静态分析的角度,了解了一些硬件相关的信息,现在再来根据系统动态运行的内容,补充获取一些基础信息吧:

root@XiaoQiang:~# cat /proc/cpuinfo
processor	: 0
model name	: ARMv7 Processor rev 4 (v7l)
BogoMIPS	: 66.00
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 
CPU implementer	: 0x51
CPU architecture: 7
CPU variant	: 0xa
CPU part	: 0x801
CPU revision	: 4

processor	: 1
model name	: ARMv7 Processor rev 4 (v7l)
BogoMIPS	: 66.00
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 
CPU implementer	: 0x51
CPU architecture: 7
CPU variant	: 0xa
CPU part	: 0x801
CPU revision	: 4

processor	: 2
model name	: ARMv7 Processor rev 4 (v7l)
BogoMIPS	: 66.00
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 
CPU implementer	: 0x51
CPU architecture: 7
CPU variant	: 0xa
CPU part	: 0x801
CPU revision	: 4

processor	: 3
model name	: ARMv7 Processor rev 4 (v7l)
BogoMIPS	: 66.00
Features	: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm aes pmull sha1 sha2 crc32 
CPU implementer	: 0x51
CPU architecture: 7
CPU variant	: 0xa
CPU part	: 0x801
CPU revision	: 4

Hardware	: Generic DT based system
Revision	: 0000
Serial		: 0000000000000000

和之前分析的一致,设备使用的是一颗 ARMv7 Rev 4 的处理器,具备 4 个核心,Bogo MIPS 估算处理器速度为 66.00。CPU 特性支持还挺多,包含了 neon 指令,这个指令可以快速处理视频或图片,做语音识别等等(不过这台路由器看起来默认没有这些功能)。同样支持 lpae,能够支持 4GB 以上的内存,或许未来会有人魔改这台设备的内存,来让 Docker 运行一些吃资源的应用。

接下来,了解下内存相关的使用情况:

root@XiaoQiang:~# cat /proc/meminfo
MemTotal:         443036 kB
MemFree:          184668 kB
MemAvailable:     271344 kB
Buffers:            9620 kB
Cached:           112280 kB
SwapCached:            0 kB
Active:            90440 kB
Inactive:          52768 kB
Active(anon):      26956 kB
Inactive(anon):     1524 kB
Active(file):      63484 kB
Inactive(file):    51244 kB
Unevictable:        5008 kB
Mlocked:               0 kB
HighTotal:             0 kB
HighFree:              0 kB
LowTotal:         443036 kB
LowFree:          184668 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB
Writeback:             0 kB
AnonPages:         26316 kB
Mapped:            83488 kB
Shmem:              2164 kB
KReclaimable:       7492 kB
Slab:              62284 kB
SReclaimable:       7492 kB
SUnreclaim:        54792 kB
KernelStack:        2928 kB
PageTables:         1188 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:      221516 kB
Committed_AS:     147256 kB
VmallocTotal:    1556480 kB
VmallocUsed:       22660 kB
VmallocChunk:          0 kB
Percpu:             1232 kB

设备整体装配了 512MB 的内存,因为预留了一部分给硬件共享使用,实际可用的内存是 432MB,默认情况下可用内存大约 265MB(271344KB),空闲内存 180MB(184668KB)。

在不运行 Docker 程序的情况下,内存资源是比较富裕的,放几年前应该是高端中的旗舰设备,不过这几年路由器蓬勃发展,这个配置大概是一个中上游水平吧。

也正是因为设备配备了比较大的内存,允许了即使不刷机为其他系统,也能够运行较大体积的容器应用程序。(下文展开)

文件系统相关信息

接下来,使用命令继续获取设备运行时的文件系统信息:

root@XiaoQiang:~# df -h
Filesystem                Size      Used Available Use% Mounted on
/dev/mtdblock29          23.3M     23.3M         0 100% /
tmpfs                   216.3M      2.1M    214.2M   1% /tmp
ubi23:cfg                 9.4M      3.1M      5.8M  34% /data
ubi23:user                9.4M      2.8M      6.1M  31% /data/usr
ubi23:plugin              8.7M     28.0K      8.2M   0% /data/userdisk
ubi23:plugin              8.7M     28.0K      8.2M   0% /userdisk
/dev/mtdblock29          23.3M     23.3M         0 100% /userdisk/data
/dev/ubiblock25_0        51.9M     51.9M         0 100% /data/docker
/dev/ubiblock24_0         7.6M      7.6M         0 100% /data/central
ubi27_0                 215.6M     17.9M    193.0M   8% /data/other_vol
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /tmp/sec_cfg/etc
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /data/etc
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/config
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/datacenterconfig
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/smartcontroller
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/parentalctl
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/smartvpn
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/ppp
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/crontabs
/dev/mapper/sec_cfg       5.7M    975.0K      4.3M  18% /etc/mipctl
/dev/mapper/other_enc
                        177.5M    268.0K    164.0M   0% /data/other
tmpfs                   512.0K         0    512.0K   0% /dev
/dev/mapper/other_enc
                        177.5M    268.0K    164.0M   0% /data/other/docker

能够看到整个小米路由的固件其实只有 23.3MB (/dev/mtdblock29),临时文件系统 tmpfs(/tmp)划分了 216.3MB 的内存,目前使用了 2.1M(1%)。用户数据配置(/data)存储配置(ubi23:cfg)和用户数据(ubi23:user)分别使用了 9.4M 空间,ubi23:plugin 插件分区配置了 8.7MB。

Docker 分区(/dev/ubiblock25_0)使用了 51.9M的空间,核心应用中枢网关的镜像分区(/dev/ubiblock24_0),占用了 7.6M 的空间。剩下的其他数据目录(ubi27_0)可用空间为 215.6M。固件本身还支持了一些用于安全加密配置信息保存的分区。

整体设计上来看非常合理,本体固件是和多数路由设备一样的 SquashFS 只读分区。单独使用 cfguser 分区将配置数据和用户数据分离,便于系统升级、备份和初始化还原。原生支持使用 Docker 应用,同时特别做了专门的加密映射,用来增强数据安全。

无线相关信息

虽然我不计划用这台设备做无线路由器使用,但是还是通过命令简单查看了设备无线相关信息:

root@XiaoQiang:~# iwconfig
wifi0     no wireless extensions.

br-docker  no wireless extensions.

eth0.3    no wireless extensions.

bhap_mld0  IEEE 802.11  Mode:Master  
          RTS thr:off   Fragment thr:off
          Power Management:off
          
wl5       IEEE 802.11bea  ESSID:"MiMesh_123123"  
          Mode:Master  Frequency:5.24 GHz  Access Point: Not-Associated   
          Bit Rate:0 kb/s   Tx-Power=28 dBm   
          RTS thr:off   Fragment thr:off
          Encryption key:1234-1122-1234-1122-1234-1122-1234-1122   Security mode:restricted
          Power Management:off
          Link Quality=0/94  Signal level=-96 dBm  Noise level=-96 dBm (BDF averaged NF value in dBm)
          Rx invalid nwid:178  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

gretap0   no wireless extensions.

eth0      no wireless extensions.

gre0      no wireless extensions.

ip6tnl0   no wireless extensions.

eth1      no wireless extensions.

soc1      no wireless extensions.

wl0       IEEE 802.11bea  ESSID:"Xiaomi_TEST"  
          Mode:Master  Frequency:5.24 GHz  Access Point: 90:FB:5D:70:E5:95   
          Bit Rate:2.8824 Gb/s   Tx-Power=28 dBm   
          RTS thr:off   Fragment thr:off
          Encryption key:1234-1122-1234-1122-1234-1122-1234-1122   Security mode:restricted
          Power Management:off
          Link Quality=0/94  Signal level=-96 dBm  Noise level=-96 dBm (BDF averaged NF value in dBm)
          Rx invalid nwid:1543  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

wl1       IEEE 802.11beg  ESSID:"Xiaomi_TEST"  
          Mode:Master  Frequency:2.437 GHz  Access Point: 90:FB:5D:70:E5:94   
          Bit Rate:344.2 Mb/s   Tx-Power=28 dBm   
          RTS thr:off   Fragment thr:off
          Encryption key:1234-1122-1234-1122-1234-1122-1234-1122   Security mode:restricted
          Power Management:off
          Link Quality=0/94  Signal level=-96 dBm  Noise level=-96 dBm (BDF averaged NF value in dBm)
          Rx invalid nwid:1813  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

mld-wifi0  IEEE 802.11  Mode:Master  
          RTS thr:off   Fragment thr:off
          Power Management:off
          
br-lan    no wireless extensions.

wifi1     no wireless extensions.

erspan0   no wireless extensions.

br-miot   no wireless extensions.

eth0.2    no wireless extensions.

bhsta_mld0  IEEE 802.11  ESSID:off/any  
          Mode:Managed  Access Point: Not-Associated   
          RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          
eth0.1    no wireless extensions.

lo        no wireless extensions.

bond0     no wireless extensions.

wl4       IEEE 802.11beg  ESSID:"MiMesh_123123123"  
          Mode:Master  Frequency:2.437 GHz  Access Point: Not-Associated   
          Bit Rate:0 kb/s   Tx-Power=28 dBm   
          RTS thr:off   Fragment thr:off
          Encryption key:1234-1122-1234-1122-1234-1122-1234-1122   Security mode:restricted
          Power Management:off
          Link Quality=0/94  Signal level=-96 dBm  Noise level=-96 dBm (BDF averaged NF value in dBm)
          Rx invalid nwid:178  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

hostap_mld0  IEEE 802.11  Mode:Master  
          RTS thr:off   Fragment thr:off
          Power Management:off
          
wl13      IEEE 802.11beg  ESSID:"123123123123123_miwifi"  
          Mode:Master  Frequency:2.437 GHz  Access Point: Not-Associated   
          Bit Rate:0 kb/s   Tx-Power=28 dBm   
          RTS thr:off   Fragment thr:off
          Encryption key:off
          Power Management:off
          Link Quality=0/94  Signal level=-96 dBm  Noise level=-96 dBm (BDF averaged NF value in dBm)
          Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
          Tx excessive retries:0  Invalid misc:0   Missed beacon:0

soc0      no wireless extensions.

从打印出的日志来看,设备是支持 Wi-Fi 7 的(IEEE 802.11bea),当前空载时的系统速率为 2.8824 Gb/s(并且是 28 dBm 的较高功率)。同时还支持两个不同频率的小米 Mesh 无线接口(2.4GHz 和 5GHz),以及还有几个感觉是用于不同模式的接口,从命名推测是无线回程(Backhaul),多路复用(MLO)接口,以及可能用于米家设备漫游发现的接口等,具体需要有场景的同学实测了。

OpenWRT 相关信息

在系统的 /etc 分区里,能够看到有两个名为 openwrt 前缀的文件:

# ls /etc/openwrt_*
/etc/openwrt_release  /etc/openwrt_version

阅读文件内容,能够发现当前镜像是基于 18.04 这个比较古老的版本构建的:

# cat /etc/openwrt_*
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='18.06-SNAPSHOT'
DISTRIB_REVISION='unknown'
DISTRIB_TARGET='ipq53xx/ipq53xx_32'
DISTRIB_ARCH='arm_cortex-a7_neon-vfpv4'
DISTRIB_DESCRIPTION='OpenWrt 18.06-SNAPSHOT unknown'
DISTRIB_TAINTS='no-all busybox override'
unknown

如果想要构建一些 OpenWRT 插件在这台设备上使用,或许需要使用旧版本 OpenWRT 相关的代码或工具。

使用 uname -a 得到的内核参数,进一步能够确定上面的判断:

Linux XiaoQiang 5.4.213 #0 SMP PREEMPT Tue Nov 26 02:21:15 2024 armv7l GNU/Linux

OpenWRT 18.06 默认的内核应该是 4.4 / 4.19,而小米使用的是 5.4 内核,说明路由器团队应该打了大量补丁。不同版本的 OpenWRT 的内核接口、系统 C 库、ABI 差异、库依赖接口差异都可能会浪费大量时间。

当然,也可以选择构建一个新的适配于这套硬件的新固件系统(放弃可能最佳的无线性能,而专注获取新的 Linux 特性和可能的更高的计算效率)。

Docker 相关信息

当完成初始化之后,Docker 也会随设备启动:

# ps | grep docker
 4840 root      1336 S    grep docker
18629 root      804m S    /data/docker/dockerd --config-file=/tmp/dockerd/daemon.json
18691 root      689m S    containerd --config /tmp/docker_exec/containerd/containerd.toml --log-level warn

通过 docker info,能够看到小米路由器使用的 Docker 版本还蛮新的:

root@XiaoQiang:~# docker info
Client:
 Version:    26.1.2
 Context:    default
 Debug Mode: false

Server:
 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 26.1.2
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 926c9586fe4a6236699318391cd44976a98e31f1
 runc version: v1.1.12-0-g51d5e94
 init version: de40ad0
 Kernel Version: 5.4.213
 Operating System: OpenWrt 18.06-SNAPSHOT
 OSType: linux
 Architecture: armv7l
 CPUs: 4
 Total Memory: 432.7MiB
 Name: XiaoQiang
 ID: 021888d8-fa5f-4f1d-b750-49d402cafab7
 Docker Root Dir: /data/other/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine

WARNING: No swap limit support
WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
root@XiaoQiang:~#

不过,默认情况下只是 Docker 服务启动了,并没有运行任何容器,也没有导入任何 Docker 镜像。

这里先不研究如何使用小米固件中默认自带的中枢网关,而是来尝试让小米路由器能够通过 Docker,从私有化的 Docker 仓库中下载应用并进行快速启动。

支持使用私有容器仓库

默认情况下,容器仓库都是使用 HTTPS 协议进行交互。如果内网中的容器仓库使用的是自签名证书,在获取镜像的时候,将得到类似下面的错误信息:

# docker pull docker.mongo.lab.com/xhofe/alist:v3.43.0-aria2
Error response from daemon: Get "https://docker.mongo.lab.com/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority

想要在小米路由器中解决这个问题,需要在官方提供的 /etc/init.d/mi_docker Docker 管理脚本中,添加一些内容,让路由器的 Docker 程序在初始化的时候,能够允许访问不被信任的证书环境。(更好的方式是配置容器信任证书,但在路由器环境中,除非构建固件,否则配置非常麻烦)

使用路由器自带的 VIM 编辑器,对程序进行修改 vim /etc/init.d/mi_docker ,找到配置中的:

        json_add_string "data-root" "${data_root}"
        json_add_string "log-level" "${log_level}" 

在上面添加:

        json_add_array "insecure-registries" 
        json_add_string "" "docker.mongo.lab.com" 
        json_close_array

使用 :wq 保存文件后,执行 /etc/init.d/mi_docker restart 重启容器服务,再次使用 docker pull 命令下载容器,会发现已经可以正常访问仓库,但是缺少鉴权信息:

# docker pull docker.mongo.lab.com/xhofe/alist:v3.43.0-aria2
Error response from daemon: Head "https://docker.mongo.lab.com/v2/xhofe/alist/manifests/v3.43.0-aria2": no basic auth credentials

如果使用 docker login 直接登录仓库,会发现因为路由器的只读分区机制,登录操作无法实现:

# docker login docker.mongo.lab.com
Username: soulteary
Password: 
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Error saving credentials: mkdir /root/.docker: read-only file system

解决的方法也比较简单,可以在临时目录中创建一个 .docker 目录,在登录的时候,指定容器要使用的配置目录即可完成仓库鉴权:

# mkdir -p /tmp/.docker
# docker --config /tmp/.docker login docker.mongo.lab.com
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /tmp/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

再次使用 docker pull 下载镜像的时候,可以通过添加 --config 参数,指定刚刚的鉴权信息,来进行仓库中的镜像下载:

# docker --config /tmp/.docker pull docker.mongo.lab.com/xhofe/alist:v3.43.0-aria2
v3.43.0-aria2: Pulling from xhofe/alist
56c91669ab0b: Pull complete 
86fc7f545902: Pull complete 
52b30c650f97: Pull complete 
2298c9ed7e57: Pull complete 
55e8e23d687c: Pull complete 
d3c7863c3dba: Extracting [==================================================>]  30.16MB/30.16MB
failed to register layer: write /opt/alist/alist: no space left on device

不过,路由器上目前的磁盘空间并不够大,不能够将 Alist 镜像下载下来。所以还需要调整下之前的 /etc/init.d/mi_docker 程序,将 Docker 数据目录调整到一个可以放下 Alist 容器的地方。原始的数据保存目录是:

json_add_string "data-root" "${data_root}"

可以将这个地址调整为大量冗余资源的,基于内存的临时目录中:

json_add_string "data-root" "/tmp/datadir"

和上文一样,重启 Docker 服务后,再次执行容器镜像下载命令:

# docker --config /tmp/.docker pull docker.mongo.lab.com/xhofe/alist:v3.43.0-aria2
v3.43.0-aria2: Pulling from xhofe/alist
56c91669ab0b: Pull complete 
86fc7f545902: Pull complete 
52b30c650f97: Pull complete 
2298c9ed7e57: Pull complete 
55e8e23d687c: Pull complete 
d3c7863c3dba: Pull complete 
Digest: sha256:018b25d02849a717f6d5a8903b6fcb42ea5a9137a927c1991c66656f0fced671
Status: Downloaded newer image for docker.mongo.lab.com/xhofe/alist:v3.43.0-aria2

稍等片刻,Alist 这个 100 多MB 的镜像就能够被正常下载到路由器上啦。

在小米路由器上快速运行 Alist

完成了镜像的下载后,对 Alist 说明文档中的命令,稍加调整,直接运行:

# docker run -d --restart=always -v /tmp/alist:/opt/alist/data -p 5244:5244 -e PUID=0 -e PGID=0 -e UMASK=022 --name="alist" docker.mongo.lab.com/xhofe/alist:v3.43.0-aria2

707333a7d6a4afcad06cc85dc52eb26b5501e4e1ec60e9e11e0cf01edb0eafe

当 Alist 运行完毕之后,我们就能够通过访问 http://192.168.31.1:5244 来访问 Alist 的界面啦。

AList 登录页面

为了能够登录 Alist,我们需要手动设置下程序的管理员密码:

docker exec -it alist ./alist admin set soulteary

命令执行完毕,会显示密码已经被设置为上面命令中的 soulteary

INFO[2025-03-26 16:20:42] reading config file: data/config.json        
INFO[2025-03-26 16:20:42] load config from env with prefix: ALIST_     
INFO[2025-03-26 16:20:42] init logrus...                               
INFO[2025-03-26 16:20:42] admin user has been updated:                 
INFO[2025-03-26 16:20:42] username: admin                              
INFO[2025-03-26 16:20:42] password: soulteary

使用我们修改后的密码和 admin 用户名就能够完成系统的登录了:

登录 AList

剩下的事情就是在 Alist 的管理后台里,配置你的数据源,就能够通过小米路由器,来浏览或播放你收藏的各种云资源啦。

AList 管理面板

最后

这个月比较忙,这篇文章原计划在月初发布,没曾想到拖到了月底。希望上面的内容,对于想折腾这台配置还不错的路由器的你有帮助。

–EOF