在Go语言中从nftables nflog获取MAC地址的技术问询
问题:从Netfilter日志中获取源/目的MAC地址
我需要把Netfilter日志推送到Grafana Loki,但ulogd和promtail都满足不了格式需求,所以自己写了个小工具,工具运行正常,但现在遇到一个问题:想在输出里获取MAC(硬件)地址。
我做了几次尝试,得到这些结论:
- 尝试解析整个数据包栈(protocols包含Ethernet、IPv4、TCP、UDP)时,用这段代码:
结果只有Ethernet层被解析出来,而且内容是错误的——没有报错,但返回的地址和实际不符。p.decoder = gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, protocols...) - 如果从IP层开始解析:
那么IP层及上层协议(通常是TCP、UDP或ICMP)都能被正确解析。p.decoder = gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, protocols...)
返回的Attributes里有个HwAddr字段,是一串字节,看起来确实是源MAC地址,但我需要分别获取源和目的MAC地址。
ulogd可以获取这些信息,它会返回三个字段:
- MAC:12字节字符串,依次是目的MAC和源MAC
- mac.saddr.str字段
- mac.daddr.str字段
ulogd的逻辑太复杂,我没法追踪它获取这些信息的来源,但它能拿到数据让我之前误以为:即使规则是针对IPv4或IPv6的,Netfilter也会传递以太网层的数据。
我的核心问题是:怎么结合gopacket和nflog获取链路层头部?我原本觉得gopacket应该能解析,但nflog返回的"Ethernet"消息和gopacket期望的格式不兼容,有没有人成功实现过两者结合?
更新:为了验证思路,我转储了Netlink套接字返回的原始负载,示例如下:
[ 69 0 0 52 197 128 64 0 127 6 65 221 192 168 1 134 129 21 x y
这是Netlink返回的attribute.Payload字段,能明显看到这只是IP头部——也就是说我之前在解析一个不存在的头部。解码后内容如下:
version=69 tos=0 length=52,1 id=97,128 offset+flags=64,0 ttl=127 proto=6 hdr_checksum=65,221 src=192 168 1 134 dst=129 21 x y
所以现在我确定以太网层数据并不存在,这也解释了为什么之前无法解析它。
内容的提问来源于stack exchange,提问作者wz2b
相关产品推荐
相关产品推荐

