空中的 htop — 一个在终端中实时显示的 802.11 (Wi-Fi) 射频仪表盘。
airtop 将你周围的 Wi-Fi 流量变为一个实时终端仪表盘 — 显示附近接入点的频谱、每个站点的信号轨迹、帧类型活动信息、RSSI 直方图以及已发现网络的滚动列表,所有这些都通过 eBPF 和盲文/块图形绘制。
[!TIP] 无需监控模式,无需原始套接字。 airtop 将 eBPF 程序附加到
mac80211/cfg80211,在内核 Wi-Fi 栈中读取 802.11 帧,因此它在你的正常已连接接口上运行,不会断开你的链路。
curl -fsSL https://yeet.cx | sh
yeet run https://github.com/yeet-src/airtop
要生成可共享的截图,可匿名化 SSID 和 MAC(你的网络和邻居的网络会被重命名为 network-01、station-02……):
yeet run https://github.com/yeet-src/airtop -- --anonymize
运行直到按 Ctrl-C 退出。调整终端大小,布局会重新流动;最小尺寸为 80×24。
要发现相邻网络,内核需要扫描结果。你的操作系统会定期自行扫描,或者你也可以手动触发一次:
nmcli dev wifi rescan # 或: iw dev <iface> scan
Wi-Fi 是 IEEE 802.11 系列标准。其思维模型是:
一切都是帧。 你的笔记本电脑、手机和路由器会交换称为帧的短无线电数据包。每个帧都包含 MAC 地址,其中一个(BSSID)标识了它所属的接入点。
三种帧类型:
| 类型 | 示例 | 目的 |
|---|---|---|
| 管理帧 | Beacon、Probe、Auth、Assoc、Deauth | 通告、加入和离开网络 |
| 控制帧 | ACK、RTS/CTS | 协调谁可以发送数据 |
| 数据帧 | 你的实际流量 | 承载有效载荷 |
接入点发送信标。 接入点大约每秒 10 次发送信标帧,其中包含其网络名称 (SSID) 和 BSSID。这就是你手机上的 Wi-Fi 列表是如何填充的,也是 airtop 发现接入点的方式。
信道与频率。 Wi-Fi 工作在频段(2.4 GHz、5 GHz、6 GHz),每个频段被划分为多个信道,每个信道对应一个中心频率(以 MHz 为单位)(信道 6 ≈ 2437 MHz,信道 161 ≈ 5805 MHz)。一台无线电一次只能监听一个信道,这就是为什么你主要看到自己信道上的流量。
信号强度 (RSSI) 以 dBm 为单位测量。值总是负数,越接近零越强:
| RSSI | 质量 |
|---|---|
| −30 … −50 dBm | 极好(就在旁边) |
| −50 … −67 dBm | 良好 |
| −67 … −80 dBm | 可用 |
| −80 … −90 dBm | 弱 / 边缘 |
主要是家庭用户调试不稳定的 Wi-Fi,以及网络管理员在活动前选择信道。
每个面板都对应上述概念:
头部 — 运行时间、总帧数、实时站点、已发现 AP、信标计数、deauth 计数(如果非零则显示为红色)以及你当前的信道。Deauth 计数器是需要关注的;健康网络应为零。
频谱 — 每个已发现的 AP 显示为一个信号“驼峰”,位于其在 MHz 轴上的实际中心频率处。高度和颜色表示 RSSI;标签为 SSID + dBm。重叠的驼峰揭示同信道拥堵 — 经典的 Wi-Fi 分析器视图,也是“为什么我的 Wi-Fi 很慢”的答案。
RSSI × 时间 — 每个实时站点的盲文折线图,绘制过去几秒钟的信号。观看当设备远离 AP 时链路的衰减,或当某人移动笔记本电脑时信号的跳变。
帧活动信息 — 随时间变化的帧类型热力图;单元格颜色表示每段时间内到达的该类型帧的数量。deauth 洪水会立即点亮该行,这是你真正想要的警报模式。
信号直方图 — 按 RSSI 分布的接收帧。你的射频环境的“形状”:在 −50 dBm 处出现尖锐峰值意味着你靠近一个强 AP,而在 −60 到 −80 范围内的散布则意味着环境拥挤。
接入点 — 已发现的 SSID,包含信道、信号指示器和 dBm,按信号强度降序排列。
一个 BPF 对象 (airtop.bpf.c) 附加了两个 fentry 程序,并通过环形缓冲区将事件流传输到用户空间:
| 钩子 | 捕获内容 |
|---|---|
fentry/ieee80211_rx_list | 每个收到的 802.11 帧:类型/子类型、地址、来自 ieee80211_rx_status 的 RSSI |
fentry/cfg80211_inform_bss_frame_data | 内核扫描发现的每个 AP:SSID、信道、信号 |
仪表盘运行在 yeet 的 V8 运行时中,订阅这些环形缓冲区并渲染终端 UI:
main.js 入口:终端大小、渲染循环、BPF 绑定/订阅
state.js 实时数据 + 帧/扫描摄入
render.js ANSI、颜色渐变、盲文画布/图表(纯函数)
dashboard.js 面板 + 布局(renderDashboard)
[!IMPORTANT] 需要支持 BTF 的 Linux:
CONFIG_DEBUG_INFO_BTF=y和CONFIG_DEBUG_INFO_BTF_MODULES=y。当前的 Arch、Fedora、Ubuntu 和 Debian 12+ 默认已启用。CO-RE 意味着无需为每个内核重新编译。
cfg80211/mac80211 栈的 Wi-Fi 接口(任何 Linux 上的普通 Wi-Fi 卡)。curl -fsSL https://yeet.cx | sh 即可安装。[!NOTE] airtop 做不到的事情:
tx_status 钩子。fentry 目标在实践中很稳定,但它们并非内核 ABI;具体数据取决于你的 Wi-Fi 驱动程序。这需要监控模式吗? 不需要。这正是它的亮点。airtop 从内部钩入内核的 Wi-Fi 栈,因此它在你正常的已连接接口上运行。
它会断开我的连接吗? 不会。不会切换模式;你的接口会保持与之前的关联状态。airtop 只是观察内核已经在做的事情。
为什么我只看到一个或两个网络?
因为你的无线电大部分时间只监听一个信道(它自己的信道)。相邻网络会在你的操作系统进行定期扫描时出现,或者当你手动触发扫描时,例如使用 nmcli dev wifi rescan / iw dev <iface> scan。全频段调查需要监控模式 + 信道跳变,那是另一种工具。
这合法吗? 在大多数司法管辖区,被动观察你周围的 802.11 帧是合法的;你的无线电已经在接收它们,airtop 只是显示它们的存在。主动干扰(deauth 面板检测攻击,而不是执行攻击)则是另一回事。如果你在企业网络,请检查你的可接受使用政策。
这与 Kismet、airodump-ng 或 Wireshark 有什么不同? 这些工具通过监控模式做更多事情:完整的逐帧捕获、PCAP 导出、解密。airtop 在你的正常接口上运行,并提供一个一目了然的仪表盘。用于渗透测试,请使用 airodump-ng。要找出通话中断的原因,请使用这个。
make # 生成 include/vmlinux.h,构建 bin/airtop.bpf.o
make vmlinux # 强制刷新内核类型头文件
make clean
需要 clang(BPF 目标)和 bpftool;以及你的发行版提供的 libbpf / libbpf-dev 头文件。生成的 include/vmlinux.h 和 bin/ 已被 gitignore。
动图由 VHS 根据 assets/airtop.tape 制作:
vhs assets/airtop.tape # -> assets/airtop.gif
它会在画面外启动 airtop,这样动图打开时就直接显示实时仪表盘。在录制时,可以在另一个 shell 中启动 Wi-Fi 扫描,以填充频谱和 AP 列表。
BPF 程序使用 GPL 许可证(SEC("license") = "GPL"),这是它所使用的内核帮助函数的要求。
由 yeet 构建。yeet 是一个用于编写 eBPF 程序和实时系统仪表盘的 Linux 运行时,支持 JavaScript。