UniFi OS on_boot.d 手动安装与日常排查指南(含一键恢复机制)
适用机型: UDM / UDM-Pro / UDM-SE / UDR / UCG-Ultra / UCG-Fiber(CGF)/ UXG 等运行 UniFi OS 4.x 及以上 的设备。
适用场景: 全程通过 SSH 手动敲命令完成,不依赖 GitHub、Gitee 等任何第三方安装脚本,特别适合国内网络环境。
0. 原理与局限性说明(排查问题前必读)
这份指南综合得非常完善,不仅逻辑清晰,还精准避开了国内网络环境的各种痛点。
尤其是 “系统版本升级后的自动恢复”,这是长期维护 UniFi OS 最大的难点。
很多人希望做到:
固件升级完成 → 自动恢复 on_boot.d → 不需要任何人工操作
遗憾的是,在 UniFi OS 4.x 架构下,这是无法实现的。
原因很简单:
每次 UniFi OS 大版本升级 时,系统都会重新构建整个 Root Filesystem(overlay upper)。
因此下面这些内容都会被删除:
/etc/systemd/system//etc/cron.d//etc/init.d/~/.bashrc- 手动 apt 安装的软件
- 所有 Root 分区修改
但是:
/data
(部分旧型号为 /mnt/data)
属于持久化分区,不会因为升级而丢失。
所以:
恢复脚本可以永久保存。
触发器(systemd)无法永久保存。
因此,100% 自动恢复是不可能的。
目前最稳定、安全、官方升级兼容性最高的方法,就是:
升级完成以后,仅执行一条命令即可恢复全部功能。
整个恢复时间约 5 秒钟。
1. 前置条件
1.1 开启 SSH
进入:
UniFi Console → Settings → System → Advanced → SSH
开启 SSH,并设置 Root 密码。
1.2 确认持久化目录
SSH 登录:
ssh root@设备IP
确认:
ls -ld /data
如果不存在,再查看:
ls -ld /mnt/data
本文统一使用:
/data
如果你的机器使用:
/mnt/data
请自行替换即可。
2. 手动部署(仅需执行一次)
Step 1:创建 on_boot.d
mkdir -p /data/on_boot.d
chmod 755 /data/on_boot.d
Step 2:创建 systemd 服务(永久母本)
注意:
这里不是直接写到 /etc/systemd/。
而是先保存到:
/data/udm-boot.service
以后升级后还能重新恢复。
执行:
cat > /data/udm-boot.service << 'EOF'
[Unit]
Description=UDM Boot Script Runner (on_boot.d)
After=vyatta-router.service network-online.target
Wants=network-online.target
[Service]
Type=idle
ExecStart=/bin/sh -c '/bin/run-parts --exit-on-error --verbose /data/on_boot.d/'
RemainAfterExit=false
TimeoutSec=0
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
Step 3:创建升级恢复脚本(核心)
这是整套方案最重要的一步。
以后升级以后,只需要执行:
/data/recover_boot.sh
即可恢复全部功能。
创建:
cat > /data/recover_boot.sh << 'EOF'
#!/bin/sh
echo "开始恢复 UDM Boot 服务..."
ln -sf /data/udm-boot.service /etc/systemd/system/udm-boot.service
systemctl daemon-reload
systemctl enable --now udm-boot.service
echo "恢复完成!"
systemctl is-active udm-boot.service
EOF
赋予权限:
chmod +x /data/recover_boot.sh
Step 4:首次安装
直接执行恢复脚本:
/data/recover_boot.sh
如果返回:
active
说明安装成功。
Step 5:创建测试脚本
注意:
run-parts 不会执行带 “.” 的文件名。
例如:
10-test.sh
会被忽略。
应该写成:
10-test
创建:
cat > /data/on_boot.d/10-hello-test << 'EOF'
#!/bin/sh
echo "[$(date '+%F %T')] hello from on_boot.d" >> /data/on_boot_test.log
EOF
赋予权限:
chmod +x /data/on_boot.d/10-hello-test
手动测试:
run-parts --exit-on-error --verbose /data/on_boot.d/
查看结果:
cat /data/on_boot_test.log
3. 固件升级后的恢复(重点)
这是唯一需要记住的操作。
升级完成以后:
SSH 登录设备:
ssh root@设备IP
执行:
/data/recover_boot.sh
即可恢复:
- on_boot.d
- systemd
- 开机启动
- 所有脚本
整个过程通常不到 5 秒钟。
这是目前 UniFi OS 下最稳定、兼容性最高的恢复方案。
4. 常见问题(FAQ)
4.1 重启后脚本没有执行
按下面顺序排查:
① 文件名错误
例如:
10-test.sh
不会执行。
应该:
10-test
② 没有执行权限
chmod +x /data/on_boot.d/脚本名
③ Windows 上传导致 CRLF
执行:
sed -i 's/\r$//' /data/on_boot.d/脚本名
4.2 服务显示 failed
由于配置了:
--exit-on-error
任何一个脚本报错,整个服务都会失败。
查看日志:
journalctl -u udm-boot.service -b --no-pager
找到对应脚本。
然后:
sh -x /data/on_boot.d/脚本名
逐步调试。
4.3 DDNS、ZeroTier 等网络脚本偶尔失败
原因:
network-online.target
表示:
网卡启动完成。
并不代表:
PPPoE 已拨号成功。
建议业务脚本增加等待:
#!/bin/sh
for i in $(seq 1 30)
do
ping -c1 -W2 223.5.5.5 >/dev/null 2>&1 && break
sleep 2
done
# 下面继续执行 DDNS 等业务逻辑
4.4 多个脚本执行顺序不正确
run-parts 按照文件名字典序执行。
建议统一:
01-init
02-route
05-ddns
10-docker
20-zerotier
不要使用:
1-test
2-test
9-test
10-test
否则:
10-test
可能排在:
9-test
前面。
4.5 临时禁用某个脚本
无需改名。
直接取消执行权限:
chmod -x /data/on_boot.d/脚本名
恢复:
chmod +x /data/on_boot.d/脚本名
5. 卸载
停止服务:
systemctl disable --now udm-boot.service
删除 systemd:
rm -f /etc/systemd/system/udm-boot.service
删除母本:
rm -f /data/udm-boot.service
删除恢复脚本:
rm -f /data/recover_boot.sh
删除 on_boot.d:
rm -rf /data/on_boot.d
总结
本方案采用 持久化存储 + 一键恢复 的设计思路,在完全不依赖第三方安装脚本的前提下,实现了 UniFi OS 4.x 环境中稳定、可维护的 on_boot.d 开机启动机制。
虽然由于 UniFi OS 固件升级会重建根文件系统,无法实现真正意义上的“100% 无人工干预自动恢复”,但借助保存在 /data 分区中的恢复脚本,只需在每次大版本升级完成后执行一次:
/data/recover_boot.sh
即可在数秒内恢复 systemd 服务、开机启动以及所有 on_boot.d 脚本,兼顾了可靠性、可维护性与升级兼容性,是目前 UniFi OS 4.x 平台最稳妥、最推荐的部署方案。









