没有合适的资源?快使用搜索试试~ 我知道了~
Linux连接跟踪源码分析报告.pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 162 浏览量
2023-05-06
12:45:50
上传
评论
收藏 781KB PDF 举报
温馨提示
试读
33页
Linux连接跟踪源码分析报告.pdf
资源推荐
资源详情
资源评论
Linux 连接跟踪源码分析
IP Connection tracking
连接跟踪用来跟踪和记录连接状态,是 netfilter 的一部份,也是通过在
hook 点上注册相应的结构来工作的。
无论是发送,接收,还是转发的数据包,都要经过两个 conntrack 模块。
第一个 conntrack 点的优先级是最高的,所有数据包进入 netfilter 后都会
首先被它处理,其作用是创建 ip_conntrack 结构。而最后一个 conntrack 的优
先级最低,总是在数据包离开 netfilter 之前做最后的处理,它的作用是将该数
据包的连接跟踪结构添加到系统的连接状态表中
1. ip_conntarck 结构 ip_conntrack.h
内核中用一个 ip_conntrack 结构来描述一个连接的状态
struct ip_conntrack
{
/* nf_conntrack 结构定义于 include/linux/skbuff.h,Line89,其中包括
一个计数器 use 和一个 destroy 函数。计数器 use 对本连接记录的公开引用次数
进行计数 */
struct nf_conntrack ct_general;
/*其中的 IP_CT_DIR_MAX 是一个枚举类型 ip_conntrack_dir(位于
include/linux/netfilter_ipv4/ip_conntrack_tuple.h,Line65)的第 3 个成
员,从这个结构实例在源码中的使用看来,实际上这是定义了两个 tuple 多元组
的 hash 表项 tuplehash[IP_CT_DIR_ORIGINAL/0]和
tuplehash[IP_CT_DIR_REPLY/1],利用两个不同方向的 tuple 定位一个连接,同
时也可以方便地对 ORIGINAL 以及 REPLY 两个方向进行追溯*/
struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
/* 这是一个位图,是一个状态域。在实际的使用中,它通常与一个枚举类型
ip_conntrack_status(位于 include/linux/netfilter_ipv4/ip_conntrack.h,
Line33)进行位运算来判断连接的状态。其中主要的状态包括:
IPS_EXPECTED(_BIT),表示一个预期的连接
IPS_SEEN_REPLY(_BIT),表示一个双向的连接
. . .
IPS_ASSURED(_BIT),表示这个连接即使发生超时也不能提早被删除
IPS_CONFIRMED(_BIT),表示这个连接已经被确认(初始包已经发出) */
unsigned long status;
/*其类型 timer_list 位于 include/linux/timer.h,Line11,其核心是一个
处理函数。这个成员表示当发生连接超时时,将调用此处理函数*/
struct timer_list timeout;
/*所谓“预期的连接”的链表,其中存放的是我们所期望的其它相关连接*/
struct list_head sibling_list;
/*目前的预期连接数量*/
unsigned int expecting;
/*结构 ip_conntrack_expect 位于 ip_conntrack.h,这个结构用于将一个预
期的连接分配给现有的连接,也就是说本连接是这个 master 的一个预期连接*/
struct ip_conntrack_expect *master;
/* helper 模块。这个结构定义于 ip_conntrack_helper.h,这个模块提供
了一个可以用于扩展 Conntrack 功能的接口。经过连接跟踪 HOOK 的每个数据报
都将被发给每个已经注册的 helper 模块(注册以及卸载函数分别为
ip_conntrack_helper_register()以及 ip_conntrack_helper_unregister(),
分别位于 ip_conntrack_core.c)。这样我们就可以进行一些动态的连接管理了
*/
struct ip_conntrack_helper *helper;
/*一系列的 nf_ct_info 类型(定义于 include/linux/skbuff.h ,Line92,实
际上就是 nf_conntrack 结构)的结构,每个结构对应于某种状态的连接。这一
系列的结构会被 sk_buff 结构的 nfct 指针所引用,描述了所有与此连接有关系
的数据报。其状态由枚举类型 ip_conntrack_info 定义(位于
include/linux/netfilter_ipv4/ip_conntrack.h,Line12)共有 5 个成员:
IP_CT_ESTABLISHED: 数据报属于已经完全建立的连接
IP_CT_RELATED: 数据报属于一个新的连接,但此连接与一个现有连接相
关(预期连接);或者是 ICMP 错误
IP_CT_NEW: 数据报属于一个新的连接
IP_CT_IS_REPLY: 数据报属于一个连接的回复
IP_CT_NUMBER: 不同 IP_CT 类型的数量,这里为 7,NEW 仅存于一个方向
上 */
struct nf_ct_info infos[IP_CT_NUMBER];
/* 为其他模块保留的部分 */
union ip_conntrack_proto proto;
union ip_conntrack_help help;
. . .
#ifdef CONFIG_IP_NF_NAT_NEEDED
struct {
struct ip_nat_info info;
union ip_conntrack_nat_help help;
#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \
defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)
int masq_index;
#endif
#if defined(CONFIG_IP_NF_RTSP) || defined(CONFIG_IP_NF_RTSP_MODULE)
struct ip_nat_rtsp_info rtsp_info;
#endif
} nat;
#endif /* CONFIG_IP_NF_NAT_NEEDED */
#if defined(CONFIG_IP_NF_CONNTRACK_MARK)
unsigned long mark;
#endif
};
struct ip_conntrack_tuple_hash 结构描述链表中的节点,这个数组包含“初
始”和“应答”两个成员(tuplehash[IP_CT_DIR_ORIGINAL]和
tuplehash[IP_CT_DIR_REPLY]),所以,当一个数据包进入连接跟踪模块后,先
根据这个数据包的套接字对转换成一个“初始的”tuple,赋值给
tuplehash[IP_CT_DIR_ORIGINAL],然后对这个数据包“取反”,计算出“应答”
的 tuple,赋值给 tuplehash[IP_CT_DIR_REPLY],这样,一条完整的连接已经跃
然纸上了。
enum ip_conntrack_dir
{
IP_CT_DIR_ORIGINAL,
IP_CT_DIR_REPLY,
IP_CT_DIR_MAX
};
2. 连接跟踪表
Netfilter 用“来源地址/来源端口+目的地址/目的端口”,即一个“tuple”,
来唯一标识一个连接。用一张连接跟踪表来描述所有的连接状态,该表用了 hash
算法。
hash 表用一个全局指针来描述(ip_conntrack_core.c)
. . .
struct list_head *ip_conntrack_hash;
表的大小,即 hash 节点的个数由 ip_conntrack_htable_size 全局变量决定,默
认是根据内存计算出来的。而每个 hash 节点又是一条链表的首部,所以,连接
跟踪表就是一个由 ip_conntrack_htable_size 条链表构成的一个 hash 表,整
个连接跟踪表大小使用全局变量 ip_conntrack_max 描述,与 hash 表的关系是
ip_conntrack_max = 8 * ip_conntrack_htable_size。
链表的每个节点,都是一个 ip_conntrack_tuple_hash 结构:
struct ip_conntrack_tuple_hash
{
/* 用来组织链表 */
struct list_head list;
/* 用来描述一个 tuple */
struct ip_conntrack_tuple tuple;
/* this == &ctrack->tuplehash[DIRECTION(this)]. */
struct ip_conntrack *ctrack;
};
实际描述一个 tuple 的是 ip_conntrack_tuple 结构 ip_conntrack_tuple.h
struct ip_conntrack_tuple
{
/* 源 */
struct ip_conntrack_manip src;
/* These are the parts of the tuple which are fixed. */
struct {
/* 目的地址 */
u_int32_t ip;
union {
/* Add other protocols here. */
u_int64_t all;
struct {
u_int16_t port;
} tcp;
struct {
u_int16_t port;
} udp;
struct {
u_int8_t type, code;
} icmp;
struct {
u_int16_t protocol;
. . .
u_int8_t version;
u_int32_t key;
} gre;
struct {
u_int16_t spi;
} esp;
} u;
/* 协议类型 */
u_int16_t protonum;
} dst;
};
对于所有 IP 协议,协议类型、源地址、目的地址这三个参数是识别连接所必须
的,具体到各个协议,就要提取出各协议的唯一特征数据,如 TCP、UDP 的源端
口、目的端口,ICMP 的 ID、TYPE、CODE 等值,这些值就是 tuple 结构要处理的
数据。各协议相关数据是以联合(union)形式定义在 tuple 结构中的,netfilter
缺省支持 TCP、UDP 和 ICMP 协议,如果还要支持其他 IP 协议,如 GRE、ESP、AH、
SCTP 等,需要在联合中添加相应的协议参数值。
ip_conntrack_manip 和 ip_conntrack_manip_proto
ip_conntrack_tuple.h
struct ip_conntrack_manip
{
u_int32_t ip;
union ip_conntrack_manip_proto u;
};
union ip_conntrack_manip_proto
{
/* Add other protocols here. */
u_int32_t all;
struct {
u_int16_t port;
} tcp;
struct {
u_int16_t port;
} udp;
struct {
u_int16_t id;
} icmp;
struct {
u_int32_t key;
} gre;
. . .
剩余32页未读,继续阅读
资源评论
hhappy0123456789
- 粉丝: 58
- 资源: 5万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功