You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Go语言中从nftables nflog获取MAC地址的技术问询

问题:从Netfilter日志中获取源/目的MAC地址

我需要把Netfilter日志推送到Grafana Loki,但ulogd和promtail都满足不了格式需求,所以自己写了个小工具,工具运行正常,但现在遇到一个问题:想在输出里获取MAC(硬件)地址。

我做了几次尝试,得到这些结论:

  • 尝试解析整个数据包栈(protocols包含Ethernet、IPv4、TCP、UDP)时,用这段代码:
    p.decoder = gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, protocols...)
    
    结果只有Ethernet层被解析出来,而且内容是错误的——没有报错,但返回的地址和实际不符。
  • 如果从IP层开始解析:
    p.decoder = gopacket.NewDecodingLayerParser(layers.LayerTypeIPv4, protocols...)
    
    那么IP层及上层协议(通常是TCP、UDP或ICMP)都能被正确解析。

返回的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 02:15:29