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

Linux内核模块中借助Netfilter获取HTTP请求数据与主机名的方法

Linux内核模块中获取HTTP请求数据与主机名的方法

我编写了一个Linux内核模块,目标是当请求的服务器名为特定字符串时,将80端口的HTTP网络请求重定向至8000端口。本以为只需读取请求、过滤并对比服务器名即可,但实际难度远超预期,尤其是内核头文件的文档极为匮乏。

我通过如下方式注册网络钩子:

static int __init my_hook_init(void) {
    pr_info("lavawall: loaded\n");
    return nf_register_net_hook(&init_net, &my_nfho);
}

经过空值检查并获取IP地址后,我存储了端口并打印数据包的目标地址:

static unsigned int lavawall(__attribute__((unused)) void* _,
                             struct sk_buff* skb,
                             const struct nf_hook_state* state) {
//...
    port = ntohs(tcp->dest);
    printk(KERN_INFO "lavawall: %s:%d\n", request_ip_string, port);
// ...
    return NF_ACCEPT;
}

我尝试从skb结构体中读取数据字符串,但结果要么为空,要么是乱码。

我的问题很明确:

  • 如何获取HTTP请求数据?
  • 如何获取请求指向的主机名(例如my.site.com)?

核心解决思路与实现步骤

1. 正确获取HTTP请求数据

TCP是流式协议,一个完整的HTTP请求可能被拆分成多个skb数据包,且skb可能是非线性存储的,直接读取会出现空值或乱码,需按以下步骤处理:

struct tcphdr *tcp;
struct iphdr *ip;
unsigned char *data;
int data_len;

// 提取IP和TCP头部
ip = ip_hdr(skb);
tcp = tcp_hdr(skb);

// 计算TCP数据段的长度(总长度减去IP头、TCP头长度)
data_len = skb->len - (ip->ihl * 4) - (tcp->doff * 4);
if (data_len <= 0) {
    return NF_ACCEPT; // 无有效数据,直接放行
}

// 处理非线性skb:将分散的数据线性化,否则无法连续读取
if (skb_is_nonlinear(skb)) {
    if (skb_linearize(skb) != 0) {
        return NF_ACCEPT; // 线性化失败,放行
    }
    // 线性化后重新获取头部指针
    ip = ip_hdr(skb);
    tcp = tcp_hdr(skb);
}

// 定位TCP数据起始位置
data = (unsigned char *)((unsigned char *)tcp + (tcp->doff * 4));

此外,必须维护连接的状态缓存:用**五元组(源IP、源端口、目标IP、目标端口、协议)**作为键,在内核中创建哈希表,缓存每个连接的已接收数据,直到检测到HTTP请求头结束标记\r\n\r\n,再进行完整的请求解析。

2. 提取HTTP请求的主机名

HTTP请求的主机名存放在Host头字段中,拿到完整的请求头后:

  • 遍历缓存的请求头内容,匹配以Host: 开头的行(HTTP头字段不区分大小写,实际场景可兼容大小写判断)
  • 提取Host: 之后、\r\n之前的内容,即为目标主机名(若包含端口如my.site.com:80,需额外截取端口前的字符串)

关键注意事项

  • 内核内存管理:使用kmalloc/kzalloc分配缓存内存,用kfree释放,避免内存泄漏
  • 并发与性能:哈希表操作需加锁防止并发冲突,请求处理完成后及时清理连接缓存,避免内存占用过高
  • 钩子点选择:根据需求选择合适的Netfilter钩子点,如本地接收数据包选NF_INET_LOCAL_IN,转发数据包选NF_INET_FORWARD

内容的提问来源于stack exchange,提问作者MrKleeblatt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:20:28