C 用于过滤NFS请求的内核模块
我正在开发一个概念验证内核模块,根据一些标准(客户端IP地址、执行的操作类型等)过滤NFS请求 我使用了中描述的黑客方法,但无法在该方法中检索客户端IP地址 我目前的想法是使用一个Netfilter钩子来拦截网络数据包,解析它们以识别操作并在那里应用过滤 他是我所说的例子。。它适用于内核版本4.15.0C 用于过滤NFS请求的内核模块,c,linux-kernel,kernel-module,nfs,C,Linux Kernel,Kernel Module,Nfs,我正在开发一个概念验证内核模块,根据一些标准(客户端IP地址、执行的操作类型等)过滤NFS请求 我使用了中描述的黑客方法,但无法在该方法中检索客户端IP地址 我目前的想法是使用一个Netfilter钩子来拦截网络数据包,解析它们以识别操作并在那里应用过滤 他是我所说的例子。。它适用于内核版本4.15.0 #include <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h&g
#include <linux/kernel.h> /* We're doing kernel work */
#include <linux/module.h> /* Specifically, a module, */
#include <linux/moduleparam.h> /* which will have params */
#include <linux/unistd.h> /* The list of system calls */
#include <linux/dirent.h>
#include <linux/cred.h>
#include <linux/syscalls.h>
#include <linux/init.h>
#include <linux/netfilter.h>
#include <linux/ip.h>
#include <linux/tcp.h>
static struct nf_hook_ops nfin;
static unsigned int hook_func_in(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct ethhdr *eth;
struct iphdr *ip_header;
struct tcphdr *tcph;
char *data;
eth = eth_hdr(skb);
ip_header = ip_hdr(skb);
tcph = tcp_hdr(skb);
data = (char *)((unsigned char *)tcph + (tcph->doff * 4));
/* Skip if it's not TCP packet */
if (ip_header->protocol != IPPROTO_TCP)
return NF_ACCEPT;
printk("src mac %pM --- src IP addr:%pI4 --- protocol: %u\n", eth->h_source, &ip_header->saddr, ip_header->protocol);
printk("TCP source : %hu, TCP dest : %hu\n", ntohs(tcph->source), ntohs(tcph->dest));
// Parse data pointer here..
return NF_ACCEPT;
}
int init_module()
{
nfin.hook = hook_func_in;
nfin.hooknum = NF_INET_LOCAL_IN;
nfin.pf = PF_INET;
nfin.priority = 0;
nf_register_net_hook(&init_net, &nfin);
return 0;
}
void cleanup_module()
{
nf_unregister_net_hook(&init_net, &nfin);
}
#include/*我们正在做内核工作*/
#包括/*特别是模块*/
#包括/*其中将包含参数*/
#包括/*系统调用列表*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态结构nf_hook_ops nfin;
静态无符号整数hook\u func\u in(void*priv,
结构sk_buff*skb,
const struct nf_hook_state*状态)
{
结构ethhdr*eth;
结构iphdr*ip_头;
结构tcphdr*tcph;
字符*数据;
eth=eth_hdr(skb);
ip_头=ip_hdr(skb);
tcph=tcp_hdr(skb);
数据=(字符*)((无符号字符*)tcph+(tcph->doff*4));
/*如果不是TCP数据包,则跳过*/
如果(ip_头->协议!=IPPROTO_TCP)
返回NF_接受;
printk(“src mac%pM---src IP addr:%pI4---protocol:%u\n”,eth->h\u source,&IP\u header->saddr,IP\u header->protocol);
printk(“TCP源:%hu,TCP目标:%hu\n”,ntohs(tcph->source),ntohs(tcph->dest));
//在此解析数据指针。。
返回NF_接受;
}
int init_模块()
{
nfin.hook=hook\u func\u in;
nfin.hooknum=NF_INET_LOCAL_IN;
nfin.pf=pf_INET;
nfin.priority=0;
nf\u寄存器\u网络\u钩子(&init\u网络,&nfin);
返回0;
}
void cleanup_模块()
{
nf_注销网络钩子(&init_网络,&nfin);
}
如何解析数据指针以识别我正在处理的请求类型?或者如何解析来自sk_buff对象的RPC请求
这是执行此任务的正确方法吗?“如何解析”、“如何解析”-太宽泛了。具体点。Linux内核中有大量NFS代码。顺便说一句,在尝试访问TCP头之前,如果(ip_头->协议!=IPPROTO_TCP)执行
更合适。这就是我想问的,是否有一些函数可以调用,将sk_buff解析为某个RPC/NFS对象?或者我应该自己解析它?如果是这样,我该怎么做?(我可以使用什么资源等)谢谢你的提示。穆罕默德,试着为你的内核安装SystemTap(是RHEL、CentOS、Debian还是Ubuntu?什么是unaa-a
output?)。系统选项卡上有nfsdtop stap脚本,它可以访问一些内部nfs指针——nfsdtop.stp脚本收集并显示nfs查找,\stap nfsd\u unlink.stp-c“sleep 0.2”
。另一个变体是修补内核源代码并使用跟踪工具它的UbuntuLinux Ubuntu VirtualBox 4.15.0-20-generic\21 Ubuntu SMP周二4月24日06:16:15 UTC 2018 x86\u 64 x86\u 64 GNU/Linux
。我会查看SystemTap并让您知道。