- 论坛徽章:
- 0
|
本帖最后由 pywj777 于 2013-05-22 01:03 编辑
最近在整理以前的笔记,在Godbach的鼓励下,准备写一个有关nf_conntrack的总结。与之前写的iptables算是姐妹篇,因为iptables和nf_conntrack应该算是netfilter中比较重要的两个模块了。同时它们之间也互相搭配应用。还是老样子,多上图,少上字。
我认为理解一个程序的实现主要从两点来理解,一个是业务的处理流程,另一个就是数据的组织结构。根据这两点,我们先来介绍几个重要的数据结构:
连接跟踪,顾名思义,就是识别一个连接上双方向的数据包,同时记录状态。下面看一下它的数据结构:
struct nf_conn {
/* Usage count in here is 1 for hash table/destruct timer, 1 per skb, plus 1 for any connection(s) we are `master' for */
struct nf_conntrack ct_general; /* 连接跟踪的引用计数 */
spinlock_t lock;
/* Connection tracking(链接跟踪)用来跟踪、记录每个链接的信息(目前仅支持IP协议的连接跟踪)。
每个链接由“tuple”来唯一标识,这里的“tuple”对不同的协议会有不同的含义,例如对tcp,udp
来说就是五元组: (源IP,源端口,目的IP, 目的端口,协议号),对ICMP协议来说是: (源IP, 目
的IP, id, type, code), 其中id,type与code都是icmp协议的信息。链接跟踪是防火墙实现状态检
测的基础,很多功能都需要借助链接跟踪才能实现,例如NAT、快速转发、等等。*/
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
unsigned long status; /* 可以设置由enum ip_conntrack_status中描述的状态 */
struct nf_conn *master; /* 如果该连接是某个连接的子连接,则master指向它的主连接 */
/* Timer function; drops refcnt when it goes off. */
struct timer_list timeout;
union nf_conntrack_proto proto; /* 用于保存不同协议的私有数据 */
/* Extensions */
struct nf_ct_ext *ext; /* 用于扩展结构 */
};
这个结构非常简单,其中最主要的就是tuplehash(跟踪连接双方向数据)和status(记录连接状态),这也连接跟踪最主要的功能。
在status中可以设置的标志,由下面的enum ip_conntrack_status描述,它们可以共存。这些标志设置后就不会再被清除。
enum ip_conntrack_status {
IPS_EXPECTED_BIT = 0, /* 表示该连接是个子连接 */
IPS_SEEN_REPLY_BIT = 1, /* 表示该连接上双方向上都有数据包了 */
IPS_ASSURED_BIT = 2, /* TCP:在三次握手建立完连接后即设定该标志。UDP:如果在该连接上的两个方向都有数据包通过,
则再有数据包在该连接上通过时,就设定该标志。ICMP:不设置该标志 */
IPS_CONFIRMED_BIT = 3, /* 表示该连接已被添加到net->ct.hash表中 */
IPS_SRC_NAT_BIT = 4, /*在POSTROUTING处,当替换reply tuple完成时, 设置该标记 */
IPS_DST_NAT_BIT = 5, /* 在PREROUTING处,当替换reply tuple完成时, 设置该标记 */
/* Both together. */
IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
/* Connection needs TCP sequence adjusted. */
IPS_SEQ_ADJUST_BIT = 6,
IPS_SRC_NAT_DONE_BIT = 7, /* 在POSTROUTING处,已被SNAT处理,并被加入到bysource链中,设置该标记 */
IPS_DST_NAT_DONE_BIT = 8, /* 在PREROUTING处,已被DNAT处理,并被加入到bysource链中,设置该标记 */
/* Both together */
IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
IPS_DYING_BIT = 9, /* 表示该连接正在被释放,内核通过该标志保证正在被释放的ct不会被其它地方再次引用。有了这个标志,当某个连接要被删
除时,即使它还在net->ct.hash中,也不会再次被引用。*/
IPS_FIXED_TIMEOUT_BIT = 10, /* 固定连接超时时间,这将不根据状态修改连接超时时间。通过函数nf_ct_refresh_acct()修改超时时间时检查该标志。 */
IPS_TEMPLATE_BIT = 11, /* 由CT target进行设置(这个target只能用在raw表中,用于为数据包构建指定ct,并打上该标志),用于表明这个ct是由CT target创建的 */
};
连接跟踪对该连接上的每个数据包表现为以下几种状态之一,由enum ip_conntrack_info表示,被设置在skb->nfctinfo中。
enum ip_conntrack_info {
IP_CT_ESTABLISHED(0), /* 表示这个数据包对应的连接在两个方向都有数据包通过,并且这是ORIGINAL初始方向数据包(无论是TCP、UDP、ICMP数据包,
只要在该连接的两个方向上已有数据包通过,就会将该连接设置为IP_CT_ESTABLISHED状态。不会根据协议中的标志位进行判断,
例如TCP的SYN等)。但它表示不了这是第几个数据包,也说明不了这个CT是否是子连接。*/
IP_CT_RELATED(1), /* 表示这个数据包对应的连接还没有REPLY方向数据包,当前数据包是ORIGINAL方向数据包。并且这个连接关联一个已有的连接,
是该已有连接的子连接,(即status标志中已经设置了IPS_EXPECTED标志,该标志在init_conntrack()函数中设置)。但无法
判断是第几个数据包(不一定是第一个)*/
IP_CT_NEW(2), /* 表示这个数据包对应的连接还没有REPLY方向数据包,当前数据包是ORIGINAL方向数据包,该连接不是子连接。但无法判断是
第几个数据包(不一定是第一个)*/
IP_CT_IS_REPLY(3), /* 这个状态一般不单独使用,通常以下面两种方式使用 */
IP_CT_ESTABLISHED + IP_CT_IS_REPLY(3), /* 表示这个数据包对应的连接在两个方向都有数据包通过,并且这是REPLY应答方向数据包。但它表示不了这是
第几个数据包,也说明不了这个CT是否是子连接。*/
IP_CT_RELATED + IP_CT_IS_REPLY(4), /* 这个状态仅在nf_conntrack_attach()函数中设置,用于本机返回REJECT,例如返回一个ICMP目的不可达报文,
或返回一个reset报文。它表示不了这是第几个数据包。*/
IP_CT_NUMBER = IP_CT_IS_REPLY * 2 - 1(5) /* 可表示状态的总数 */
};
以上就是连接跟踪里最重要的数据结构了,用于跟踪连接、记录状态、并对该连接的每个数据包设置一种状态。 |
评分
-
查看全部评分
|