文章目录
netfilter
what?
(1) Netfilter是Rusty Russell提出的Linux 2.4 内核防火墙框架,框架既简介又灵活,可实现安全策略的很多功能,如DNAT、SNAT、数据包过滤,数据包处理等等。
(2) Netfilter与IP协议栈的关系:Netfilter是嵌入内核IP协议栈的一系列调用入口,设置在报文处理的路径上。Linux网络内核内置了5条链PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING, 其实就是在内核的五个位置嵌入了NF_HOOK函数,然后通过NF_HOOK进入Netfilter框架处理(进入不同的钩子函数)。
(3)与Netfilter的五个钩子
在内核协议栈中,有5个跟netfilter有关的钩子,数据包经过每个钩子时,都会检查上面是否注册有函数,如果有的话,就会调用相应的函数处理该数据包,它们的位置见下图:
|
| Incoming
↓
+-------------------+
| NF_IP_PRE_ROUTING |
+-------------------+
|
|
↓
+------------------+
| | +----------------+
| routing decision |-------->| NF_IP_LOCAL_IN |
| | +----------------+
+------------------+ |
| |
| ↓
| +-----------------+
| | local processes |
| +-----------------+
| |
| |
↓ ↓
+---------------+ +-----------------+
| NF_IP_FORWARD | | NF_IP_LOCAL_OUT |
+---------------+ +-----------------+
| |
| |
↓ |
+------------------+ |
| | |
| routing decision |<----------------+
| |
+------------------+
|
|
↓
+--------------------+
| NF_IP_POST_ROUTING |
+--------------------+
|
| Outgoing
↓
从上面的流程中,我们还可以看出,不考虑特殊情况的话,一个数据包只会经过下面三个路径中的一个:
本机收到目的IP是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_LOCAL_IN
本机收到目的IP不是本机的数据包: NF_IP_PRE_ROUTING -> NF_IP_FORWARD ->
NF_IP_POST_ROUTING本机发出去的数据包: NF_IP_LOCAL_OUT -> NF_IP_POST_ROUTING
注意: netfilter所有的钩子(hooks)都是在内核协议栈的IP层,由于IPv4和IPv6用的是不同的IP层代码,所以iptables配置的rules只会影响IPv4的数据包,而IPv6相关的配置需要使用ip6tables。
图示netfilter
数据包的处理:
加入netfilter后的流程:
钩子函数
钩子函数返回值
在上图的处理流程中可以看到在每个关键点上,有很多已经按照优先级预先注册了的回调函数(回调函数又被称为“钩子函数”)埋在这些关键点,形成了一条链。回调函数的返回值告诉netfilter对数据包如何处理:
- NF_ACCEPT 继续正常传输数据报
- NF_DROP 丢弃这个数据报,不再传递
- nNF_STOLEN 模块接管该数据报。该回调函数将从此开始对数据报的处理,并且netfilter应当放弃该数据报的任何处理。但是并不意味着该数据包的资源已经被释放,只是回调函数从netfilter手上获取了该数据包的所有权。
- NF_QUEUE 对该数据包进行排队
- NF_REPEAT 再次调用该回调函数
钩子函数的存储
钩子函数存储在全局二维数组nf_hooks中。
协议栈进入Netfilter
Netfilter使用NF_HOOK(/include/linux/netfilter.h)宏在协议栈内部切入到Netfilter框架
切入点
1、ip_rcv(/net/ipv4/ip_input.c)
如果协议栈当前收到了ipv4的报文,那么就把这个报文传到Netfilter的NF_IP_PRE_ROUTING过滤点,去检查过滤点是否已经有注册了相关的用于处理数据包的钩子函数。如果有,则挨个去遍历链表nf_hooks去寻找匹配的match和target,根据返回到Netfilter的值来进一步决定该如何处理这个数据包。
2、ip_forward(/net/ipv4/ip_forward.c)
3、ip _output.c(/net/ipv4)
4、ip_local_deliver(/net/ipv4/ip_input.c)
5、__ip_local_out_sk(/net/ipv4ip _output.c)
协议栈+Netfilter处理流程
iptables
what?
iptables是用户态下的命令行前台,用于操作netfilter.netfilter真正完成内核态下的数据包的处理。
iptables用表(table)来分类管理它的规则(rule),根据rule的作用分成了好几个表,比如用来过滤数据包的rule就会放到filter表中,用于处理地址转换的rule就会放到nat表中,其中rule就是应用在netfilter钩子上的函数,用来修改数据包的内容或过滤数据包。
使用
iptables中的规则(Rules)
rule存放在特定表的特定chain上,每条rule包含下面两部分信息:
Matching
Matching就是如何匹配数据包,匹配的条件很多,如协议类型、源/目的IP、源/目的端口、in/out接口、包头里面的数据以及链接状态等,这些可以自由组合从而实现复杂情况下的匹配。详细请参考这里
Tragets
Targets就是找到匹配的数据包之后怎么办,常见的有下面的几种:
- DROP:直接将数据包丢弃,不再进行后续处理
- RETURN:跳过当前的chain,该chain里后续的rule不再执行
- QUEUE:将数据包放入用户空间的队列,供用户空间的程序处理
- ACCEPT:同意数据包通过,继续执行后续的rule
- 跳转到其它用户自定义的chain继续执行(target为自定义的chain)
自定义chain
iptables -N xxxChain
链接
http://wiki.dreamrunner.org/public_html/Linux/Networks/netfilter.html
https://www.ibm.com/developerworks/cn/linux/l-ntflt/
https://segmentfault.com/a/1190000009043962
Netfilter的hook机制
http://www.360doc.com/content/15/1222/11/29689985_522244314.shtml
https://www.ibm.com/developerworks/cn/linux/l-ntflt/
http://wiki.dreamrunner.org/public_html/Linux/Networks/netfilter.html