我正在编写一个内核模块,通过使用网络过滤器来阻止对特定网站的访问,并且它运行良好。我已经为NF_INET_PRE_ROUTING注册了挂钩,可以检查请求是否是http请求并且是否发出了ip地址请求。从这里开始,我想扩展我的模块的功能,使得对特定网站的请求被重定向到另一个网站。我正在考虑重写iphdr struct的saddr属性。这是可行的方法吗?我试图重写saddr属性,但请求没有被重定向。 Wget刚刚停止响应。
这是我的代码片段 -
// This code is inside hook function
__be32 test = ntohl(0xCC4FC5C8);
ip_header = (struct iphdr *)skb_network_header(skb);
ip_header->saddr = test;
return NF_ACCEPT;
内核版本 - 3.19 UBuntu
答案 0 :(得分:1)
我不认为可以使用netfilter重定向tcp请求。如果我没记错的话,只有包含有效负载的数据包才能通过netfilter框架,但三次握手中的同步等数据包将由接口卡处理和响应。这样做的原因可能是表现。
因此,您的程序可能会发生的情况是,带有http请求的数据包实际上会重定向到test
,但不会重定向到syns,这意味着您的客户端和{{1之间甚至没有设置tcp连接}}。我建议使用wireshark来检查是否所有数据包都被重定向到test
。
也许您可以尝试代理服务器,而不是在内核模块中完成所有操作。
如果我错了,请务必纠正我。
答案 1 :(得分:1)
我实际上正在处理与此类似的事情,但是在用户空间。
您可能需要做的是嗅探数据包,直到您获得带GET
标头的初始Host
请求。如果它与您要重定向到其他位置的主机相匹配,请使用302 Redirect
响应伪造来自Web服务器的响应。您可能仍需要跟踪连接本身以处理FIN等等。
祝你好运!
答案 2 :(得分:1)
你的方法很健全,而你几乎就在那里。
首先,根据@ruofan的建议,您需要确保更新重定向数据包的ip头校验和。您可能还必须根据您正在执行的操作更新其TCP标头校验和。
此外,如果您想将针对一个网站的流量重定向到另一个网站,则应该编辑ip标头的daddr
字段,而不是其saddr
字段。请注意,您稍后可能需要更改应用程序的响应数据包的saddr
ip头字段,以便正确处理它们。
最后但同样重要的是,请记住,您应该从注册到NF_INET_PRE_ROUTING
的钩子和注册到NF_INET_POST_ROUTING
的钩子中的源相关字段修改与目标相关的字段。