Python scapy sniff抓包报错OSError: Error opening adapter
错误原因
- 核心触发原因是抓包操作权限不足:Scapy 调用原始套接字访问网络适配器需要高权限,Windows 下普通用户启动 Python、Linux/macOS 下非 root 用户运行脚本,都没有直接操作网卡抓包的权限,会直接抛出适配器打开失败错误。
- Windows 环境下如果没有安装 Npcap 抓包驱动,或者安装时未勾选 WinPcap 兼容模式,也会触发该错误:Scapy 本身不自带抓包驱动,依赖系统层面的 pcap 驱动实现网卡流量读取。
- 提供的代码本身存在两处逻辑错误,即使权限正常也无法正确筛选 DNS 包:
sniff()函数的filter参数仅支持 BPF 语法的字符串过滤规则,不支持传入自定义函数,传入函数会导致参数解析异常;自定义包过滤逻辑需要传给lfilter参数。- 自定义的
is_dns判断逻辑无效:"DNS Resource Record" in pkg是匹配包对象的文本输出内容,不是合法的包层级判断方式,正确的 DNS 层判断写法为DNS in pkg。
修复方案
- 先解决抓包环境问题
- Windows:安装官方版 Npcap,安装时勾选「WinPcap API 兼容模式」选项;启动脚本时右键选择「以管理员身份运行」。如果装了 Npcap 还是报错,先在 Python 中执行
from scapy.all import get_if_list; print(get_if_list())打印所有网卡名称,调用sniff()时通过iface参数指定当前联网用的物理网卡,排除 VPN、虚拟机生成的虚拟网卡干扰。 - Linux/macOS:执行脚本时加
sudo提权,例如sudo python3 dns_sniff.py,部分 Linux 发行版如果需要长期非 root 抓包,可以将当前用户加入wireshark用户组,新手直接用 sudo 提权最简便。
- Windows:安装官方版 Npcap,安装时勾选「WinPcap API 兼容模式」选项;启动脚本时右键选择「以管理员身份运行」。如果装了 Npcap 还是报错,先在 Python 中执行
- 修正代码逻辑,优先使用 BPF 过滤规则(内核态直接过滤非 DNS 流量,减少用户态处理压力),修正后的可运行代码如下:
from scapy.all import sniff from scapy.layers.dns import DNS from scapy.layers.inet import IP, UDP def print_dns_pkt(pkt): if IP in pkt and UDP in pkt and DNS in pkt: dns = pkt[DNS] if dns.qr == 0: print(f"[DNS请求] {pkt[IP].src} -> {pkt[IP].dst} 查询域名: {dns.qd.qname.decode()}") else: print(f"[DNS响应] {pkt[IP].src} -> {pkt[IP].dst} 解析域名: {dns.qd.qname.decode()}") # 需要查看完整包结构时取消注释下一行 # pkt.show() if __name__ == "__main__": # BPF规则直接过滤UDP 53端口(DNS默认端口),store=0表示不缓存包到内存,适合长时间嗅探 sniff(filter="udp port 53", prn=print_dns_pkt, store=0) # 如果要使用自定义函数过滤,替换为下面这行,不要给filter参数传函数 # sniff(lfilter=lambda x: DNS in x, prn=print_dns_pkt, store=0)
内容的提问来源于stack exchange,提问作者roee attias
相关产品推荐
相关产品推荐

