如何用 Moby 的 Wireshark 插件解析 NetworkDB 的 memberlist 组播与加密消息
2026/9/9 21:47:37 网站建设 项目流程

如何用 Moby 的 Wireshark 插件解析 NetworkDB 的 memberlist 组播与加密消息

【免费下载链接】mobyThe Moby Project - a collaborative project for the container ecosystem to assemble container-based systems项目地址: https://gitcode.com/GitHub_Trending/mo/moby

当你在排查 Moby(moby)集群网络问题时,NetworkDB 是 overlay 网络在节点之间同步状态(endpoint 记录、peer 信息)的 gossip 层。它的消息通过 memberlist 协议在 TCP/UDP 端口上传输,加密时抓包只能看到密文。Moby 仓库自带两个 Wireshark Lua 插件(memberlist.lua 与 moby-networkdb.lua),可以把抓到的 memberlist 报文解析成协议字段,并把 user data 消息进一步解析为 NetworkDB gossip 的 protobuf 结构,配合密钥文件还能解开加密消息。完成本文后,你在 Wireshark 中打开抓包,就能按协议树查看 ping、alive、push/pull 等 memberlist 消息类型以及 NetworkDB 的 TableEvent、NetworkEvent 等具体载荷。

以下依据 contrib/wireshark/README.md 及插件源码整理,适用于 Wireshark 4.5 或更新版本。

准备条件:Wireshark 版本与插件文件

README 明确要求Wireshark 4.5 或更新版本:4.4 的 msgpack 协议解析器不完整,无法正确解码 memberlist 消息。文档指出 2025-06-30 时 4.5 尚未正式发布,可能需要使用官方 nightly build,请按 Wireshark 官方下载渠道获取。

插件文件位于当前仓库的 contrib/wireshark/ 目录,无需从别处下载:

  • memberlist.lua:注册名为memberlist的协议,解析 memberlist 的 TCP/UDP 报文;
  • moby-networkdb.lua:注册名为networkdbgossip的协议,解析 NetworkDB gossip 消息。由于 NetworkDB 的节点间通信以 memberlist user message 形式承载,必须先让 memberlist 解析器调用networkdbgossip子解析器。

按 Wireshark 的 Lua 插件手册把这两个文件配置为启动加载(放入对应 Lua 插件目录或在luacpath/插件配置中指定路径),使 Wireshark 或 Tshark 能加载memberlist.luamoby-networkdb.lua

配置 ProtoBuf 协议加载 NetworkDB 的 IDL

NetworkDB 消息序列化为 protobuf,而 protobuf 不是自描述格式,必须向 Wireshark 的 ProtoBuf 协议提供消息的 IDL 定义才能解析。README 给出的操作是:

  1. 克隆 moby/moby 仓库(提供 NetworkDB 的 IDL 定义);
  2. 克隆 protocolbuffers/protobuf 仓库(提供 protobuf "标准库" IDL);
  3. 在 Wireshark 中配置 ProtoBuf 协议(Preferences -> Protocols -> ProtoBuf):
    • 勾选 "Load .proto files on startup"(protobuf.reload_protos);
    • 勾选 "Dissect Protobuf fields as Wireshark fields"(protobuf.pbf_as_hf);
    • 向 Protobuf Search Paths 表(uat:protobuf.search_paths)添加条目:
path/to/protocolbuffers/protobuf/src path/to/moby/moby/vendor path/to/moby/moby path/to/moby/moby/libnetwork/networkdb (Load all files) path/to/moby/moby/libnetwork/drivers/overlay (Load all files)

其中path/to/...替换为你实际克隆出的两个仓库根目录。README 特别强调:只把.proto文件拷出来是不够的,必须保留目录结构,否则定义无法正确加载。

注意:本文所用仓库中,这两个目录对应的.proto文件当前实际位于 daemon/libnetwork/networkdb/networkdb.proto 和 daemon/libnetwork/drivers/overlay/overlay.proto,即libnetwork已移到daemon/之下。如果你以当前源码布局克隆仓库,应把上面后两条搜索路径指向实际存在.proto的目录,保证 protobuf 解析器能找到networkdboverlay包的定义。

配置 memberlist 协议解析 NetworkDB 用户消息

在 Preferences -> Protocols -> MEMBERLIST 中:

  • User Data Dissectormemberlist.userdata_dissector)设置为networkdbgossip,使 memberlist 的 User 消息体交给 NetworkDB gossip 解析器处理;
  • 可选:设置Memberlist TCP+UDP port(s)memberlist.ports)。插件默认端口为 7946(见 memberlist.lua 中的default_settings);README 给出的示例值是7946,10000-10999,用于分析 NetworkDB 单元测试的抓包。按你实际网络环境的 memberlist 端口调整。

解析加密消息:配置密钥文件

memberlist 加密消息的解密依赖一份包含对称密钥的文件。文档说明的完整链路是:

  1. 让 dockerd 把 NetworkDB 加密密钥写入日志文件:设置环境变量NETWORKDBKEYLOGFILE为期望的文件路径。实现见 daemon/libnetwork/networkdb/debug.go:logEncKeys以追加方式把每把密钥编码为十六进制字符串写入该文件,每行一把密钥,文件权限0o600;密钥在SetKey和集群初始化(config.Keys)时分别写入(见 cluster.go)。该环境变量未设置时直接返回,不写文件,因此要在启动 dockerd 之前设置好;
  2. 在 Wireshark 中指向该文件:Preferences -> Protocols -> MEMBERLIST,把Encryption Key Logfile Pathmemberlist.keylog)设为第 1 步生成的文件。文件内容就是十六进制密钥、以换行分隔——恰好与 dockerd 写出的格式一致。

插件侧的解密逻辑同样在 memberlist.lua:对 UDP 报文尝试try_decrypt,按行读取密钥逐一以 AES-GCM 解密并校验 AEAD tag,命中后在协议树中标记 "Encrypted Memberlist" 并展开解密内容。

验证解析结果与处理首次启动报错

打开抓包后按以下现象判断配置是否生效(以下协议名与消息类型来自两个 Lua 插件的源码定义):

  • memberlist 报文在协议列显示为 "Memberlist Protocol, Type: ...",message_type字段取值为PingAliveSuspectDeadPushPullEncryptUser等(memberlist.lua 中的message_type_enum);
  • User 消息的载荷被networkdbgossip协议展开为networkdb.GossipMessagetype字段再决定具体消息:1=NetworkEvent、2=TableEvent、3=NetworkPushPull、4=BulkSyncMessage、5=CompoundMessage、6=NodeEvent(moby-networkdb.lua 中的msgtype_map);TableEvent 还会按表名二次解析:overlay_peer_table对应overlay.PeerRecordendpoint_table对应libnetwork.EndpointRecord
  • 配置了密钥文件后,加密消息(加密版本 1)应展开为 "Encrypted Memberlist" 子树并显示解密内容。

一个文档明确记录的已知问题:Wireshark 首次启动时 NetworkDB 插件可能加载失败并报错:

moby-networkdb.lua:4: bad argument #1 to 'new' (Field_new: a field with this name must exist)

这是 Wireshark 侧的已知缺陷。解决办法是在 Wireshark 完成初始化后重载 Lua 插件:菜单 Analyze -> Reload Lua Plugins,或快捷键 Ctrl-Shift-L(Windows/Linux)、⇧⌘L(macOS)。重载后协议应正常注册。

限制

README 的 Limitations 一节明确列出了两点,排查前先对照:

  • 仅支持 memberlist 加密版本 1(AES-GCM 128,无 padding),不支持版本 0(AES-GCM 128 使用 PKCS#7 padding);
  • 带 label 的消息目前无法解密(memberlist.lua 中对加密版本不为 1 的报文直接跳过解密)。

如果你的抓包中出现未解密或解析失败的消息,先确认是否落在以上两种情况内,再回到密钥文件内容(是否包含该消息对应的密钥)与端口范围(memberlist.ports是否覆盖实际通信端口)检查。

【免费下载链接】mobyThe Moby Project - a collaborative project for the container ecosystem to assemble container-based systems项目地址: https://gitcode.com/GitHub_Trending/mo/moby

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询