Skip to content

errorcode7/usb_filter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

USB Filter - Linux 内核模块

License: GPL DKMS Kernel

一个提供 USB 设备过滤功能的 Linux 内核模块,支持 UEFI 变量持久化。该模块允许您通过厂商 ID (VID) 和产品 ID (PID) 黑名单机制来阻止特定的 USB 设备。

🚀 功能特性

  • USB 设备阻止:通过 VID:PID 禁用 USB 设备
  • UEFI 持久化:将黑名单存储在 UEFI 变量中,实现重启后持久化
  • Sysfs 接口:通过 /sys/kernel/usb_filter/ 提供用户友好的接口
  • DKMS 支持:内核更新时自动重新构建内核模块
  • 跨架构支持:支持 x86_64、ARM64 和 ARM32 架构
  • 内核兼容性:支持 Linux 内核 6.6+(已测试至 6.16)

📋 系统要求

  • Linux 内核 6.6 或更高版本
  • 支持 EFI 变量的 UEFI 固件
  • DKMS(动态内核模块支持)
  • GCC 编译器和内核头文件

🛠️ 安装

方法一:Debian 包(推荐)

# 构建 DKMS 包
dpkg-buildpackage -us -uc

# 安装包
sudo dpkg -i ../usb-filter-dkms_0.1.0_all.deb

# 模块将通过 DKMS 自动构建和安装

方法二:手动安装

# 克隆仓库
git clone <repository-url>
cd usb

# 构建模块
make

# 加载模块
sudo insmod usb_filter.ko

# 或带参数加载
sudo insmod usb_filter.ko blacklist="0781:5591,0a12:0001" use_efi=1

📖 使用方法

Sysfs 接口

模块在 /sys/kernel/usb_filter/ 提供 sysfs 接口,包含以下属性:

查看当前黑名单

cat /sys/kernel/usb_filter/list
# 输出:0781:5591,0a12:0001

添加设备到黑名单

# 添加单个设备
echo "0781:5591" | sudo tee /sys/kernel/usb_filter/add

# 添加多个设备
echo "0781:5591,0a12:0001,1234:5678" | sudo tee /sys/kernel/usb_filter/add

从黑名单移除设备

# 移除单个设备
echo "0781:5591" | sudo tee /sys/kernel/usb_filter/remove

# 移除多个设备
echo "0781:5591,0a12:0001" | sudo tee /sys/kernel/usb_filter/remove

清空整个黑名单

echo "1" | sudo tee /sys/kernel/usb_filter/clear

启用/禁用过滤

# 查看当前状态
cat /sys/kernel/usb_filter/enable
# 输出:1(启用)或 0(禁用)

# 禁用过滤
echo "0" | sudo tee /sys/kernel/usb_filter/enable

# 启用过滤
echo "1" | sudo tee /sys/kernel/usb_filter/enable

模块参数

您也可以使用内核参数配置模块:

# 带初始黑名单加载
sudo insmod usb_filter.ko blacklist="0781:5591,0a12:0001"

# 禁用 UEFI 持久化
sudo insmod usb_filter.ko use_efi=0

可用参数:

  • blacklist:逗号分隔的十六进制 VID:PID 条目(例如:"0781:5591,0a12:0001")
  • use_efi:启用 UEFI 变量持久化(默认:true)

🏗️ 架构

模块分为以下几个组件:

src/
├── main.c              # 主模块入口点和 kprobe 处理器
├── hook.c              # 设备过滤逻辑
├── include/
│   ├── usb_filter.h    # 公共 API 定义
│   └── pt_regs_compat.h # 跨架构兼容性
├── core/
│   ├── list.c          # 黑名单管理
│   └── api.c           # 导出的 API 包装器
├── storage/
│   └── efi.c           # UEFI 变量持久化
├── iface/
│   └── sysfs.c         # Sysfs 接口
└── parse/
    └── parse.c         # 字符串解析工具

核心组件

  1. Kprobe 拦截:使用 kprobes 拦截 usb_device_match 调用
  2. 设备过滤:在设备匹配期间检查 USB 设备是否在黑名单中
  3. UEFI 持久化:将黑名单存储在 UEFI 变量中实现持久化
  4. Sysfs 接口:为黑名单管理提供用户空间接口

🔧 技术细节

Kprobe 实现

模块使用 kprobes 拦截 USB 设备匹配函数 usb_device_match ,而不修改内核结构:

// 获取usb_device_match符号
static struct kprobe usb_match_kp = {
    .symbol_name = "usb_device_match",
};
usb_match_kp.post_handler = usb_match_post_handler;
// 后置处理器:如果设备应该被阻止则修改返回值
static void usb_match_post_handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags)
{
    int original_ret = (int)PT_REGS_RET(regs);
    if (usb_filter_enabled && device_filter(current_dev, current_drv)) {
        PT_REGS_SET_RET(regs, 0); // 阻止设备
    }
}

通过阻止设备和驱动匹配,可实现设备功能无法正常工作,同时设备本身可以用lsusb看到。

流程说明:

  1. 设备插入:USB设备插入时,USB子系统开始设备枚举过程
  2. 设备匹配:系统调用usb_device_match函数来匹配设备和驱动
  3. Kprobe拦截:我们的模块通过kprobe拦截这个函数调用
  4. 原始执行:让原始的usb_device_match函数正常执行
  5. 结果检查:Post-handler检查过滤状态和设备黑名单
  6. 返回值修改:如果设备在黑名单中,将返回值改为0(匹配失败)
  7. 最终结果
    • 匹配成功:设备加载驱动,正常工作
    • 匹配失败:设备可见但无驱动,功能被禁用

UEFI 变量存储

黑名单存储在自定义 UEFI 变量中:

  • 变量名UsbFilterBlacklist
  • GUID:自定义 GUID,避免与系统变量冲突
  • 格式:逗号分隔的 VID:PID 对(例如:"0781:5591,0a12:0001")

跨架构支持

模块包含不同架构的兼容性头文件:

  • x86_64
  • ARM64 (AArch64)
  • ARM32
  • 通用后备方案

🐛 故障排除

模块加载问题

# 检查模块是否成功加载
lsmod | grep usb_filter

# 检查内核消息
dmesg | grep usb_filter

# 检查错误
sudo modprobe usb_filter

UEFI 变量问题

# 检查 UEFI 变量是否可访问
ls /sys/firmware/efi/efivars/

# 检查 EFI 变量挂载
mount | grep efivarfs

# 检查安全启动状态
mokutil --sb-state

调试

通过增加内核详细程度启用调试消息:

# 增加内核日志级别
echo 8 | sudo tee /proc/sys/kernel/printk

# 或使用动态调试
echo 'module usb_filter +p' | sudo tee /sys/kernel/debug/dynamic_debug/control

📝 使用示例

阻止 USB 闪存驱动器

# 查找设备的 VID:PID
lsusb
# 输出:Bus 001 Device 002: ID 0781:5591 SanDisk Corp. Ultra

# 添加到黑名单
echo "0781:5591" | sudo tee /sys/kernel/usb_filter/add

# 验证
cat /sys/kernel/usb_filter/list
# 输出:0781:5591

阻止多个设备

# 添加多个设备
echo "0781:5591,0a12:0001,1234:5678" | sudo tee /sys/kernel/usb_filter/add

# 检查黑名单
cat /sys/kernel/usb_filter/list
# 输出:0781:5591,0a12:0001,1234:5678

临时禁用

# 临时禁用过滤
echo "0" | sudo tee /sys/kernel/usb_filter/enable

# 重新启用
echo "1" | sudo tee /sys/kernel/usb_filter/enable

🔒 安全考虑

  • 修改黑名单需要 root 权限
  • UEFI 变量受固件安全策略保护
  • 模块使用 kprobes,需要适当的内核权限
  • 自定义 GUID 防止与系统 EFI 变量冲突,这里有个坑,UEFI全局GUID,可以在efivar文件系统内看到,但是没有权限写,私有GUID可以写但是无法被看到。

📄 许可证

本项目采用 GPL-2.0 许可证 - 查看 LICENSE 文件了解详情。

🙏 致谢

  • Linux 内核社区提供 kprobe 基础设施
  • UEFI 论坛提供 EFI 变量规范
  • DKMS 项目提供动态内核模块支持

注意:此模块会修改内核行为,应谨慎使用。在生产系统部署前,请始终在安全环境中进行测试。

About

一个提供 USB 设备过滤功能的 Linux 内核模块,支持 UEFI 变量持久化。

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published