- 浏览: 315926 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
JQ_AK47:
...
Linux下直接发送以太包 -
winsen2009:
谢谢分享,如果能再来一个列子就更好了,刚接触看完还是不懂的用
UNPv1_r3读书笔记: SCTP编程
本文档的Copyleft归yfydz所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
msn: yfydz_no1@hotmail.com
来源:http://yfydz.cublog.cn
1. iptables规则中的state匹配 在2.4/2.6内核的Linux中的防火墙代码netfilter中实现了状态检测(stateful inspection)检测技术,在命令行接口的iptables命令是通过匹配“-m state”来实现,“-m state”匹配中定义了四种状态: NEW,表示新连接; ESTABLISHED,表示已经建立的连接; RELATED,表示相关的子连接; INVALID,表示非法状态。 所以在制定iptables规则时,只需要定义单向的规则,再加上如下两条规则,就可以保证连接回应包能正确通过防火墙而不必加反向规则: iptables -I FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -I FORWARD -m state --state INVALID -j DROP (如果是保护本机,将FORWARD改为INPUT) 2. 内核中的state匹配的实现 (以下的内核代码基于2.4.26内核) 和匹配state对应的内核部分实现是ipt_state.c(net/ipv4/netfilter),匹配部分的代码非常简单,就是根据函数ip_conntrack_get()的返回值来判断数据包的状态类型: if (!ip_conntrack_get((struct sk_buff *)skb, &ctinfo)) statebit = IPT_STATE_INVALID; else statebit = IPT_STATE_BIT(ctinfo); 3. skb与ip_conntrack的关联 再跟踪到ip_conntrack_get()函数(net/ipv4/netfilter_ipv4 /ip_conntrack_core.c),该函数有两个参数,一个是指向sk_buff数据包的指针skb,另一个是枚举类型enum ip_conntrack_info的指针,实际上是一个返回参数,将返回数据包的状态类型;该函数的返回值是连接结构struct ip_conntrack的指针,表示该包属于哪个连接,如果连接不存在,返回空,该包也将被认为是非法包: struct ip_conntrack * ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo) { if (skb->nfct) return __ip_conntrack_get(skb->nfct, ctinfo); return NULL; } ip_conntrack_get()函数本身也很简单,实际上是__ip_conntrack_get()函数(net/ipv4 /netfilter_ipv4/ip_conntrack_core.c)的包裹函数,判断skb的nfct是否非空,非空则将其和枚举指针 ctinfo传给__ip_conntrack_get()函数,nfct是sk_buff中用于描述netfilter conntrack信息的struct nf_ct_info指针,在内核配置了CONFIG_NETFILTER后有效。struct nf_ct_info结构在include/linux/sk_buff.h中定义: struct nf_conntrack { atomic_t use; void (*destroy)(struct nf_conntrack *); }; struct nf_ct_info { struct nf_conntrack *master; }; 在__ip_conntrack_get()函数中,通过nfct->master获取连接指针ct,而nfct相对于ct成员infos的偏移就是连接状态: static inline struct ip_conntrack * __ip_conntrack_get(struct nf_ct_info *nfct, enum ip_conntrack_info *ctinfo) { struct ip_conntrack *ct = (struct ip_conntrack *)nfct->master; /* ctinfo is the index of the nfct inside the conntrack */ *ctinfo = nfct - ct->infos; IP_NF_ASSERT(*ctinfo >= 0 && *ctinfo < IP_CT_NUMBER); return ct; } 由此可见,netfilter的状态检测过程很简洁,如果skb包中的nfct指针设置了的话,可以很快地确定该skb包属于哪个连接,如果不属于任何连接则是非法包。现在的焦点是skb中的nfct值是如何设置的? 4. netfilter如何实现中skb与ip_conntrack连接的关联 nfct值是在resolve_normal_ct()函数(net/ipv4/netfilter/ip_conntrack_core.c)中定义的,该函 数被ip_conntrack_in()函数(net/ipv4/netfilter/ip_conntrack_core.c)调用,在 ip_conntrack_local()函数(net/ipv4/netfilter/ip_conntrack_standalone.c)中调用了 ip_conntrack_in()函数,而这两个函数分别是PREROUTING链和OUTPUT链的起始函数,由下面两个结构 定义(net/ipv4/netfilter/ip_conntrack_standalone.c): static struct nf_hook_ops ip_conntrack_in_ops = { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING, NF_IP_PRI_CONNTRACK }; static struct nf_hook_ops ip_conntrack_local_out_ops = { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_CONNTRACK }; 这说明netfilter是在连接的第一个包时就建立连接了,这个连接可能是由外部发起的,也可能是由本机发起的,后续包查找连接HASH表找到相应的连接,然后赋值给skb结构中的nfct,这就是resolve_normal_ct()函数的工作: /* On success, returns conntrack ptr, sets skb->nfct and ctinfo */ static inline struct ip_conntrack * resolve_normal_ct(struct sk_buff *skb, // 数据包 struct ip_conntrack_protocol *proto, // 连接协议跟踪,该结构对应协议特殊处理过程,如TCP的状态转换等 int *set_reply, // 返回值,表示该包是否是响应方的包 unsigned int hooknum, enum ip_conntrack_info *ctinfo) { struct ip_conntrack_tuple tuple; struct ip_conntrack_tuple_hash *h; IP_NF_ASSERT((skb->nh.iph->frag_off & htons(IP_OFFSET)) == 0); // 确定该包对应的tuple,对TCP/UDP协议来说就是地址协议端口的5元组 if (!get_tuple(skb->nh.iph, skb->len, &tuple, proto)) return NULL; /* look for tuple match */ // 根据tuple值查找连接HASH h = ip_conntrack_find_get(&tuple, NULL); if (!h) { // 在当前连接表中没找到,说明是新连接的包,初始化新连接 h = init_conntrack(&tuple, proto, skb); if (!h) return NULL; // 该包非法返回NULL,其他错误会返回错误号的负值 if (IS_ERR(h)) return (void *)h; } /* It exists; we have (non-exclusive) reference. */ if (DIRECTION(h) == IP_CT_DIR_REPLY) { // 连接回应方向包 *ctinfo = IP_CT_ESTABLISHED + IP_CT_IS_REPLY; /* Please set reply bit if this packet OK */ // 这个包是响应方的包 *set_reply = 1; } else { // 连接原始方向的包 /* Once we've had two way comms, always ESTABLISHED. */ if (test_bit(IPS_SEEN_REPLY_BIT, &h->ctrack->status)) { DEBUGP("ip_conntrack_in: normal packet for %p\n", h->ctrack); // 如果不是第一个包,设置ESTABLISHED属性,这个位标志表示发现了响应方发的包, // 表示连接可以建立,该标志在ip_conntrack_in()函数中设置 *ctinfo = IP_CT_ESTABLISHED; } else if (test_bit(IPS_EXPECTED_BIT, &h->ctrack->status)) { DEBUGP("ip_conntrack_in: related packet for %p\n", h->ctrack); // 该标志表示是子连接的包,如FTP的数据连接 // 该标志在init_conntrack()函数中设置 *ctinfo = IP_CT_RELATED; } else { DEBUGP("ip_conntrack_in: new packet for %p\n", h->ctrack); // 没有任何标志,是连接的第一个包,设置为NEW属性 *ctinfo = IP_CT_NEW; } // 这个包是发起方的包 *set_reply = 0; } // infos是数量为IP_CT_NUMBER(=5)的数组,分别对应连接发起方向的 // NEW(2)/ESTABLISHED(0)/RELATED(1) // 和连接响应方向的ESTABLISHED(3)/RELATED(4) // 每个skb包都会划归为其中一类, 也就是ctinfo的值 // 每个skb包根据其类型,将其nfct值设为相应infos项的地址 skb->nfct = &h->ctrack->infos[*ctinfo]; return h->ctrack; } 在init_conntrack()函数中将连接的infos值初始化为: ... for (i=0; i < IP_CT_NUMBER; i++) conntrack->infos[i].master = &conntrack->ct_general; ... 也就是infos各项的值都是相同的,没有发现在其他地方重新赋值,所以把所有项实际都是相同的,指向同一个连接。设计之初可能是考虑要区分,但实现时还是只用到一个就行了,在其他地方基本只用到infos[0]进行处理,infos的用处目前只用来判断状态,也就是每一项相对于 infos[0]的偏移值。 最后讨论一下为什么在__ip_conntrack_get()函数中nfct->master值就是连接的地址: __ip_conntrack_get(struct nf_ct_info *nfct, enum ip_conntrack_info *ctinfo) { struct ip_conntrack *ct = (struct ip_conntrack *)nfct->master; ... skb的nfct值是infos数组中某一项的地址,而这些项中的master成员都初始化为连接中ct_general的地址,而ct_general参数是连接结构的第一项参数,所以其地址和连接结构的地址是相同,在Linux内核中,类似用法很多。 5. 结论 在每个skb数据包进入netfilter架构时,netfilter就会给其建立连接,通过简单方法就能找到连接,能区分出发起方、响应方以及第一个包还是后续包,并能识别子连接,从而实现状态检测。 连接结构中的infos数组就目前而言似乎不是很必要,单值就可以,然后增加一个连接状态参数,而不是通过infos的偏移来判断。
发表评论
-
Linux内核中流量控制(24)
2011-01-10 16:33 2213本文档的Copyleft归yfydz所 ... -
Linux内核中流量控制(23)
2011-01-10 16:30 1497本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(22)
2011-01-10 16:29 1946本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(21)
2011-01-10 16:28 1362本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(20)
2011-01-10 16:27 1528本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(19)
2011-01-10 16:27 1984本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(18)
2011-01-10 16:26 1576Linux内核中流量控制(18) ... -
Linux内核中流量控制(17)
2011-01-10 16:25 1955本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(16)
2011-01-10 16:25 1812本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(15)
2011-01-10 16:24 1897本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(14)
2011-01-10 16:23 1964本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(13)
2011-01-10 16:22 2643本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(12)
2011-01-10 16:21 2115本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(11)
2011-01-10 16:21 3243本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(10)
2011-01-10 16:20 2012本文档的Copyleft归yfydz所 ... -
Linux内核中流量控制(9)
2011-01-10 16:19 1838本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(8)
2011-01-10 16:18 1504本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(7)
2011-01-10 16:18 2930本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(6)
2011-01-10 16:17 1500本文档的Copyleft归yfydz所有,使用GPL发布,可以 ... -
Linux内核中流量控制(5)
2011-01-10 16:16 1734本文档的Copyleft归yfydz所有,使用GPL发布,可以 ...
相关推荐
状态检测包过滤技术在Linux下的实现.pdf
基于状态检测的TCP包过滤在Linux下的实现方法.pdf
"Linux环境下入侵检测系统的研究与实现" 本文研究的主要目的是设计和实现Linux环境下的入侵检测系统。入侵检测系统是防火墙的第二道安全闸门,在主动防御方面起着至关重要的作用。系统可以监视和分析用户的各种活动...
使用udev监测usb摄像头状态,并在终端进行显示add和remove,add为添加设备,remove为移除设备。
检测U盘是否挂载成功c语言实现,检测时间5s,通过打开路径,写入和读取同一文件实现
Linux 下具有故障检测与处理的 CAN 驱动设计,该设计基于微处理器 S3C 6410 和 CAN 控制器 M C P 2515,详细分析了 Linux 下 CAN 驱动程序的开发过程、CAN 控制器 M C P 2515 的初始化流程及接口设计,并重点分析了...
基于LINUX的全状态检测包过滤计费网关的研究与实现.pdf
在Linux下对pore文件进行检测 python实现
操作系统课程设计源代码 实现linux系统状态监测
主要为大家详细介绍了用c/c++实现linux下检测网络接口状态,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
华中科技大学-网络空间安全学院-网络安全课程设计,Linux 下状态检测防火墙的设计与实现+源代码+文档说明+实验报告 - 小白不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的课程设计,代码都测试ok...
linux下多线程udp网络编程实现消息驱动状态机流转,同时可实现BUSY检测。
本文研究了一种基于机器视觉与PERCLOS疲劳判定算法相结合的嵌入式疲劳驾驶检测方法,并将其移植到嵌入式Linux操作系统,实现了车载、非接触、低功耗等要求,同时保证了检测的实时性和高效性。 知识点1:嵌入式Linux...
"基于Linux的嵌入式汽车检测装置的设计与实现" 本文主要介绍了基于Linux的嵌入式汽车检测装置的设计与实现。该装置采用Hynix公司生产的以ARM720T为内核的32位RISC微处理器HMS30C7202为核心,运行嵌入式Linux操作...
华中科技大学网络安全课程设计项目,基于Netfilter、Netlink的Linux传输层状态检测防火墙+源代码+文档说明 - 小白不懂运行,下载完可以私聊问,可远程教学 该资源内项目源码是个人的课程设计,代码都测试ok,都是...
该系统基于Linux平台,使用LSM数据源建立隐马尔可夫模型,实现异常检测原型系统。 1. 程序行为异常检测的重要性 程序行为异常检测是计算机安全领域中的一个重要问题。随着计算机系统的普及,恶意攻击和异常行为的...
1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合...
系统地介绍了Linux2 4内核对状态检测包过滤技术的支持机制,并且给出了2.4内核中的一种实现方法,即Netfilter+IPconntrack+ IPtables体系。同时,就Linux2. 4环境中的状态检测包过滤技术无法对某些多连接服务进行...
主要为大家详细介绍了C语言+shell实现linux网卡状态检测,具有一定的参考价值,感兴趣的小伙伴们可以参考一下