最近一段时间一直在学习netfilter和iptables相关的知识。首先要感谢我的老大能给我时间、给我机会来学习。写这篇总结就只有一个目的,总j结近来学到的知识,理清思路,查漏补缺。看了半个多月的基础知识(加上前面一段时间自己也一直在看,差不多也有一个月了),刚开始看netfilter和iptables的时候感觉是很空旷的,于是找了很多篇文档来一字一句的理解,现在总算有点眉目了。学习完之后的感觉就是linux内核防火墙的功能很强大,很人性化。说它强大是因为netfilter实现了,filter(数据包过滤),nat(网络地址转换),manage(数据包处理),raw(连接跟踪)等几大功能。说它很人性化是因为用户可以根据自己的需要通过iptables命令来配置这些功能,从而达到各有所需的目的。以下内容都是我个人总结而成,不敢保证完全正确,但若涉及到代码和iptables命令,都是我亲自在机子上调试运行过,可以保证正确性。
提到netfilter首先我就来回顾下netfilter的架构,也就是数据包从协议栈切入netfilter框架时,必须经过的那几个hook点(iptables成为链),这里为了节约时间我就直接把网上的图拿过来用哈,
1.当数据包从ip协议栈切入到netfilter框架的时候,首先会经过第一个hook点NF_IP_PRE_ROUTING,然后在路由判断,其实路由判断和路由器的转发数据包的道理一样的,如果这个数据包的ip地址是本机的那么就通过NF_IP_LOCAL_IN这个hook点传递给本机,如果ip地址不是本机的,就通过NF_IPFORWARD这个hook点往NF_IP_POST_ROUTING这个hook点发送出去。
2.如果数据包是从本机发送出去的,那么首先会经过hook点NF_IP_LOCAL_OUT,经过这个点以后其实还有一个路由判断(图中未标注,图有点问题哈),这个路由判断的目的就是决定从那种网卡把数据包发送出去哈,判断以后会经过hook点NF_IP_POST_ROUTING,然后传递给协议栈,网络接口层,最终从网卡发到公网上去哈。
3.这就是数据包在netfilter中的走向哈,其实内核已经提前在那五个点中注册了hook函数哈,当数据包从协议栈进入netfilter的时候,都会经过这些hook函数。Iptables将这五个对应的点称为五条链哈,PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING。后面再来详细说iptables。
4.协议栈需要切入netfilter架构,是通过NF_HOOK这个宏函数实现的。当数据包进入ip协议栈的时候,是由函数ip_recv函数接收数据包,这个函数的功能还是比较简单,主要就是完成一些检查,例如ip头部长度啊,版本啊,校验和之类的检查,这个函数最后会调用宏函数NF_HOOK从而切入到netfilter中,由于实现netfilter的内核源码很复杂,时间有限所以暂时没有看完,下周还得继续学习哈!
HOOK函数的实现
1.提到hook,现在来回顾下hook函数。首先netfilter中的那五个hook点在内核中是用宏来表示的,如下:
#define NF_IP_PRE_ROUTING 0
#define NF_IP_LOCAL_IN 1
#define NF_IP_FORWARD 2
#define NF_IP_LOCAL_OUT 3
#define NF_IP_POST_ROUTING 4
2.hook函数是有优先级的,优先级是用一个结构体表示的,具体的成员忘记了,直接复制过来了哈(但是我清楚的记得数值越小,优先级越高哈)