摘要

  • 草案把生成时间、hostname、发布进程内的 32 位序号和观测时间语义装进可扩展 YANG envelope;每个字段仍只是特定模式和运行语境下的有限声明。
  • 自动化若要把 envelope 当作证据,仍须分别取得模式、认证身份、进程连续性、时钟、订阅、内容保管链、下游传输以及权威结果八类凭证。

采集器收到一个规整对象:根节点是 envelope,时间可解析,hostname 看似属于预期路由器,sequence-number 恰好接着上一条,contents 中的 YANG-Push 更新也顺利解码。所有可见指示灯都亮着绿光。

它究竟证明了什么?

2026 年 5 月 18 日的 通知封装草案第 05 版 针对一个真实缺口:RFC 5277 通知头只有必填 eventTime,也不可扩展;接收器把通知转发到消息代理或时序数据库后,原传输上下文可能消失。草案因此用可复用的 YANG 结构承载元数据与载荷,并支持 XML、JSON 和 CBOR。

Datatracker 页面 将它列为拟走 Proposed Standard 路径、等待工作组主席推进的 NETCONF 工作组活跃 Internet-Draft。它还不是 RFC。它的价值正在于把更多声明变得机器可读;操作纪律则是,不让声明越过自身证据边界。

结构只对形状负责

启用后,新头部用根 envelope 包住通知:event-time 必填;hostname 与 sequence-number 是可选扩展;contents 是承载通知载荷的 anydata。RFC 8791 提供 YANG structure 机制,RFC 7951 与 RFC 9254 分别补足 JSON 与 CBOR 编码规则。

模式检查可以证明节点、类型、命名空间和序列化符合被加载的模式,却不能证明模式清单就是预期版本,也不能默认 contents 内部已被完整验证,更不能证明字段值符合现实。Datatracker 在 2026 年 9 月 10 日显示 4 个 YANG 错误、2 个警告;历史中的 shepherd 记录则描述过更早一次 yanglint、pyang 无错误的检查,并明确说示例验证没有深入与该文档无关的 anydata 内容。二者日期和范围不同,都不是部署实现或运行正确性的证明。

所以第一张凭证必须写清:模块版本、feature、编码、命名空间或 SID、验证器版本、加载的模式集合,以及验证是否进入 contents。只说“封装通过验证”并不完整。

hostname 不能认证自己

草案把 hostname 描述为发布消息的网络节点,并称其在网络内唯一。YANG 描述同时透露了关键事实:这个值通常由管理员配置。它是受治理命名域里的好标签,却不是自证身份的凭据。

安全章节把两者明确分开:NETCONF 或 RESTCONF 应使用安全传输与双向认证,访问控制应限制敏感配置和通知;暴露 hostname 还可能帮助攻击者绘制网络或注入伪造通知。从未认证路径收到 edge-17.example,只能证明某个发送者提供了这串字符。

身份凭证要把认证传输对端或签名密钥、证书与密钥周期、设备、发布进程、命名权威和订阅授权绑在一起。RFC 8341 也指出,授权会过滤或丢弃通知内容。认证说明谁控制某个凭据,却不自动说明该进程有权发布此订阅,或接收者看到了全部预期字段。

连续序号只属于一个进程周期

可选 sequence-number 是 counter32:从 1 开始,每发布一条通知加一,到 4294967295 后回卷至 0,以 0 显示回卷。只要发布进程周期稳定且已被观察,缺口或逆序就是有用的断裂证据。

真正困难的是“发布进程”四字。草案没有给这个计数器定义持久 epoch,也没有规定重启后的延续方式。采集器若从 914 才开始观察,看不到此前遗漏;替代进程可在相同 hostname 下重置或恢复计数;relay 可能重排、复制或丢消息;计数器还会自然回卷。只有把计数值同认证进程、启动周期、接收器起点、初始值、回卷判断、转发路径和下游持久化回执绑定,连续性才可审计。

“没有序号缺口”因此只意味着:在声明的身份与进程周期中,观察者保留的区间内没有看到缺口。它不等于“什么都没有丢”。

三类时间回答不同问题

envelope 的 event-time 是事件生成时间;草案进一步解释为 YANG-Push 消息被制作并发出的时刻。observation 扩展另加 timestamp,表示周期指标被测量或 on-change 状态变化被观察的时刻;point-in-time 再区分 current-accounting、initial-state 和 state-changed。

这解决了真实的时序误判:周期轮询可能发生在时间桶边界前,而消息构造发生在边界后;若用生成时间索引,就可能一个桶零条、下个桶两条。观测时间提供了更好的对齐点。

但它依然只是某个时钟给出的时间戳。RFC 6991 定义 date-and-time 表示,甚至允许用 -00:00 表示未知时区。能解析并不证明 NTP/PTP 锁定、UTC 可追溯、偏移有界、闰秒处理正确或时间单调。事件时间、观测时间、订阅 anchor-time、到达时间和持久化时间应分别保留,同时附上时钟源和不确定度;否则小数秒精度只会给失同步的钟表增加虚假权威。

capability 是声明,不是实例回执

RFC 9196 允许发布者在实现期或运行期暴露能力。第 05 版为 envelope、hostname/sequence-number 元数据与 observation time 增加能力标志,便于客户端合理协商。

能力为 true 只说明“支持”。它没有证明全局开关当前已启用,也没有证明某条通知里实际出现了可选字段、字段值正确,或所有接收器和中间环节都能保留它。支持、配置、实例发出、下游保真,是四种不同状态。

这个差异还带来运维后果:envelope 开关是 server-wide;启用或关闭时,所有现存动态与配置订阅都必须终止,并用旧头部先发 subscription-terminated。同一网络可能同时存在新旧格式。迁移凭证必须记录开关事务、被终止订阅、接收器兼容性和新订阅周期;能力发现不能证明切换期间没有盲区。

contents 继承订阅条件

RFC 8639 把事件交付同过滤器、接收者、权限和订阅生命周期绑定;RFC 8641 区分周期与 on-change YANG-Push、数据存储、选择过滤器、anchor-time、dampening 和同步行为。push-update 的“完整”只是在该订阅条件下的完整;push-change-update 还可能在 dampening 周期内合并中间变化。

envelope 没有复述整份订阅契约。subscription ID 只是查询键,不证明查询到的配置就是生成时的预期版本。过滤器、datastore、权限、触发方式或 receiver binding 改变时,hostname 与序号仍可平滑连续,消息含义却已改变。应为每个进程周期保存有效订阅与授权语境的密码学指纹,并保留改变它的生命周期事件。

RFC 8342 给出最后一道语义边界:intended、running 与 operational state 不能互换。发布者可以准确序列化某个 datastore 视图,却仍未证明转发行为、服务影响或用户结果。语法不会把通知抬升为权威事实。

下游保管链需要内容身份

基础草案说 contents 原样承载通知值,但没有内容签名。安全的 NETCONF 或 RESTCONF 能保护一段连接;接收器一旦解码、重编码、转发、聚合或存储,该连接的保证不会自动附着在载荷上继续流转。

另一份仍在演进的 YANG provenance 草案 正好展示 envelope 可扩展性的价值:它提议为 contents 精确计算 COSE 签名,并让能力树暴露签名支持。同时它也写明边界:签名保护签名时刻的来源和完整性,却不保证新鲜度、合法签名者提供的数据正确、私钥未泄露、每个中间步骤都签过名,或 key ID 已可靠映射到数据权威。

因此 provenance 仍是一张有限凭证。应保留内容摘要、规范化与序列化方法、签名者和密钥政策、验签结果、新鲜度材料、每次变换和 countersignature,然后另行验证被签名的观测是否真实。

八类凭证,互不借用确定性

可靠结论需要八张回执:模式及验证范围;认证身份;进程连续性;时钟源与不确定度;订阅和授权语境;精确内容身份与签名范围;传输及下游保管链;权威 datastore 与独立运行结果。

envelope 让这些回执更容易命名和携带,这是实质进步。错误在于让一个字段借走另一个字段的权威:让 hostname 借认证、计数器借持久历史、时间戳借时钟同步、capability 借实例存在,或让有效字节借运行事实。