如何用 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.lua和moby-networkdb.lua。
配置 ProtoBuf 协议加载 NetworkDB 的 IDL
NetworkDB 消息序列化为 protobuf,而 protobuf 不是自描述格式,必须向 Wireshark 的 ProtoBuf 协议提供消息的 IDL 定义才能解析。README 给出的操作是:
- 克隆 moby/moby 仓库(提供 NetworkDB 的 IDL 定义);
- 克隆 protocolbuffers/protobuf 仓库(提供 protobuf "标准库" IDL);
- 在 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)添加条目:
- 勾选 "Load .proto files on startup"(
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 解析器能找到networkdb与overlay包的定义。
配置 memberlist 协议解析 NetworkDB 用户消息
在 Preferences -> Protocols -> MEMBERLIST 中:
- 把User Data Dissector(
memberlist.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 加密消息的解密依赖一份包含对称密钥的文件。文档说明的完整链路是:
- 让 dockerd 把 NetworkDB 加密密钥写入日志文件:设置环境变量
NETWORKDBKEYLOGFILE为期望的文件路径。实现见 daemon/libnetwork/networkdb/debug.go:logEncKeys以追加方式把每把密钥编码为十六进制字符串写入该文件,每行一把密钥,文件权限0o600;密钥在SetKey和集群初始化(config.Keys)时分别写入(见 cluster.go)。该环境变量未设置时直接返回,不写文件,因此要在启动 dockerd 之前设置好; - 在 Wireshark 中指向该文件:Preferences -> Protocols -> MEMBERLIST,把Encryption Key Logfile Path(
memberlist.keylog)设为第 1 步生成的文件。文件内容就是十六进制密钥、以换行分隔——恰好与 dockerd 写出的格式一致。
插件侧的解密逻辑同样在 memberlist.lua:对 UDP 报文尝试try_decrypt,按行读取密钥逐一以 AES-GCM 解密并校验 AEAD tag,命中后在协议树中标记 "Encrypted Memberlist" 并展开解密内容。
验证解析结果与处理首次启动报错
打开抓包后按以下现象判断配置是否生效(以下协议名与消息类型来自两个 Lua 插件的源码定义):
- memberlist 报文在协议列显示为 "Memberlist Protocol, Type: ...",
message_type字段取值为Ping、Alive、Suspect、Dead、PushPull、Encrypt、User等(memberlist.lua 中的message_type_enum); - User 消息的载荷被
networkdbgossip协议展开为networkdb.GossipMessage,type字段再决定具体消息:1=NetworkEvent、2=TableEvent、3=NetworkPushPull、4=BulkSyncMessage、5=CompoundMessage、6=NodeEvent(moby-networkdb.lua 中的msgtype_map);TableEvent 还会按表名二次解析:overlay_peer_table对应overlay.PeerRecord,endpoint_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),仅供参考