netfilter-iptable

netfilter-iptable什么是Netfilter/iptableNetfilter/iptables是Linux内核内置的报文过滤框架,程序可以通过该框架完成报文过滤、地址转换(NAT)以及连接跟踪等功能。Netfilter/iptables由两部分组成,一部分是Netfilter的”钩子(hook)“,这些”钩子”由Linux内核协议栈提供,内核模块可以通过注册”钩子”来完成各种各样的功能。 另一部

大家好,又见面了,我是你们的朋友全栈君。

什么是Netfilter/iptable

Netfilter/iptables是Linux内核内置的报文过滤框架,程序可以通过该框架完成报文过滤、地址转换(NAT)以及连接跟踪等功能。

Netfilter/iptables由两部分组成,一部分是Netfilter的”钩子(hook)“,这些”钩子”由Linux内核协议栈提供,内核模块可以通过注册”钩子”来完成各种各样的功能。 
另一部分是iptables的规则,这些规则规定了”钩子”如何工作。

下图很直观的说明了用户空间的iptables和内核空间的ip_tables模块、Netfilter之间的关系。

netfilter-iptable

Netfilter

Netfilter是嵌入Linux内核协议栈的,设置在报文处理路径上的一系列调用入口。 
Netfilter一共有5个”钩子”设置在IP协议栈的报文处理路径上,这5个”钩子”就是内嵌在内核协议栈的检查点。 
我们可以把处理函数注册到各个检查点,当报文经过各个检查点时,就可以通过”钩子”函数对报文进行处理完成相应功能。

下图说明了5个”钩子”在内核协议栈的位置。 
netfilter-iptable

“钩子”的存储及管理机制

在内核中,“钩子”函数由一个全局二维数组nf_hooks按照协议族归类存储,在每个协议族中,根据钩子点顺序排列,在钩子点内则根据钩子函数的优先级排列。 
例如ipv4和ipv6就是两个协议族,每个协议族都包含5个”钩子”,每个”钩子”下面保存了注册在这个”钩子”上的函数地址。
netfilter-iptable

  • 这个二维数组的每一项代表了一个钩子被调用的点,NF_PROTO代表协议栈,NF_HOOK代表协议栈中某个路径点。
  • 所有模块都可以通过nf_register_hook()函数将一个钩子函数挂入想要被调用点的链表中(通过Protocol和hook指定一个点)。 
    这样,该钩子函数就能够处理从指定Protocol和指定hook点流过的数据包。
  • Netfilter在不同协议栈的不同点上放置钩子函数,当数据包经过某个协议栈(NF_PROTO)的某个点(NF_HOOK)时,该协议栈会通过NF_HOOK()函数调用对应钩子链表(nf_hooks[NF_PROTO][NF_HOOK])中注册的每一个钩子项来处理该数据包。

Netfilter定义了每个钩子函数的返回值,每个钩子函数只能返回下面的返回值,而不能自定义返回值。

  • NF_DROP(0):数据包被丢弃,即不被下一个钩子函数处理,同时也不再被协议栈处理,并释放数据包。
  • NF_ACCEPT(1):数据包被接受,即交给下一个钩子或协议栈继续处理。
  • NF_STOLEN(2):数据包被停止处理,即不被下一个钩子函数处理,同时也不再被协议栈处理,但不释放数据包。
  • NF_QUEUE(3):将数据包交给nf_queue子系统处理,即不被下一个钩子函数处理,同时也不再被协议栈处理,也不释放数据包。
  • NF_REPEAT(4):数据包将被该返回值的钩子函数再次处理一遍。
  • NF_STOP(5): 数据包停止被该HOOK点的后续钩子函数处理,交给协议栈继续处理。

“钩子”的使用方法

“钩子”的使用首先实例化一个nf_hook_ops对象,然后对其进行必要的初始化设置,最后通过nf_register_hook()函数将其注册到二维数组nf_hooks中。 
我们首先初始化nf_hook_ops中的常用字段:


static struct nf_hook_ops nf_hook_test_ops = 
{
    .hook = test_hook_func;
    .hooknum = NF_INET_PRE_ROUTING;
    .pf = PF_INET;
    .owner = THIS_MODULE;
    .priority = NF_IP_PRI_FIRST;
}

其中:

  • hook是钩子函数
  • hooknum是钩子点
  • pf是协议栈
  • priority是钩子函数的优先级

然后在模块加载和退出函数中注册和移除钩子函数:


int init_module(void) {
    nf_register_hook(&nf_hook_test_ops);
}
void cleanup_module() {
    nf_unregister_hook(&nf_hook_test_ops);
}

下面是回调函数的声明:


static unsigned int test_hook(unsigned int hooknum, struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
    int (*okfn)(struct sk_buff*)

从上述过程可以看出,钩子函数的使用与iptables没有任何关系,也就是说如果某个模块需要对协议栈的报文进行处理,但不需要用户空间的参数,那么完全可以只注册钩子函数,而不需要编写iptables的模块。

即使需要用户空间的参数,也可以通过proc或者netlink等其他用户态和内核态通信方式来传递参数,这样就可以更灵活的使用Netfilter了。

参考资料:

traceback:http://my.oschina.net/hoolev/blog/389196

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/140416.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • webpack处理less的loader_登录器和引擎版本号不匹配

    webpack处理less的loader_登录器和引擎版本号不匹配Theremightbeaproblemwiththeprojectdependencytree.ItislikelynotabuginCreateReactApp,butsomethingyouneedtofixlocally.Thereact-scriptspackageprovidedbyCreateReactApprequiresadependency:”webpack”:”4.44.2″Don’ttryt

    2022年8月9日
    33
  • 无锁编程实例

    无锁编程实例最近在研究nginx的自旋锁的时候,又见到了GCCCAS原子操作,于是决定动手分析下CAS实现的无锁到底性能如何,网上关于CAS实现无锁的文章很多,但少有研究这种无锁的性能提升的文章,这里就以实验结果和我自己的理解逐步展开。1.什么是CAS原子操作在研究无锁之前,我们需要首先了解一下CAS原子操作——Compare&Set,或是Compare&Swap,现在

    2022年6月3日
    33
  • oracle 9i安装_oracle9i查看字符集

    oracle 9i安装_oracle9i查看字符集Oracle9iDatabaseRelease2Enterprise/Standard/PersonalEditionforWindowsNT/2000/XPhttp://download.oracle.com/otn/nt/oracle9i/9201/92010NT_Disk1.ziphttp://download.oracle.com/otn/nt/oracle9i/9201/…

    2025年6月28日
    2
  • javascript数组怎么定义_js中的数组

    javascript数组怎么定义_js中的数组每一门编程语言,都有数组或类似数组的结构,同样的JavaScript(虽然是脚本语言)也不例外,学习JavaScript的数组,我们从新建第一个数组开始。JavaScript中的数组,长度是动态可变的,如果学过其他编程语言的朋友可能对这一点不是很习惯。但事实上反而使得问题变得简单了,因此不需要再定义数组的时候就指定它的大小。

    2022年10月1日
    2
  • HTTPS能有效保护用户隐私

    HTTPS就等于HTTP加上TLS(SSL),HTTPS协议的目标主要有三个:http://hovertree.com/menu/webfront/数据保密性。保证内容在传输过程中不会被第三方查看

    2021年12月24日
    44
  • 股票购买拐点在哪里

    股票购买拐点在哪里 股票购买拐点在哪里   逢低买,当然最好买在拐点。股价始向上的时候。   不过当主力刚开始吸筹时,反复震荡难免,没准还来一个诱空,这时介入心情极坏,毫无成就感,白受折磨。所以第一步,总是等主力先吃饱喝足,他是老大,我是小弟。   等主力吃够了喝足了,他会拉上去一点,最理想的介入点,就是等他洗盘结束时。当股价开始下跌,不必介入,再等,待拐点出现介入。   拐点在哪里呢?黄金分割?神奇数

    2022年6月26日
    32

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号