关闭 RG-MA3063 内置 DHCP

AIGC

今天收到了 PVE 备份失败的提醒,原因是无法访问 Synology 的 SMB 挂载。检查发现是 Synology 服务器的 IP 地址变到了子路由 DHCP 分配的另一个网段。想起来前两天收到了 Synology 发过来的关于禁用转发规则的邮件:

由于默认网关设置已更改,端口转发规则功能已禁用。请检查网络设置。

应该就是那个时候,主路由因意外断电重启,导致了子路由 DHCP 激活。

这次我把整个 firmware 拖下来,直接让 GPT 5.6 进行分析


主因不是 rg_mng,而是:

lan4 DHCP 租约失效 / 接口下线

/bin/rjd 收到 network.interface 事件

判定进入 island(孤岛)状态

/lib/librjdal.so
  rjdal_island_ctrl()

/sbin/switch_network enterisland

dhcp.lan.ignore=0
dhcp.lan.interface=mgt
uci commit dhcp
dnsmasq restart

关键文件:

  • /bin/rjd
  • /lib/librjdal.so
  • /sbin/switch_network
  • /etc/init.d/rjd
  • /etc/init.d/rg_mng

IDA 确认 /bin/rjdisland_event_hdl0x4864)监听 netifd 的 network.interface 事件:

  • 只在非 router 模式启用。
  • 关注 lan4*,这里的 lan4 正是桥接模式下向上级路由申请 DHCP 的接口。
  • lan4 ifup 表示退出孤岛。
  • lan4 下线,或 /var/rj_waninfo 中没有 lan4=up,表示进入孤岛。
  • 最终调用 rjdal_island_ctrl()

进入孤岛后,switch_network 执行:

  • 第 690–691 行:dhcp.lan.ignore=0dhcp.lan.interface=mgt
  • 第 696–697 行:提交 DHCP 配置并重启 dnsmasq
  • 第 931–935 行:暴露 enterislandexitisland 两个入口

由于 mgt192.168.10.1/24,dnsmasq 使用 start=100limit=150,所以客户端会拿到 192.168.10.x

上级 DHCP 恢复、lan4 ifup 后,它会反向设置:

dhcp.lan.ignore=1
dhcp.lan.interface=lan

rjd 不只是自动 DHCP,主要还负责:

  • AutoWAN:探测活动端口、DHCP/PPPoE、默认网关及上联口切换。
  • 监听 network.interfacenetwork.restartnetwork.workmode 等事件。
  • 网络变化时执行 LAN/端口复位、PHY 断电重上电。
  • 协调无线重启及部分 ACL/客户端恢复。
  • 处理 mesh controller/agent 角色,并更新 dnsmasq 的设备角色标志。
  • 孤岛检测及临时管理网 DHCP。

所以它不是毫无价值。固定桥接环境中很多功能可能用不上,但直接禁用会同时失去上联口探测、网络恢复、mesh 角色和端口复位逻辑。

推荐只关闭孤岛功能,不要禁用整个 rjd。因此最简单只需要:

uci set nvram.info.island_enable='0'
uci commit nvram

我先修改观察试试

定位 RG-MA3063 中谁设置的 114.114.114.114

AIGC

真正写入者是厂商修改过的 /sbin/netifd

IDA 中的调用链:

  • interface_write_resolv_conf()0x99a0
  • DNS 写入函数:0x7c78
  • 硬编码追加位置:0x7d70–0x7d84

逻辑是:

接口实际只提供一个 IPv4 DNS

先写这个上游 DNS

netifd 自动追加 114.114.114.114

IPv6 的对应硬编码备用地址是 240C::6666

现场证据也完全吻合:

  • ubus call network.interface.lan4 status 只报告一个 IPv4 DNS:192.168.9.1
  • /tmp/resolv.conf.auto 却包含:
nameserver 192.168.9.1
nameserver 114.114.114.114

所以 114.114.114.114 不是上级 DHCP 下发的,而是 netifd 在只有一个 IPv4 DNS 时主动补上的。修改 dnsmasq 的 noresolv 不能阻止 netifd 把它写进文件。

结论是在不 patch netifd 的前提下,避免访问 114 DNS 的方法是,让 DHCP 下发两个自己可控的 DNS。

清理 PVE 挂载的 SMB 每 10 秒一条的访问日志

层级,日志,时间,用户,事件
信息,连接,2026/08/06 15:29:14,enihsyou,User [enihsyou] from [PVE(2409:8a1e:6950:9510::90d1)] via [CIFS(SMB3)] accessed shared folder [pve].
信息,连接,2026/08/06 15:29:04,enihsyou,User [enihsyou] from [PVE(2409:8a1e:6950:9510::90d1)] via [CIFS(SMB3)] accessed shared folder [pve].
信息,连接,2026/08/06 15:28:54,enihsyou,User [enihsyou] from [PVE(2409:8a1e:6950:9510::90d1)] via [CIFS(SMB3)] accessed shared folder [pve].

PVE 的 pvestatd 大约每 10 秒查询一次已配置存储的可用性、容量等状态。对通过 PVE“数据中心 → 存储”添加的 CIFS 存储,这个检查可能会建立一次 SMB 连接并访问共享目录,所以 Synology 将它记录成:accessed shared folder [pve]

解决方法就是换成 NFS,根据 有关 NFS 的常见问题 - Synology 知识中心 设置很快的。

清理 PVE 中 failed protocol match 的 apparmor DENIED 日志

AIGC

每隔 4 分钟,每张网卡产生 3 次 failed protocol match 的 apparmor DENIED 日志。

8月 06 15:07:22 pve kernel: audit: type=1400 audit(1786000042.519:119962): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=32110 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none
8月 06 15:08:22 pve kernel: audit: type=1400 audit(1786000102.983:119965): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=1100 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none
 
8月 06 15:11:33 pve kernel: audit: type=1400 audit(1786000293.928:119973): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=32110 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none
8月 06 15:12:44 pve kernel: audit: type=1400 audit(1786000364.398:119974): apparmor="DENIED" operation="create" class="net" info="failed protocol match" error=-13 profile="/{,usr/}sbin/dhclient" pid=1100 comm="dhclient" family="unix" sock_type="dgram" protocol=0 requested="create" denied="create" addr=none

早在 PVE 主机依赖虚拟机作 DHCP 导致主机无法启动 的日志中就有见过,当时正常工作就没当回事,这次翻日志,看到量非常大就想清理

GPT 5.6 给出的原因是 Debian 提供的 dhclient profile 是一个没有显式 Feature ABI 声明的旧式 profile:

#include <tunables/global>

/{,usr/}sbin/dhclient {
    ...
}

它缺少 abi <abi/3.0>, 在当前默认编译环境下,dhclient profile 被编译为对 Unix-domain socket 执行新的网络协议匹配;但旧 profile 没有对应的细粒度 Unix socket 规则,于是创建:
AF_UNIX + SOCK_DGRAM 时出现 info="failed protocol match" error=-13

用简单的 Python 脚本复现问题

aa-exec -p '/{,usr/}sbin/dhclient' -- \
  python3 -c \
  'import socket; socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM); print("OK")'

异常时会提示 PermissionError: [Errno 13] Permission denied

然后运行修复命令:

apparmor_parser \
  --skip-cache \
  --policy-features=/etc/apparmor.d/abi/3.0 \
  --replace \
  /etc/apparmor.d/usr.sbin.dhclient

如果重新验证后提示 OK,说明有效果