【转】Netfilter机制

转自http://ycnian.org/blog/archives/628

Netfilter是Linux内核网络子系统中的一个模块,这个模块可以拦截系统中的报文进行处理。Linux系统中的防火墙iptables就是构建在netfilter模块之上的。报文在一台Linux主机中的流通过程如下图所示:

假设一台Linux主机的eth0端口接收到了一个报文,Linux主机首先会查找路由表,判断这个报文的目的地址是否是自己。如果是自己,那么就逐层剥掉报文头,然后提交给应用程序处理。如果目的地址不是自己,那么通过查找路由表可以确定将报文从哪个网口转发出去。除了接收报文外,Linux主机还会主动向外发送报文。发送报文前也需要查找路由表,确定发送报文的网口。

Netfilter在报文流通的路径中设置了5个处理点,位置如上图所示。在这5个处理点,netfilter会截获经过的每个报文,调用一系列函数进行处理。我们可以在这些处理点增加自己的处理函数,从而实现特定功能。这5个处理点分别是:
NF_INET_PRE_ROUTING(位置1):可以截获接收的所有报文,包括目的地址是自己的报文和需要转发的报文。
NF_INET_LOCAL_IN(位置2):可以截获目的地址是自己的报文。
NF_INET_FORWARD(位置3):可以截获所有转发的报文。
NF_INET_LOCAL_OUT(位置4):可以截获自身发出的所有问题。
NF_INET_POST_ROUTING(位置5):可以截获发送的所有报文,包括自身发出的报文和转发的报文。

Netfilter模块对报文的处理结果可能如下:
#define NF_DROP 0 // 丢弃该报文,不再继续传输
#define NF_ACCEPT 1 // 继续正常传输报文
#define NF_STOLEN 2 //Netfilter 模块接管该报文,不再继续传输
#define NF_QUEUE 3 // 对该数据报进行排队,通常用于将数据报提交给用户空间进程处理
#define NF_REPEAT 4 // 再次调用该钩子函数
#define NF_STOP 5 // 继续正常传输报文
其中NF_ACCEPT和NF_STOP都表示报文通过了检查,可以正常向下流通,但是NF_STOP效果强于NF_ACCEPT。在每个处理点可以注册多个钩子函数,这些钩子函数按照优先级排列。优先级高的钩子函数先处理报文,优先级低的报文后处理报文。NF_ACCEPT表示报文通过了某个钩子函数的处理,下一个钩子函数可以接着处理了。而NF_STOP表示报文通过了某个钩子函数的处理,后面的钩子函数你们就不要处理了,谁让你的优先级低呢,我就可以替你做主。假设NF_INET_LOCAL_IN中注册了两个钩子函数hook1和hook2,hook1的优先级高于hook2,hook2设定的处理结果是NF_DROP。如果hook1设定的处理结果是NF_ACCEPT,那么报文就不会递交给应用程序,因为hook2会把报文丢弃掉。如果hook1设定的处理结果是NF_STOP,那么报文就会提交给应用程序,因为hook1放行了,根本不会给hook2处理的机会。

Netfilter中,一个钩子函数的数据结构如下:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

typedef unsigned int nf_hookfn(const struct nf_hook_ops *ops,

                struct sk_buff *skb, // 正在处理的报文

                const struct net_device *in, // 输入设备

                const struct net_device *out, // 输出设备

                int (*okfn)(struct sk_buff *)) // 如果通过了检查,就调用这个函数。

struct nf_hook_ops {

        struct list_head list;  // 同一个处理点的所有钩子函数链接在一条链表中

        nf_hookfn       *hook;  // 这是钩子函数

        struct module   *owner; // 模块

        void            *priv;  // 私有指针

        u_int8_t        pf;     // 协议族

        unsigned int    hooknum;// 钩子函数起作用的时间点

        int             priority;// 钩子函数的优先级,数值越小优先级越高.

};

在nf_hookfn()中,我们不需要关心okfn(),因为一般情况下不会用到这个参数。我们可以编写自己的hook函数,然后调用nf_register_hook()将hook函数注册到netfilter模块,这样我们就可以截获每个报文进行处理了。下面是一个例子,这个例子向NF_INET_LOCAL_IN注册了hook函数,如果接收到192.168.7.121发送的报文就打印一条信息“receive message from 192.168.7.121”,然后放行。

?


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

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/netfilter.h>

#include <linux/skbuff.h>

MODULE_AUTHOR("Yanchuan Nian");

MODULE_LICENSE("GPL");

static char target[4];

static unsigned int nftest_fn(const struct nf_hook_ops *ops,

        struct sk_buff *skb,

        const struct net_device *in,

        const struct net_device *out,

        int (*okfn)(struct sk_buff *))

{

    int res;

    char    saddr[4];

    int offset;

    offset = skb_network_offset(skb);

    offset += 12;

    res = skb_copy_bits(skb, offset, saddr, 4);

    if (res < 0) {

        return NF_ACCEPT;

    }

    res = memcmp(saddr, target, 4);

    if (!res)

        printk(KERN_INFO"receive message from 192.168.7.121\n");

    return NF_ACCEPT;

}

static struct nf_hook_ops nf_test_ops = {

    .hook = nftest_fn,

    .owner = THIS_MODULE,

    .pf = NFPROTO_IPV4,

    .hooknum = NF_INET_LOCAL_IN,

    .priority = 0,

};

static int __init nftest_init(void)

{

    int res;

    target[0] = 192; target[1] = 168;

    target[2] = 7; target[3] = 121;

    res = nf_register_hook(&nf_test_ops);

    if (res < 0)

        printk(KERN_INFO"failed to register hook\n");

    else

        printk(KERN_INFO"hello nftest\n");

    return res;

}

static void __exit nftest_exit(void)

{

    printk(KERN_INFO"bye nftest\n");

    nf_unregister_hook(&nf_test_ops);

}

module_init(nftest_init);

module_exit(nftest_exit);

时间: 2024-07-28 13:21:52

【转】Netfilter机制的相关文章

防火墙之 iptables软件(Netfilter机制)(读鸟哥笔记)欢迎指出错误

kernel版本不同 防火墙机制不同--2004年以后的distributions 已经都为2.6的kernel Version 2.0:使用 ipfwadm 这个防火墙机制: Version 2.2:使用的是 ipchains 这个防火墙机制: Version 2.4 与 2.6 :主要是使用 Netfilet机制的iptables 这个软件,不过在某些早期的 Version 2.4 版本也同时支持 ipchains (编译成为模块).不过,不建议在 2.4 之后的核心版本使用 ipchain

利用netfilter机制,实现内核防火墙把http请求和回应的数据包截获后,解释出其中的http层数据

#include<linux/init.h> #include<linux/kernel.h> #include<linux/module.h> #include<linux/netfilter_ipv4.h> #include<linux/skbuff.h> #include<linux/ip.h> #include<linux/tcp.h> #include<linux/if_ether.h> #inclu

Linux 4.10中两个新特性与我的一段故事

今早5点半起来没有开始写文章,而是去西湾红树林连跑带走折腾了将近20公里,回来后就8点多了...洗了个澡之后坐稳当,开始写一段关于我的故事.        在2014年到2015年期间,我在负责研发一款无线安全网关,其实就是一个VPN,接入设备包括手机,xPad,盒子...这些设备的OS除了iOS之外,基本上都是基于Linux的Android.这个网关一般用于各种需要高性能加密通信的场合,在数据传输之前需要比较强的认证,服务端支持4G的加密带宽,支持复杂的接入控制和访问控制,支持复杂的Qos,另

IT管理员必备技能有哪些?

IT管理员常用的管理.运维工具有哪些?先说说TCPcopy这个神器吧,貌似很多人都还在用着ab模拟测压力,TCPcopy能直接导入线上流量供上线前的风险测试.下面对使用过的工具会简单进行功能及使用场景介绍,并提及一些所了解的工具. 统一帐号管理: 你还在自己写脚本批量增加机器的用户.分组和修改密码或者同步主机的/etc/passwd吗?你还在使用脚本批量对用户设置权限吗?如果有一台帐号主机能够提供所有服务器的帐号.密码.权限控制,如此一来,如果想要增加.修改.刪除用户,只要到这台服务器上面处理即

Linux -- 入侵检测系统(IDS)介绍及应用(1)

一.入侵检测工具简介 Internet上的服务器一般都会被安置在防火墙的DMZ(Demilitarized Zone)区,受到防火墙的保护.这在一定程度可以防止具有已知非法特征的危险连接和恶意攻击,但是却防止不了合法用户的非法访问.什 么 时候会出现合法用户的非法访问呢?举例说明,比如,合法用户的机器被他人控制,成为了黑客的攻击跳 板,或者是合法用户想做一些别有用心的探测等.除此之外,有些攻击者还会用端口扫描程序扫描服务器的所有端口,以收集有用的信息(比 如,哪些端口是打开的?哪些是关闭的? )

教你如何用好这些IT运维管理必备工具

能熟练使用下面的两三个IT运维管理工具,你就是高手中的高手. 统一帐号管理 你还在自己写脚本批量增加机器的用户名.分组和修改密码或者同步主机的/etc/passwd吗?你还在使用脚本批量对用户设置权限吗?如果有一台帐号主机能够提供所有服务器的帐号.密码.权限控制,如此一来,如果想要增加.修改.刪除用户,只要到这台服务器上面处理即可,这样是不是很方便? 1. LDAP 统一管理各种平台帐号和密码,包括但不限于各种操作系统(Windows.Linux),Linux系统sudo集成,系统用户分组,主机

高手Linux运维管理必备工具大全

一.统一账号管理 1.LDAP 统一管理各种平台帐号和密码,包括但不限于各种操作系统(Windows.Linux),Linux系统sudo集成,系统用户分组,主机登入限制等:可与Apache,HTTP,FTP,SAMBA,ZABBIX,Jenkins等集成:支持密码策略(密码强度.密码过期时间.强制修改.超过验证错误次数锁定帐号)等:支持插件式鉴别模块PAM:不同平台权限的设定.划分: 2.JumpServer 一款由python编写开源的跳板机(堡垒机)系统,实现了跳板机应有的功能.基于ssh

编写iptables模块实现不连续IP地址的DNAT-POOL

1.背景 <路由应用-使用路由实现负载流量均衡>的第3.3节,并没有给出如何配置一个pool,那是因为在Linux 2.6.10之上,已经不再支持配置不连续IP地址的pool了,如果看iptables的man手册,将会得到以下信息: In  Kernels up to 2.6.10 you can add several --to-destination options. For those kernels, if you specify more than one destination 

Netfilter&amp;iptables:如何理解连接跟踪机制?

如何理解Netfilter中的连接跟踪机制? 本篇我打算以一个问句开头,因为在知识探索的道路上只有多问然后充分调动起思考的机器才能让自己走得更远.连接跟踪定义很简单:用来记录和跟踪连接的状态. 问:为什么又需要连接跟踪功能呢? 答:因为它是状态防火墙和NAT的实现基础. OK,算是明白了.Neftiler为了实现基于数据连接状态侦测的状态防火墙功能和NAT地址转换功能才开发出了连接跟踪这套机制.那就意思是说:如果编译内核时开启了连接跟踪选项,那么Linux系统就会为它收到的每个数据包维持一个连接