摘要

  • RFC 5381 记录了用 WSDL、XML Schema 和 Apache Axis 生成 NETCONF/SOAP 客户端桩与服务器骨架的实践,生成物降低了开发摩擦,但没有补全设备功能和治理规则。
  • 实现把 NETCONF 会话标识同时写入 XML 元素与 HTTP cookie,形成可自洽的私有配对;RFC 明确说明它不能与遵循 RFC 4743 的实现互通。

一个方法名遮住了多少层

在生成后的 Java API 里,get-config 或 edit-config 可以表现为一个普通方法。开发者无需手写 SOAP 信封,也不必逐项拼接 XML。这个抽象确实减少了机械劳动。

但方法返回时,究竟完成了什么?它可能只证明本地桩代码序列化成功;也可能证明 HTTPS 连接完成、SOAP 被解析、NETCONF RPC 被接收。再往后还有能力协商、会话归属、访问控制、目标 datastore、验证或提交、设备实现以及网络行为观察。任何一层都不能借用后一层的结论。

RFC 5381 的价值,在于它把这个链条以真实工程部件呈现出来。NMS 是客户端,网络设备是服务器。Axis 从 WSDL 生成 Java 类;服务器端则得到需要继续填充的骨架。在资源受限的设备上,HTTP daemon、SOAP 模块和 NETCONF 服务提供者甚至可能是三个清晰分开的组件。

抽象越顺滑,责任边界越容易消失。

生成器只是编译了一个输入

RFC 描述的 WSDL2Java 会生成 NetconfBindingStub.java、Hello.java、GetConfigType.java 等文件。服务器端也从同一描述生成 skeleton。因为两端拥有同一套类型与消息结构,它们很容易通过彼此的测试。

然而,netconf-soap_1.0.wsdl 本身并不完整:它缺少 service 元素,需要另一个 WSDL 提供端点。设备功能的数据模型也要单独用 XML Schema 描述,再与 NETCONF 操作属性连接。服务器骨架只是模板,真正的配置逻辑仍需人工加入。

所以,生成成功的准确含义是:某个版本的工具根据某组输入产生了某些文件。编译成功的准确含义是:这些文件满足编程语言和依赖关系。部署成功的准确含义是:容器能够装载它们。若把三张回执合并成“网络管理服务已完成”,组织就把尚未发生的授权与结果提前宣布了。

代码生成没有消除决定,只是把一些决定移到了输入文件、生成参数、运行库和手写扩展中。越看不见,越需要版本和证据。

cookie 接管了标准没有交给它的权力

NETCONF 需要维持会话。RFC 4743 在 HTTP 场景中把会话状态绑在持续的传输连接上。RFC 5381 的实现面对 HTTP 服务器常见的无状态处理方式,选择把会话标识写进 cookie。设备在 hello 回复中分配标识,NMS 保存它,并在后续 XML 和 HTTP 头中重复。close-session 后再删除。

这套方法对成对实现很方便,却改变了会话事实的来源。连接变了但 cookie 没变,会话是否还在?负载均衡把同一 cookie 送到另一个进程,谁拥有状态?XML 中的标识与 cookie 不同,哪一个优先?RFC 5381 没有把私有选择包装成标准行为;它直接指出,这个替代绑定不能与符合 RFC 4743 的实现互通。

这也是自动化最危险的成功方式:同一个生成体系可以让两端共同继承偏差。测试全部通过,不是因为实现遵循公共合同,而是因为双方犯了同一种错。

因此,会话日志不能只写一个数字。它至少要关联传输连接、TLS 身份、cookie 来源、NETCONF session-id、能力集合、RPC message-id 和关闭事件。否则,“会话存在”只是跨层复制的一段文本。

可访问的骨架仍然只是骨架

RFC 5381 比较了 top-down 与 bottom-up 开发。前者先定义 WSDL,再生成服务器骨架;接口先于实现,因此更有利于多厂商互通。后者先写代码,再从代码生成 WSDL,速度更快,却容易把厂商特有结构固化为接口。

即使走 top-down,部署也不等于完成。Axis/Tomcat 可以报告服务已上线,骨架类可以回应请求,真正的 NETCONF 功能却仍需加入。端口打开只证明 listener。HTTP 200 只证明 Web 层。SOAP 正确只证明信封层。rpc-reply 也必须结合操作结果、授权决定与 datastore 回执解读。

设备侧的 C 路径更能说明问题:HTTP daemon 收到消息,SOAP 模块剥去信封,NETCONF 提供者解析内容并配置设备。若设备内存不足,解析器甚至可以只处理 SOAP 必选部分。每一次“简化”都需要说明保留了什么语义、放弃了什么扩展、由谁承担兼容风险。

TLS 保护通道,不分配管理权

RFC 5381 沿用 RFC 4741 和 RFC 4743 的安全要求,并要求 SOAP 绑定使用 TLS 提供认证与加密,即 NETCONF/SOAP/HTTPS。

这能证明通信通道受保护,也能为对端身份提供证据。它不能自动授权某个主体执行 edit-config,不能决定 cookie 与连接谁拥有会话,也不能证明目标 datastore 已提交,更不能证明转发行为已经改变。

IESG 注记还指出:当时仅支持 SOAP 而不至少支持 SSH 的 NETCONF 实现并不符合整体标准要求。一个安全、可达、能够交换消息的 SOAP 端点,依然可能缺少标准要求的另一块能力。

安全控制也必须写清作用域。证书不是配置授权书,加密回执不是设备结果回执。

历史状态改变后,本地事实仍需盘点

后来,RFC 6241 更新了 NETCONF 基础,RFC 6242 规定了新的 SSH 映射。RFC 9900 又把 RFC 4743 与 RFC 4744 设为 Historic,并释放相应端口,但保留历史服务名。

公开登记的变化不会自动删除私网中的 WSDL、生成类、旧镜像、cookie 逻辑或防火墙对象。BTW 已有 RFC 9900 文章负责“登记释放不等于本地退役”这一主题。本篇关注另一条边界:即使旧系统仍能互相通信,也必须证明它们遵循的是哪一份会话合同。

Heng Lu 关于 running code 的要求在这里尤其具体。WSDL 是声明,生成器是转换器,运行库是执行环境,cookie 规则是本地政策,NETCONF 服务是管理权力,设备状态才是结果。把它们缩成一个“API”字段,会让最重要的差异消失。

来源