前阵子我在实验室翻出一台吃灰的树莓派 3B+,顺手把它变成了一台 TR-069 ACS 自动配置服务器,跑的是 GenieACS。这台小东西以前只用来跑点温度监控脚本,现在却管住了手头十几台光猫和无线路由器,以前逐台登录后台改配置的日子基本结束了。如果你也是做网络运维、搞设备管理平台,或者家里设备多到不想一个个记密码登后台,这篇实录应该能让你少踩一些坑。文章会从选型、软硬件准备、部署、接设备到问题排查完整过一遍,重点说清楚每个环节为什么要这么做,以及我实际踩过的坑。
1. 方案选型背后的那点事
1.1 先把 TR-069 的工作方式讲透
TR-069 的正式名称是 CWMP,是网络设备管理协议里非常常见的一种。它里面的角色就俩:CPE 和 ACS。CPE 就是光猫、路由器、家庭网关这些被管理的设备,ACS 是自动配置服务器,也就是我们这台树莓派上跑的东西。
很多人刚接触时会理解错,以为 ACS 要主动去连设备才能下发配置。实际恰恰相反,整个会话由 CPE 发起。设备上会写一个 ACS URL,设备通电或者到了周期时,主动向这个 URL 发送一个 Inform 报文,把自己型号、序列号、软件版本、IP 地址这些信息报给 ACS。ACS 收到后回一个 InformResponse,如果服务器这边有任务,就会在同一个会话里继续下发 SetParameterValues、GetParameterValues、Reboot 之类的 RPC 指令。
这个“CPE 主动上报”的设计非常关键。因为大多数光猫和路由器藏在家庭网关的 NAT 后面,ACS 根本连不进去,所以协议才设计成由设备来找服务器。你可以把 CPE 想象成每天早上来公司打卡的员工,ACS 是前台,员工不来打卡,你就没法把加班单塞给他。
1.2 为什么选 GenieACS,而不是自己造轮子
TR-069 协议里面最磨人的不是协议交互,而是数据模型和会话状态机。设备类型五花八门,每个厂商对 TR-098、TR-181 这些数据模型的支持程度都不一样。自己撸一个能响应 Inform 的接口不难,搞到真正能稳定下发参数、处理任务队列、兼容不同设备,工作量就大了。
商用 ACS 当然有,但价格不低,而且很多时候不需要那么多冗余功能。开源里我评估过几个项目,最终选 GenieACS,主要看中三点:一是还在活跃更新,遇到问题能找到人问;二是带 Web 管理界面,设备上线以后可以直接在页面上看参数;三是它有北向 API,也就是 NBI 接口,以后想接自己的工单系统、自动开通流程,都有现成的入口。
对我这种需要快速做原型验证的场景来说,GenieACS 的性价比非常高。它建立在 Node.js 上,数据库用 MongoDB,整体逻辑不复杂,部署文档也比较清楚,树莓派这种小机器完全带得动。
1.3 3B+ 跑 ACS,性能上有没有戏
树莓派 3B+ 是四核 A53 处理器,内存只有 1GB,存储走 TF 卡,这在很多人眼里算“玩具”配置。但 ACS 这个角色很有意思,它不是持续大量转发流量,而是在设备周期来报到时做少量 JSON 处理和数据库读写。真正的内存大户不是 GenieACS 本身,而是 MongoDB。
我实测过一段时间的真实环境:同时接入二十几台真实设备,Inform 间隔 300 秒左右,CPU 日常负载在 3% 到 20% 之间波动,内存占用大概 600 到 800MB,偶尔瞬时冲到 900MB。这个量级下,树莓派 3B+ 是扛得住的。如果不加干预直接跑默认配置,MongoDB 可能会吃掉太多内存,触碰 OOM 边界,所以后面我会专门说内存怎么限制。
如果你要管理几百台甚至上千台设备,那 3B+ 肯定不合适,建议还是换 x86 服务器或者至少树莓派 4B + SSD。但作为实验环境、小型工作室、家庭网络设备管理,这台吃灰小板子完全够用。
2. 部署环境的准备,别在第一步省事
2.1 硬件清单和几个容易忽略的配件
树莓派 3B+ 本身就是一块主板,但想让它 24 小时稳定跑 ACS,有几样东西别省:
- 树莓派 3B+ 主板
- TF 卡,建议 16GB 起步,首选 A1 或 U3 等级,别买杂牌
- 电源,5V / 2.5A 起的正规电源,劣质电源是随机重启的根源
- 散热片或者小风扇,长期高负载时 A53 也会热降频
- 有线网线,强烈建议不要用 WiFi 连接
我知道很多人喜欢用 WiFi 让树莓派“无线化”,但 ACS 承担的是设备管理职责,网络稳定性比美观重要得多。WiFi 受干扰时偶发丢包,设备上报失败又重试,排起错来很麻烦。直接插网线,把树莓派放在一个固定位置,IP 也固定下来,后续会省很多事。
2.2 烧一个干净的系统并固定 IP
系统我推荐用 Raspberry Pi OS Lite,不带桌面。既然这台机器是当服务用的,桌面环境纯属浪费内存。烧录工具随便选,重点是把系统写到 TF 卡之后,先在 boot 分区放一个空的ssh文件,这样开机后就能直接 SSH 连进去。
进入系统后第一件事,除了改密码,就是设置静态 IP。ACS 的 IP 地址是要填到每台 CPE 设备里的,如果树莓派从 DHCP 拿地址,哪天路由器租约一刷新,所有设备都找不到服务器了。我习惯用/etc/dhcpcd.conf配置,参考如下:
interface eth0 static ip_address=192.168.8.250/24 static routers=192.168.8.1 static domain_name_servers=192.168.8.1配置完重启网络,确认 IP 稳定。这个步骤看起来基础,但实际项目里至少有三分之一的问题是“IP 变了导致 CPE 找不到 ACS”,越基础越不能省。
2.3 Node.js 和 MongoDB 安装为什么麻烦
GenieACS 跑在 Node.js 上,数据存 MongoDB,所以这两个运行时都得装。Node.js 建议直接装 LTS 版本,注意如果你的树莓派刷的是 64 位系统,就下载 arm64 包;如果还是 32 位系统,MongoDB 新版本会比较麻烦。
我在这块踩过一个大坑:早期图省事从系统仓库直接apt install mongodb,装完发现版本很老,GenieACS 启动后连不上,日志里报了一堆 MongoDB 协议错误。后来老老实实按官方仓库装了mongodb-org才解决问题。
MongoDB 安装完成后,先别急着跑 GenieACS,确认服务已经启动:
sudo systemctl enable --now mongod mongo --eval "db.version()"能打印出版本号,再继续往下走。
3. GenieACS 核心安装与配置
3.1 安装软件和建独立用户
GenieACS 本身可以通过 npm 安装,前提是你 Node.js 环境已经就绪。安装命令大致是:
sudo npm install -g genieacs装完之后,不要直接拿 root 去跑服务。ACS 是一个长期监听端口的服务,万一 Web 面板或者北向 API 有安全漏洞,独立用户能降低一些风险。我习惯单独建一个用户:
sudo useradd --create-home --system --shell /bin/bash genieacs sudo mkdir -p /opt/genieacs sudo chown -R genieacs:genieacs /opt/genieacs然后创建配置文件/opt/genieacs/config.json。不同版本的参数名可能会有差异,建议装好后先执行genieacs --help或genieacs-acs --help确认。我这里给出一个可用的核心配置:
{ "mongo": { "uri": "mongodb://127.0.0.1:27017/genieacs" }, "acsPort": 7547, "nbiPort": 3001, "uiPort": 3000, "externalPort": 7547, "secret": "please-change-me" }三个端口的用途要分清:7547 是 ACS 与 CPE 通信的端口,必须能被设备访问到;3001 是北向 API 端口;3000 是管理 Web 界面端口。MongoDB 连接串指向本地 27017。
这里有个安全提醒:GenieACS 的 UI 默认没有强认证,如果你把它监听在0.0.0.0上,同一内网的人都能打开配置管理页。所以我建议要么在配置里指定监听地址只绑内网,要么用防火墙把 3000 端口限制来源。
3.2 写 systemd 服务,三件套都安排上
GenieACS 的部署逻辑是拆成三个服务来跑:ACS 主服务、NBI 北向 API、UI 管理界面。拆开的好处是某一端出现阻塞或崩溃,不会把整个系统带崩。我用 systemd 来管,示例 unit 文件如下:
[Unit] Description=GenieACS ACS After=network-online.target mongod.service Wants=network-online.target [Service] User=genieacs ExecStart=/usr/bin/genieacs-acs --config /opt/genieacs/config.json Restart=on-failure RestartSec=5 LimitNOFILE=65536 [Install] WantedBy=multi-user.targetNBI 和 UI 的服务文件同理,只是ExecStart分别改成genieacs-nbi和genieacs-ui。如果你的安装路径里命令名不带-acs,就用which genieacs-acs查一下,然后调整路径。
写完 unit 后依次启动:
sudo systemctl daemon-reload sudo systemctl enable --now genieacs-acs genieacs-nbi genieacs-ui看到三个服务都 active 后,再继续验证端口。
3.3 安装后的自检清单
服务都起来了不代表万事大吉,我每次部署完会按下面几步检查:
systemctl status genieacs-acs ss -lntp | grep -E '7547|3000|3001' curl http://127.0.0.1:3000ss应该能看到 7547、3000、3001 都在监听。如果 3000 端口 curl 没反应,看看防火墙是不是挡了本机回环。接着进 MongoDB 看一眼:
mongo show dbs如果genieacs这个库已经出现,说明服务初始化没问题。然后打开浏览器访问http://树莓派IP:3000,能看到管理界面,左侧没有设备是正常的,因为还没有 CPE 接入。
4. 把第一台 CPE 设备接进来
4.1 在设备上配置 ACS URL
光猫和路由器的 TR-069 设置入口藏在不同的地方。有些设备在“管理”菜单里,有些叫“网络-宽带远程管理”,还有一些叫“运维”或“OMS”。你需要填写几个关键字段:
- ACS URL:填
http://192.168.8.250:7547/ - ACS 用户名 / 密码:按 GenieACS 侧配置填写,建议起一个专用账号
- CPE 用户名 / 密码:这个是设备端用来标识自己的信息,ACS 侧会对应到设备标识
- 周期上报间隔:调试期可以先改成 60 秒,稳定后改回 300 秒或者更长
如果你用的设备是运营商定制光猫,普通用户后台里很可能看不到 TR-069 配置页。这种情况要么走正规途径申请管理员权限,要么用实验室自己的旧设备来做实验。不要用什么来路不明的破解方式搞自己的设备,风险不值得。
4.2 观察第一台设备上线过程和日志
保存设备上的配置后,正常情况下最多一分钟内,CPE 就会发起一次 Inform。如果你把周期上报设成 60 秒,等待时间会更短,甚至可以在设备管理页面找到“立即上报”按钮主动触发。
在树莓派上实时看日志,能直观感受到会话过程:
journalctl -u genieacs-acs -f我会看到类似“handling request”的日志输出,这时候再刷新 GenieACS 的 Web 界面,设备列表里应该出现一个新设备。点进去可以看到厂商、型号、序列号、WAN IP、软件版本这些自动同步的信息。
这一步有人会卡住。设备一直处于“未上线”状态的话,先别急着重装系统,重点检查两件事:一是 ACS URL 里的 IP 和端口是否写对;二是设备所在的网段能不能路由到树莓派。只要 CPE 能访问 7547,Inform 一定会过来。
4.3 真正下发一次配置:改 WiFi SSID
设备上线后,最直观的验证是下发一个真实参数。在 GenieACS 管理界面里选中设备,创建一条“设置参数”任务。下面的例子是把设备的 WiFi SSID 改成新名字:
{ "name": "setParameterValues", "parameterValues": [ ["Device.WiFi.SSID", "MyPi-Net", false] ] }如果你更习惯用 API,可以通过北向接口提交任务。命令大致长这样:
curl -H "Content-Type: application/json" \ -d '{"name":"setParameterValues","parameterValues":[["Device.WiFi.SSID","MyPi-Net",false]]}' \ http://192.168.8.250:3001/devices/<deviceId>/tasks注意,任务提交后不会立刻生效,要等 CPE 下一次 Inform 到来时才会拉取执行。想让效果更及时,去设备上手动触发一次“上报”即可。
这也解释了为什么 TR-069 适合批量管理:你不需要登录每一台设备,只需要在 ACS 里把设备分组,然后往多个设备 ID 下塞同样的任务,剩下的交给设备自己来取。以后要统一改 VLAN、改 DNS、改 WiFi 密码,都是同样的套路。
5. 踩坑与优化实录
5.1 MongoDB 内存占用是头号麻烦
树莓派 3B+ 的 1GB 内存很紧张,MongoDB 默认会倾向于多用内存做缓存,如果不管它,很容易触发 OOM。我的处理方式是在/etc/mongod.conf里限制 WiredTiger 的缓存:
storage: wiredTiger: engineConfig: cacheSizeGB: 0.25改完重启 mongod,内存占用会明显降下来。如果你后面接了更多设备,可以接着调大一点,但树莓派上 0.25GB 到 0.5GB 是比较合适的区间。
如果还出现内存不够,可以考虑把 swap 增大到 1GB。但要注意 SD 卡本身读写速度和寿命都有限,频繁的 swap 交换会加速磨损,所以这属于临时缓解手段,不是长久之计。
5.2 别让日志和数据库把 TF 卡写坏
GenieACS 的日志打到 stdout 后会被 systemd-journal 存储到磁盘,长时间运行日志量不小。我配置过 journal 大小上限,把SystemMaxUse设成 100M,避免日志无限增长。
另外数据库体积也要关注。设备不多时,mongodump定期备份一下配置和数据库很轻松:
mongodump --db genieacs --out /home/genieacs/backup如果 TF 卡本来质量一般,日志和数据库的持续写入会让系统越来越慢。我后来把 journal 日志级别调高,只记录 warn 和 error,日常输出量小了很多。有条件的话,树莓派用 SSD 启动是根治方案。
5.3 设备不上线或频繁离线的排查表
这里把我遇到过的典型问题整理成一张表,排查时可以按顺序对一下:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 设备状态一直“未上线” | ACS URL 填错、端口不通、设备在别的网段 | 在树莓派上用telnet <设备IP> 7547测连通性,或检查防火墙 |
| UI 能打开但设备列表为空 | 设备还没到 Inform 周期 | 等一个周期,或去设备上手动触发上报 |
| 设备上报成功但任务不执行 | 任务参数名不对、数据模型不存在 | 在 UI 里查设备支持的数据模型,确认参数路径正确 |
| 树莓派突然重启或卡死 | MongoDB OOM、电源不稳 | 查dmesg,限制缓存,换合格电源 |
| 日志显示访问被拒绝 | ACS 用户口令不匹配 | 检查设备上填的 ACS 用户名密码是否与配置一致 |
这些坑看起来琐碎,但实际排障时非常关键。尤其是第一条,很多人折腾了半天,最后发现是防火墙默认挡了 7547。
5.4 设备的上报周期和批量下发节奏怎么控
包换周期越短,任务下发的实时性越好,但服务器压力也越大。大量设备同时上报时,如果 CPU 被打满,整个系统都会变慢。我自己的经验是:
- 调试期:把 1 到 2 台设备的周期改成 60 到 120 秒,方便观察
- 稳定运行期:周期拉到 600 秒,甚至更长
- 大批量下发时:尽量选设备不那么活跃的时间段,避免集中冲击
TR-069 会话有一个特点:ACS 无法真正主动连接到 CPE,所以任务再紧急,也得等设备下一次上报。想缩短延迟,只能靠设备侧的“立即上报”按钮。别去依赖 Connect Request 这类可以主动连接设备的方式,因为大多数场景下设备在 NAT 后面,这条通路不一定通。
6. 这套方案的管理边界和扩展空间
6.1 我在实测里跑出来的容量边界
基于树莓派 3B+ 的实际体验,我给出的判断是:
- 20 台左右设备,周期 300 秒,非常稳定
- 50 台以内,只要内存限制做好,也能跑,但 CPU 偶尔会冲到 50% 以上
- 100 台以上,建议不要把 MongoDB 和 GenieACS 都压在同一块小板子上,最好拆开
- 500 台以上,树莓派完全不合适,该上真实服务器了
这不是说 GenieACS 不能管理更多设备,瓶颈在硬件资源。如果你只是想做实验、验证自动开通流程、管理一个办公室的设备,这套树莓派方案是很香的。
6.2 后续还能怎么玩
这台 ACS 其实可以继续做很多事。比如通过 NBI 接口,把设备注册事件推到自己的工单系统里,新装一台光猫就自动建档、自动下发默认配置。也可以把 ACS 界面接进一个统一的可视化面板,实现设备型号、固件版本、在线状态的批量查看。
网络环境允许的话,你还可以给 ACS 配 HTTPS 证书,让设备走https://上报。这样配置下发过程中不会明文暴露用户名和密码。但要注意,CPE 校验证书时需要系统时间准确,如果树莓派没有联网校时,证书校验会失败,反而造成设备连不上。
我个人体会最深的一件事是:ACS 这种服务一旦跑起来,你会越来越依赖它。现在我在实验室里调整网络参数,基本已经不从电脑上 SSH 到每台设备去改配置了,直接在 ACS 界面里开个任务,等几十秒,全自动完成。树莓派 3B+ 虽然已经不算新硬件,但在这种场景里,它依然是一个极其可靠的“小管家”。如果你也想给手头的设备“收编”统一管理,照着这篇实录一步步走,大概率能顺利完成。