标题：netfilter
架构
通俗的说，netfilter的架构就是在整个网络流程的若干位置放置了一些检测点（HOOK），而在每个检测点上登记了一些处理函数进行处理（如包过滤，NAT等，甚至可以是 用户自定义的功能）。  netfilter[1]
IP层的五个HOOK点的位置如下图所示
[1]:NF_IP_PRE_ROUTING：刚刚进入网络层的数据包通过此点（刚刚进行完版本号，校验 
和等检测）， 目的地址转换在此点进行； 
[2]:NF_IP_LOCAL_IN：经路由查找后，送往本机的通过此检查点，INPUT包过滤在此点进行； 
[3]:NF_IP_FORWARD：要转发的包通过此检测点，FORWARD包过滤在此点进行； 
[4]:NF_IP_POST_ROUTING：所有马上便要通过网络设备出去的包通过此检测点，内置的源地址转换功能（包括地址伪装）在此点进行； 
[5]:NF_IP_LOCAL_OUT：本机进程发出的包通过此检测点，OUTPUT包过滤在此点进行。
在IP层代码中，有一些带有NF_HOOK宏的语句，如IP的转发函数中有：
如果在编译内核时没有配置netfilter时，就相当于调用最后一个参数，此例中即执行 
ip_forward_finish函数；否则进入HOOK点，执行通过nf_register_hook（）登记的功能 
（这句话表达的可能比较含糊，实际是进入nf_hook_slow（）函数，再由它执行登记的 
函数）。
NF_HOOK宏的参数分别为：
⒈ pf：协议族名，netfilter架构同样可以用于IP层之外，因此这个变量还可以有诸如 
PF_INET6，PF_DECnet等名字。
⒉hook：HOOK点的名字，对于IP层，就是取上面的五个值； 
⒊skb：不用多解释了吧； 
⒋indev：进来的设备，以struct net_device结构表示； 
⒌outdev：出去的设备，以struct net_device结构表示； 
（后面可以看到，以上五个参数将传到用nf_register_hook登记的处理函数中。） 
⒍okfn：是个函数指针，当所有的该HOOK点的所有登记函数调用完后，转而走此流程。
这些点是已经在内核中定义好的，除非你是这部分内核代码的维护者，否则无权增加 
或修改，而在此检测点进行的处理，则可由用户指定。像packet filter,NAT,connection 
track这些功能，也是以这种方式提供的。正如netfilter的当初的设计目标－－提供一 
个完善灵活的框架，为扩展功能提供方便。
如果我们想加入自己的代码，便要用nf_register_hook函数，其函数原型为：
int nf_register_hook(struct nf_hook_ops *reg) 
我们考察一下struct nf_hook_ops结构：
我们的工作便是生成一个struct nf_hook_ops结构的实例，并用nf_register_hook将 
其HOOK上。其中list项我们总要初始化为{NULL,NULL}；由于一般在IP层工作，pf总是 
PF_INET；hooknum就是我们选择的HOOK点；一个HOOK点可能挂多个处理函数，谁先谁后 
，便要看优先级，即priority的指定了。netfilter_ipv4.h中用一个枚举类型指定了内
置的处理函数的优先级：
hook是提供的处理函数，也就是我们的主要工作，其原型为：
它的五个参数将由NFHOOK宏传进去。
了解了这些，基本上便可以可以写一个lkm出来了。三.例子代码这段代码是一个例子，其功能实现了一个IDS，检测几个简单攻击（land,winnuke）和特殊 
扫描(nmap)，当然，不会有人真把它当严肃的IDS使用吧：-）。可以利用类似结构干点别 
的。
四.附录：
与2.2在应用方面的区别简介 
本来还想详细介绍一下iptables的用法，但如果说的太详细的话，还不如索性将HOWTO 
翻译一下，于是干脆了却了这个念头，只顺便简介一下与以前版本的变化（而且是我认 
为最重要的）。如果ipchains本来便没有在你的脑子中扎根，其实便没有必要看这部分。
netfilter，又可称为iptables.开发初期准备将packet filter和NAT的配置工具完全 
分开，一个称为iptables，另一个称为ipnatctl，而将整个项目成为netfilter.但后 
来可能是还是习惯2.2内核中用ipchians一个工具干两件事的用法，又 
改为全部用iptables配置了。
理论上还可以用2.2系列的ipchains和2.0系列的ipfwadm作配置工具，但只是做兼容 
或过渡的考虑了。通过源码看到他们也是通过现有的结构HOOK上去的（主要是net/ipv 
4/netfilter目录下的ip_fw_compat.c,ip_fw_compat_masq.c,ip_fw_compat_redir.c,
ipchains_core.c,ipfwadm_core.c这几个文件）。
一个重要的变化是原有的INPUT,OUTPUT（原来是小写的input,ouput）链（现在应称 
为表?）的位置变了，原来的input,output的位置相当于现在的NF_IP_PRE_ROUTING， 
NF_IP_POST_ROUTING。原有的结构确实不太合理，转发的包要经过三条链，现在INPUT 
专指去往本机的，OUPUT专指从本机发出的，而FOWARD仍旧是转发的包。
举两个简单的例子：
⒈作地址伪装（场景：对外通过拨号连接internet）注意原来的MASQ变成好长的 
MASQUERATE，而伪装相当于SNAT，因此位置是在POSTROUTING：
iptables -t nat -A POSTROUTING －o ppp0 -j MASQUERATE 
⒉还有一个限制包速率的功能比较好玩，例如如下规则：
iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT 
简单的说就是在转发时（-A FORWARD：因为是防火墙嘛），如果是tcp协议，且有syn 
标记（-p tcp --syn），可以限制为每秒一个（-m limit --limit 1/s），行动项是 
ACCEPT。最后连起来意义就是每秒只允许转发一个tcp连接请求。五.后记netfilter还提供了许多新功能，如可以将包转发到应用层，由应用程序进行处理等 
，可目前我还没有分析多少，慢慢抽出点时间看吧。唉，尽管以前看过ipchains的代码 
，但netfilter实在变动太大了，一切都要从头看起
引netfilter技术分析
netfilter是由Rusty Russell提出的Linux 2.4内核防火墙框架，该框架既简洁又灵活，可实现安全策略应用中的许多功能，如数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换（Network Address Translation，NAT），以及基于用户及媒体访问控制（Media Access Control，MAC）地址的过滤和基于状态的过滤、包速率限制等。1.1 netfilter框架netfilter提供了一个抽象、通用化的框架[1]，作为中间件，为每种网络协议（IPv4、IPv6等）定义一套钩子函数。Ipv4定义了5个钩子函数，这些钩子函数在数据报流过协议栈的5个关键点被调用，也就是说，IPv4协议栈上定义了5个“允许垂钓点”。在每一个“垂钓点”，都可以让netfilter放置一个“鱼钩”，把经过的网络包（Packet）钓上来，与相应的规则链进行比较，并根据审查的结果，决定包的下一步命运，即是被原封不动地放回IPv4协议栈，继续向上层递交；还是经过一些修改，再放回网络；或者干脆丢弃掉。
Ipv4中的一个数据包通过netfilter系统的过程如图1所示。
图1 Netfilter的功能框架1.2 netfilter的关键技术netfilter主要采用连线跟踪（Connection Tracking）、包过滤（Packet Filtering）、地址转换、包处理（Packet Mangling)4种关键技术。
⒈2.1 连线跟踪
连线跟踪是包过滤、地址转换的基础，它作为一个独立的模块运行。采用连线跟踪技术在协议栈低层截取数据包，将当前数据包及其状态信息与历史数据包及其状态信息进行比较，从而得到当前数据包的控制信息，根据这些信息决定对网络数据包的操作，达到保护网络的目的。
当下层网络接收到初始化连接同步（Synchronize，SYN）包，将被netfilter规则库检查。该数据包将在规则链中依次序进行比较。如果该包应被丢弃，发送一个复位（Reset，RST）包到远端主机，否则连接接收。这次连接的信息将被保存在连线跟踪信息表中，并表明该数据包所应有的状态。这个连线跟踪信息表位于内核模式下，其后的网络包就将与此连线跟踪信息表中的内容进行比较，根据信息表中的信息来决定该数据包的操作。因为数据包首先是与连线跟踪信息表进行比较，只有SYN包才与规则库进行比较，数据包与连线跟踪信息表的比较都是在内核模式下进行的，所以速度很快。
⒈2.2 包过滤
包过滤检查通过的每个数据包的头部，然后决定如何处置它们，可以选择丢弃，让包通过，或者更复杂的操作。
⒈2.3 地址转换
网络地址转换源（NAT）分为（Source NAT，SNAT）和目的NAT(Destination NAT,DNAT)2种不同的类型。SNAT是指修改数据包的源地址（改变连接的源IP）。SNAT会在数据包送出之前的最后一刻做好转换工作。地址伪装（Masquerading）是SNAT的一种特殊形式。DNAT 是指修改数据包的目标地址（改变连接的目的IP）。DNAT 总是在数据包进入以后立即完成转换。端口转发、负载均衡和透明代理都属于DNAT。
⒈2.4 包处理
利用包处理可以设置或改变数据包的服务类型（Type of Service,TOS）字段；改变包的生存期（Time to Live,TTL）字段；在包中设置标志值，利用该标志值可以进行带宽限制和分类查询。