一、linux内核中neitfilter的处理过程
1.5个HOOK点的执行点说明:
数据包从进入系统,进行IP校验以后,首先经过第一个HOOK函数NF_IP_PRE_ROUTING进行处理;
然后就进入FORWARD路由匹配,其决定该数据报是需要转发还是发给本机的;
若该数据包是发给本机的,则该数据经过HOOK函数NF_IP_LOCAL_IN处理以后然后传递给上层协议;
若该数据报应该被转发则它被NF_IP_FORWARD处理;
经过转发的数据报经过最后一个HOOK函数NF_IP_POST_ROUTING处理以后,再传输到网络上。
本地产生的数据经过HOOK函数NF_IP_LOCAL_OUT 处理后,进行路由选择处理,然后经过NF_IP_POST_ROUTING处理后发送出去。
2.nf_hooks结构:
3.协议头字段
#include <linux/netfilter.h>
#include <limits.h>
#define NFC_IP_SRC 0x0001
#define NFC_IP_DST 0x0002
#define NFC_IP_IF_IN 0x0004
#define NFC_IP_IF_OUT 0x0008
#define NFC_IP_TOS 0x0010
#define NFC_IP_PROTO 0x0020
#define NFC_IP_OPTIONS 0x0040
#define NFC_IP_FRAG 0x0080
#define NFC_IP_TCPFLAGS 0x0100
#define NFC_IP_SRC_PT 0x0200
#define NFC_IP_DST_PT 0x0400
#define NFC_IP_PROTO_UNKNOWN 0x2000
二、源码解析:
1.通过源码make编译,生成simple_nf_test.ko,加载进内核使用;
2.使用rmmod卸载模块,将内核计算数据保存进user file;
3.使用od -tu /root/netfilter.log查看保存的file数据。
#Makefile
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
obj-m += simple_nf_test.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
[root@test02 netfilter-test]
[root@test02 netfilter-test]
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
^C
--- 114.114.114.114 ping statistics ---
64 packets transmitted, 0 received, 100% packet loss, time 64552ms
[root@test02 netfilter-test]
[22038.705777] ----------------------------------------------------------
[22038.705779] 114.114.114.114 is denied by netfilter!
[22038.705780] drop 114.114.114.114 packets count is : 20
[22039.575591] ----------------------------------------------------------
[22039.575602]
[22039.575607]
[22039.575609] ----------------------------------------------------------
[22039.575611] ...packet pass filter...
[22039.575613] [simple_nf_test] packet_filter. end.
[22039.729706] ----------------------------------------------------------
[22039.729762]
[22039.729767]
[22039.729770] ----------------------------------------------------------
[22039.729772] 114.114.114.114 is denied by netfilter!
[22039.729774] drop 114.114.114.114 packets count is : 21
[22040.753807] ----------------------------------------------------------
[22040.753822]
[22040.753826]
[22040.753829] ----------------------------------------------------------
[22040.753830] 114.114.114.114 is denied by netfilter!
[22040.753832] drop 114.114.114.114 packets count is : 22
...
[22088.630236] ----------------------------------------------------------
[22088.630237] ...packet pass filter...
[22088.630239] [simple_nf_test] packet_filter. end.
[22089.055705] ----------------------------------------------------------
[22089.055722]
[22089.055727]
[22089.055729] ----------------------------------------------------------
[22089.055731] ...packet pass filter...
[22089.055733] [simple_nf_test] packet_filter. end.
[22089.060209] packet fillter capture count: 64
[22089.060212] begin to write to netfilter.log
[22089.060258] record file write done .
[22089.060470] [simple_nf_test] remove hook lkm success!
[root@test02 netfilter-test]
0000000 64 0
0000010
#simple_nf_test.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
unsigned long int count = 0L;
static int _fileWrite(unsigned long int count)
{
unsigned long int buf[]= { count };
printk("packet fillter capture count: %ld \n",count);
struct file *fp;
mm_segment_t fs;
loff_t pos;
printk("begin to write to netfilter.log \n");
fp =filp_open("/root/netfilter.log",O_RDWR|O_CREAT,0644);
if (IS_ERR(fp)){
printk("open file error\n");
return -1;
}
fs =get_fs();
set_fs(KERNEL_DS);
pos =0;
kernel_write(fp,buf, sizeof(buf), &pos);
filp_close(fp,NULL);
set_fs(fs);
return 0;
}
unsigned int packet_filter(unsigned int hooknum, struct sk_buff *skb,const struct net_device *in, const struct net_device *out,int (*okfn)(struct sk_buff *))
{
struct iphdr *iph;
struct tcphdr *tcph;
struct udphdr *udph;
if(skb == NULL)
return NF_ACCEPT;
iph = ip_hdr(skb);
if(iph == NULL)
return NF_ACCEPT;
printk("----------------------------------------------------------");
printk("# source address is %x , %pI4 \n",iph->saddr,&iph->saddr);
printk("# dest address is %x , %pI4 \n",iph->daddr,&iph->daddr);
printk("----------------------------------------------------------");
if(iph->saddr == 0x72727272){
printk("114.114.114.114 is denied by netfilter!\n");
count++;
printk("drop 114.114.114.114 packets count is : %ld \n",count);
return NF_DROP;
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5
#define NF_MAX_VERDICT NF_STOP
*/
}
printk("...packet pass filter...");
switch(iph->protocol)
{
case IPPROTO_TCP:
tcph = (struct tcphdr *)(skb->data + (iph->ihl * 4));
break;
case IPPROTO_UDP:
udph = (struct udphdr *)(skb->data + (iph->ihl * 4));
break;
default :
return NF_ACCEPT;
}
printk("[simple_nf_test] %s. end.\n", __func__);
return NF_ACCEPT;
};
nf_hookfn *hook;
struct net_device *dev;
void *priv;
u_int8_t pf;
unsigned int hooknum;
int priority;
};
*/
static struct nf_hook_ops packet_simple_nf_opt = {
.hook = (nf_hookfn *)packet_filter,
.pf = NFPROTO_INET,
.hooknum = NF_INET_PRE_ROUTING,
.priority = NF_IP_PRI_FIRST,
};
static int simple_nf_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
nf_register_net_hook(&init_net, &packet_simple_nf_opt);
#else
nf_register_hook(&packet_simple_nf_opt);
#endif
printk("[simple_nf_test] network hooks success.\n");
return 0;
};
static void simple_nf_exit(void)
{
_fileWrite(count);
printk("record file write done.\n");
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,3,0)
nf_unregister_net_hook(&init_net, &packet_simple_nf_opt);
#else
nf_unregister_hook(&packet_simple_nf_opt);
#endif
printk("[simple_nf_test] remove hook lkm success!\n");
};
module_init(simple_nf_init);
module_exit(simple_nf_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jeb");
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)