原帖由 dreamice 于 2009-3-12 22:23 发表
关键是你拦截在什么地方,包能否走到tcp层?
一个syn包,是不会走到应用层的,只是在内核检查到有应用程序在监听这个端口,那么在tcp层就直接回ack+syn包了,
所以,这个就看你在哪里拦截了,你若在ip层 ...
原帖由 Godbach 于 2009-3-13 09:37 发表
呵呵,其实我这里并不是讨论什么应用。主要就是了解一下这个proxy的实现。
因为在这个代理中,很明显Firewall要负责转换的是client到server的ack号,和server到client的seq号。
如果是这样的话,Fire ...
如果是透明代理,tcp握手阶段,client和proxy之间进行,而真正的通信,proxy只是个中转。
所以,我说应用和我想的不一样
原帖由 richardhesidu 于 2009-3-13 10:32 发表
这样行不行
自己定一个my_sock结构,里面存储源地址,源端口,目标地址,目标端口,差值,skb_buff链表(存储SYN包),连接状态。再创建一个my_sock的hash表。client和firewall第一次握手的时候,创建一个my_s ...
原帖由 dreamice 于 2009-3-13 12:12 发表
老大,你这个实现太复杂了。
现在新版内核也支持透明代理,实现非常简单:client发起和server的连接,被proxy拦截(注意这里是拦截),然后伪装成server和client建立起连接,
连接建立成功以后,proxy在伪 ...
原帖由 richardhesidu 于 2009-3-13 12:59 发表
透明代理的确是一个不错的解决方法。
楼主说的syn proxy跟透明代理还是不同。syn proxy只是对Client和Server之间的三次握手做一个类似的透明代理。建立连接后,数据的传输只是转发而已。
如果纯粹是防SYN F ...
syn proxy只是对Client和Server之间的三次握手做一个类似的透明代理。建立连接后,数据的传输只是转发而已。
双方数据传输的(client)ACK和SYN(server)的正确转换
原帖由 dreamice 于 2009-3-13 12:12 发表
老大,你这个实现太复杂了。
现在新版内核也支持透明代理,实现非常简单:client发起和server的连接,被proxy拦截(注意这里是拦截),然后伪装成server和client建立起连接,
连接建立成功以后,proxy在伪 ...
原帖由 richardhesidu 于 2009-3-13 15:29 发表
好像内核对透明代理的支持,只是内核把数据包forward到一个本地的proxy服务器吧。比如squid。还是内核有了新的功能,可以完全实现代理服务?
原帖由 richardhesidu 于 2009-3-13 15:29 发表
好像内核对透明代理的支持,只是内核把数据包forward到一个本地的proxy服务器吧。比如squid。还是内核有了新的功能,可以完全实现代理服务?
原帖由 Godbach 于 2009-3-13 16:31 发表
看来是我想的复杂了。
我以为Firewall只是把client的报文做一下ACK的修改,然后转发这个报文就可以了。
相反,对于server过来的报文,也做一下SEQ的修改,接着转发就OK了。
原帖由 dreamice 于 2009-3-13 16:11 发表
是的,2.6.28版内核支持这个东东,我做国squid的完全透明代理。
其实内核实现了握手这一系列机制,无非就是我上面说的增加了对非本地IP的目的和源包的处理,以及握手机制。
God兄考虑得太复杂了,你首先 ...
原帖由 dreamice 于 2009-3-13 16:11 发表
是的,2.6.28版内核支持这个东东,我做国squid的完全透明代理。
其实内核实现了握手这一系列机制,无非就是我上面说的增加了对非本地IP的目的和源包的处理,以及握手机制。
God兄考虑得太复杂了,你首先 ...
原帖由 dreamice 于 2009-3-13 17:08 发表
这里要澄清一下,内核只是支持透明代理。
这种代理,肯定是应用层做的事情了,所以,必须要有应用层的软件实现代理才行。
我不知道是不是可以在内核来实现这个代理,理论上是可以的吧。
原帖由 Godbach 于 2009-3-13 16:39 发表
呵呵,是啊。我就觉得按照我的想法,内核是需要维护一个比较大的表的。
那你现在说的这种透明方式在那个版本的内核支持啊。
它对SYN包也是要进行Cookie验证的吧。
原帖由 richardhesidu 于 2009-3-13 17:27 发表
如果纯粹为了解决syn flood的话,用linux+squid的效率还是没有syn-proxy高。
这里要维护的表,远没有维护一个socket的消耗高。
原帖由 richardhesidu 于 2009-3-13 17:27 发表
如果纯粹为了解决syn flood的话,用linux+squid的效率还是没有syn-proxy高。
这里要维护的表,远没有维护一个socket的消耗高。
原帖由 Godbach 于 2009-3-12 17:53 发表
Linux内核中提供了SYN Cookie的检验机制,用来防御SYN Flood攻击。因此,延伸出来的在SYN Cookie Firewall,用来验证SYN连接,并对通过验证报文进行转发。
具体的内容可以参考《SYN Cookie原理及其在Linux内核 ...
PS:我认为,我不让攻击包进入conntrack,在pre_routing之前全处理了,保证进入conntrack的,都是正常的包,就不存在性能方面的问题了吧?哈哈,主要是我比较懒,有现成的不用,我太对不起自己了。
是的,借助于conntrack,可以省很多很多的代码和时间,自己的要实现的话,其实就是实现它其中的一部份功能,核心部件是TCP的状态机的维护(偶承认,偶水平有限,当时看Netfilter的TCP状态机的实现都看了好几天,如果自己写的话——所以说“省很多的时间”)。
比如,欺骗Netfilter的状态检测等等。
还有就是性能问题,因为如果真的发生syn flooding,pps是非常多的。
还有就是ack flooding问题。例如100Mb的syn流量,要构造cookie ack,又是100Mb的回应包,但是众所周知,其中有99%都是不用回应的——这个问题很头痛,可能需要一个数学统计学的模型,My god,以前跟我们上统计学的老师是一个双博士学位的老处女,我对她没有兴趣,所以没有认真听讲,后悔呀!如果你有好的解决方案,一起讨论一下。
原帖由 独孤九贱 于 2009-3-16 11:12 发表
顶楼上,我的意思是说,“在连接跟踪之外做syn cookie,这样,连接跟踪中保存的都是正常数据包的会话,因为数量相对少几个数量级(比起所有包都进来的话),性能问题相对而言,就不那么敏感了!”
原帖由 Godbach 于 2009-3-16 11:15 发表
看来抗synflood和conntrack他俩之间的关系很紧密啊。要是想减轻conntrack的负载,就要在它之前做synflood的防御。如果向方便快捷的实现防御synflood,最好利用conntrack。 唉,矛盾啊
1、首先,在pre_routing挂一个Hook,它监听所有的tcp syn包(这里也可以做一些过滤,比如,只保护指定的目的地址等等,或者是做一个缓存,存下已验证正确的主机等等)。
2、伪造syn+ack,当然,是包含cookie的,因为这个回应的数量级非常之大,所以,效率很重要。
3、凡是收到ack,验证cookie,这里并不需要状态机。只要验证cookie就可以了,这是跟syn proxy最核心的区别了。
4、如果cookie验证不过,就不用多说了。如果过了,就要接下来伪装跟服务器端的三次握手了。这样的包才会被放进conntrack表,最多是需要做点小小的欺骗。
5、两端三次握手OK后,后续数据包都要更改序列号,就是你一开始提的问题,因为序列号保存在ip_conntrack,自己也不用维护状态机,很简单,直接更改,重新计算校验和就行了。
原帖由 独孤九贱 于 2009-3-16 11:40 发表
你看我给你的数据结构应知道了。
通过了cookie验证,则ip_conntrack中的相应自定义字段记录cookie。而通过cookie处理的话,cookie一定是一个定值,否则为0。所以,如果cookie > 0,则应该处理seq,就这样简单噻 ...
原帖由 独孤九贱 于 2009-3-16 13:38 发表
楼上的,你让给服务器的syn请求穿过netfilter连接跟踪表(事实上,如何是使用netfilter的状态跟踪,而不是自己来实现,也应该这样做),这个信息不就有地方存储了吗?
原帖由 独孤九贱 于 2009-3-16 13:38 发表
楼上的,你让给服务器的syn请求穿过netfilter连接跟踪表(事实上,如何是使用netfilter的状态跟踪,而不是自己来实现,也应该这样做),这个信息不就有地方存储了吗?
原帖由 独孤九贱 于 2009-3-16 13:38 发表
楼上的,你让给服务器的syn请求穿过netfilter连接跟踪表(事实上,如何是使用netfilter的状态跟踪,而不是自己来实现,也应该这样做),这个信息不就有地方存储了吗?
原帖由 Godbach 于 2009-3-16 14:24 发表
采用syncookie + conntrack机制的话,个人觉得流程如下可以:
采用syncookie + conntrack机制的话,个人觉得流程如下可以:
(1)在PREROUTING处conntrack前注册syncookie的hook函数。fw完成处理和client端SYN三次握手,同时保存初始的SYN包,并记录cookie值。经过验证之后,将保存的SYN包发给server。
(2)fw发给server的syn包经过conntrack,新建一个conntrack表项,并在报文离开fw时加入连接跟踪表。这里如何获取cookie的值,让(1)模块中提供函数吗?
原帖由 Godbach 于 2009-3-16 15:11 发表
拦截到ACK的时候,fw应该是将原先保留的SYN包发出去,然后这个SYN包就会进入conntrack进行处理了。按理说这个时候新建了conntrack,应该让conntrack记录下之前的cookie值了。
所谓的另一种方法,是针对于SYN-FLOOD的危害的采取的。
SYN-FLOOD主要危害是由于服务器的半开连接消耗较大资源导致的。
所以,我们可以把半开连接处理为完成连接。
也就是,放过SYN和SYN-ACK。伪造一个发送给服务器的ACK,并丢弃原始client的ACK。
这种方法会造成受到SYN-FLOOD攻击的服务器建立大量的连接。
但是防火墙本身的负担小了很多。
原帖由 Godbach 于 2009-3-17 09:48 发表
ShadowStar兄的意思是让在server端建立起来连接。已建立的连接要比半连接节省资源。
但是本身使用fw保护server的,现在反而成了牺牲server保护fw,这样合适吗?
代理的方式在负载较大时,防火墙很容易成为网络的瓶颈,进而崩溃,影响的就不是一台服务器了。
原帖由 Godbach 于 2009-3-17 10:16 发表
不知ShadowStar兄是否已经采用了这种方式,效果怎么样啊?
另外,怎么确定这个SYN连接是攻击报文,而不是正常的请求呢? 因为你是拦截了server的SYN+ACK, 直接构造了ACK报文
欢迎光临 Chinaunix (http://bbs.chinaunix.net/) | Powered by Discuz! X3.2 |