0%

linux_netfilter

关于netfilter

netfilter的介绍:

PS: 关于netfilter属于内核中的哪一层,或者内核软件结构解析:
看下载下来的内核代码:可以看到netfilter相关的头文件在:/linux-lts-xenial-4.4.0/include/linux/netfilter/目录中
而看实际实现文件在 /net/netfilter中,也就是说它属于linux的网络部分代码中的一个软件库;和ipv4并列,而ipv4/中包含了ip,tcp等网络的实现;
所以netfilter在linux源码的地位可想而知;

再来思考下linux源代码:其实是一个大的软件库,而linux系统就是调用了里面的各种函数,运行起来的一个大软件;
对linux源代码的使用,可以编写linux内核相关的代码,而通过以模块的形式载入内核,就可以影响内核的行为;
内核软件架构本身是分部分分层的,实际上比如netfilter是可以被其他各个部分的代码引用使用,但是设计是需要考虑分层隔离概念,不然会做到耦合太强;

netfilter的4个表和5个链的概念

netfilter的使用例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <linux/module.h>    // included for all kernel modules
#include <linux/kernel.h> // included for KERN_INFO
#include <linux/init.h> // included for __init and __exit macros
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("geeksword");
MODULE_DESCRIPTION("A Simple Hello Packet Module");

enum { NF_IP_PRE_ROUTING,
NF_IP_LOCAL_IN,
NF_IP_FORWARD,
NF_IP_LOCAL_OUT,
NF_IP_POST_ROUTING,
NF_IP_NUMHOOKS };

static struct nf_hook_ops in_nfho; //net filter hook option struct
static struct nf_hook_ops out_nfho; //net filter hook option struct

static void dump_addr(unsigned char *iphdr)
{
int i;
for(i=0; i<4; i++){
printk("%d.", *(iphdr+12+i));
}
printk(" -> ");
for(i=0; i<4; i++){
printk("%d.", *(iphdr+16+i));
}
printk("\n");
}

unsigned int my_hook(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
printk("Hello packet! ");
//printk("from %s to %s\n", in->name, out->name);
unsigned char *iphdr = skb_network_header(skb);
if(iphdr){
dump_addr(iphdr);
}
return NF_ACCEPT;
// return NF_DROP;//会导致上不了网
}

static int init_filter_if(void)
{
//NF_IP_PRE_ROUTING hook
in_nfho.hook = my_hook;
in_nfho.hooknum = NF_IP_LOCAL_IN;
in_nfho.pf = PF_INET;
in_nfho.priority = NF_IP_PRI_FIRST;

nf_register_hook(&in_nfho);

//NF_IP_LOCAL_OUT hook
out_nfho.hook = my_hook;
out_nfho.hooknum = NF_IP_LOCAL_OUT;
out_nfho.pf = PF_INET;
out_nfho.priority = NF_IP_PRI_FIRST;

nf_register_hook(&out_nfho);
return 0;
}

static int hello_init(void)
{
printk(KERN_INFO "[+] Register Hello_Packet module!\n");
init_filter_if();
return 0; // Non-zero return means that the module couldn't be loaded.
}

static void hello_exit(void)
{
nf_unregister_hook(&in_nfho);
nf_unregister_hook(&out_nfho);
printk(KERN_INFO "Cleaning up Helllo_Packet module.\n");
}

module_init(hello_init);
module_exit(hello_exit);

编译:
obj-m += hello.o
obj-m += hello-packet.o
#obj-m += rootkit.o
obj-m += rickroll.o
obj-m += excited_virus.o
obj-m += task2file.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

接着make
sudo insmod hello-packet.ko
dmesg | tail 可以看到输出的日志
sudo rmmod hello-packet

关于linux下如何下载编译linux源代码,使用源代码创建模块,加载卸载模块等内容,专门一个文章记录;