TPROXY之殇-NAT设备加署理的后果51CTO博客 - 众发娱乐

TPROXY之殇-NAT设备加署理的后果51CTO博客

2019-01-03 15:17:37 | 作者: 代萱 | 标签: 设备,署理,效劳 | 浏览: 1878

一段往事无独有偶,过了N多年,又到了这个时分,碰到了相同的作业...
xx年的万圣节,由于效劳器瘫痪咱们被罚了500块钱,终究发现瘫痪的原因是TPROXY形成的,其时每个大效劳区有一台LVS负载均衡设备,作业在NAT形式下,下联一台中心交换机,中心交换机分出N条线路去往各小区域效劳器群,每一个小区域效劳群具有一台TPROXY完成的登录署理效劳器,仅仅对登录数据包做署理,其它的包直接经过。
作业发作在晚上8点左右,咱们其时均在加班,值勤客服接到很多的投诉电话,说是效劳器无法登录...咱们立刻停下手头的新作业,投入到抢险榜首线,经过简略排查,很快发现是LVS的端口竭尽导致,可是排查出它为何竭尽却用来一晚上的时刻,到了次日早上7点多,我打车回家,路上正碰到上班高峰期,将近9点半才到家,路上根本都在睡觉。到家今后开端写剖析文档,下午3点又去了公司(公司规矩,假如发作通宵加班,次日上午能够回家歇息一上午,下午3点假如不请假则有必要正式上班,不然算矿工...)只为了提交上午写的文档,其实原本想请假的,这才回了家,不然爽性就在公司了,可是作业严重,只能忍着,6点开端开会,一向开到9点灰头土脸的回家,期间说了涉事者每人罚款500元的事...依照那次的陈述,提出了锥形设备以及倒锥型布置的概念,也正是本文要说的。
本次的作业和我的联系并不大,也没有谁被罚款,实际上我早就换了作业。我仅仅依据现场支撑的搭档们的描绘,回想起了我的那段往事,觉得挺共同,就写了篇文章。说实话,几年下来,我在协议栈的层次下跌了,其时的我尽管对IP路由等不是很了解,可是对TCP的细节的掌握却非常好,现在我诚心的觉得遇到瓶颈了...
开篇之前再说几句题外话:榜首,为什么不论我换了作业仍是搬了家,公司离家的间隔都是那么的远,不论是租的房子仍是买的房子,不论是榜首家公司仍是现在的公司,我的打车费用都是110元到130元之间!第二,其时的公司怎样就不必***呢?要是用了,我必定不会再跑回公司去提交什么文档。
1.通明署理所谓的通明署理是针对客户端和效劳器端两方面来讲的,关于客户端来讲,建议衔接时衔接的效劳端是实在的效劳器而不是署理效劳器,关于效劳器端来讲,收到的恳求来自实在客户端而不是署理效劳器。当然这其中有移花接木的进程,全部仅仅是看起来很通明罢了。
2.TPROXYTPROXY是Linux体系上完成通明署理的首选,它利用了Linux网络的利器-Netfilter完成了一些target,比方TPROXY,别的还有一个socket match用于捕获效劳器回来的数据包,确保它们能够再回到署理效劳器应用程序。
值得留意的是,装备TPROXY一定要确保文件翻开描绘符的数量足够大,由于署理效劳要创立很多的socket,每一个socket对应一个文件描绘符。
2.1.IP_TRANSPARENT选项IP_TRANSPARENT能够完成很奇特的作业,即,它能够bind一个不归于本机的IP地址,作为客户端,它能够运用一个不归于本机地址的IP地址作为源IP建议衔接,作为效劳端,它能够侦听在一个不归于本机的IP地址上,而这正是通明署理一切必要的。面临实在的客户端,通明署理明知道方针地址不是自己,却仍是要承受衔接,关于实在的效劳器,通明署理显着不是实在的客户端,却还要运用实在客户端的地址建议衔接。
2.2.截获数据捕获数据便是把原本不应发给这台设备的数据捕获到这台设备的应用层。办法太多了,用ebtables,iptables,战略路由,不论是二层形式仍是路由形式,捕获数据都不是问题,详细到细节,还得需求应用层参加,由于数据抵达第四层的时分,会去查socket,也便是说有必要得有一个socket和数据包相关起来,而一个socket又和一个应用程序相关,终究,一个数据包被捕获后,发给一个应用程序!
2.2.1.NAT方法应用层启用一个效劳,侦听一个端口,运用iptables的DNAT或许REDIRECT这些target能够将数据包定向到本机应用程序。此刻假如你运用netstat检查,看到的方针地址将是本机socket侦听的地址。
2.2.2.纯TPROXY方法即便不必NAT,也能够经过TPROXY target和战略路由的方法将数据包捕获,首要需求界说一条iptables规矩:
-A PREROUTING -p tcp -m tcp --dport 80 -j TPROXY --on-port 0 --on-ip 0.0.0.0 --tproxy-mark 100
界说一条rule以及路由:
ip rule add fwmark 100 tab proxy
ip route add local 0.0.0.0/0 dev lo tab proxy
如此一来,不论你发给哪个IP地址的抵达80端口的TCP衔接,均将被捕获,比方署理效劳器的地址是192.168.100.100,而你发包的方针地址是1.2.3.4,只需数据包抵达这台机器,均会被捕获到应用层。这是怎样回事呢?运用IP_TRANSPARENT选项能够侦听恣意IP或许一切IP,当你侦听一切IP的时分,作用就出现了,只需下面代码便能够测验:
struct sockaddr_in addr = {0};
int opt = 1;
fd = socket(AF_INET,SOCK_STREAM,0);
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
setsockopt(fd,SOL_IP, TRANSPARENT,&opt,sizeof(opt));
bind(fd,(struct sockaddr *)(&addr),sizeof(struct sockaddr));
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
listen(fd,5);
尽管本机根本就没有1.2.3.4这个地址,可是假如你在另一台机器上telnet 1.2.3.4 80,确保数据包经过192.168.100.100后,照样能够连通。
3.tuple空间一个tuple代表了一个socket衔接,在一台机器上,在一个命名空间内,tuple有必要是仅有的,由于体系要区别一个数据要发给谁而不应发给谁。一般来说,tuple仅有性由第四层来确保,可是在规划的时分,由于NAT这种锥形行为运用了第四层的信息,因而NAT以及ip_conntrack也要确保tuple的仅有性。详细一点说,一个TCP的tuple包含了4元组:源IP地址,源端口号,方针IP地址,方针端口号。
4.布置问题作为一个署理程序,TPROXY要一起扮演客户端和效劳器的功用,它一般布置在客户端和效劳器的中心,遍及的布置拓扑为沙漏型布置,如下图所示:


留意,布置了TPROXY署理之后,tuple空间并没有什么丢失,由于客户端IP地址调集非常大,效劳器IP地址空间也不小,因而TPROXY署理的确认化侦听端口并不会带来什么丢失,此处有一个默许条件,一般的效劳都是侦听熟知端口,因而并不存在很多的端口的状况,端口和IP地址的数量不对称性是要害。
4.1.沙漏布置典型的,如通明署理,负载均衡设备,IPS,IDS,防火墙等,作业在三层或许七层通明形式下的布置都是沙漏布置,七层形式比三层/二层形式更耗费tuple空间,可是在效劳器端都是熟知端口的状况下,能够疏忽这种丢失。
4.2.锥形设备相似NAT设备,NAT形式下的负载均衡设备,这些都归于锥形设备,所谓的锥形设备便是将一个以IP为标识的tuple元素映射成一个以IP-端口对为标识的tuple元组的设备,比方NAT设备能够将不同的IP地址映射成一个IP地址,然后用不同的端口来区别。
简略点说,锥形设备便是将区别源IP,复用源端口改为了复用源IP,区别源端口,可是这种转化是不对称的,由于IP地址空间有32位,端口地址空间有16位,锥形转化一定会带来tuple空间的缩小,在方针效劳为熟知端口的状况下,这种缩小更为严重,这便是说,源地址转化根本都是发作在出口方位而不是发作在进口方位的。为何效劳会偏好熟知端口,由于效劳的命名空间是战略化的,和效劳的IP地址空间显着不同,端口很难经过相似DNS来检索,记住,IP和效劳联系并不大,它仅仅为了寻址,效劳的根本性的标识便是端口!
所以,由于这种端口和IP地址空间的不对称性,在面临不同IP地址的相同端口的效劳时,锥形设备并不会削减多少tuple空间的巨细,可是一旦锥形设备和效劳之间连续七层形式的沙漏设备时,就会带来tuple空间的敏捷坍缩!由于七层形式下,一个效劳必定要绑定一个确认的端口,然后抵消掉前面锥形设备的端口发散作用。
4.3.倒锥形布置所谓的倒锥形布置便是将锥形设备和七层形式沙漏设备串行结合在一起的布置方法,比方锥形NAT设备后边接一个TPROXY署理设备。这会带来什么问题呢?很显然,有必要在署理设备上确保tuple的仅有性,为了确保这个仅有性,不得不支付一些价值,价值便是牺牲掉很多的tuple空间。也便是说,尽管锥形设备靠端口确保了tuple仅有性,可是锥形设备和沙漏设备串接在一起的时分,由于独自的沙漏设备也要坚持tuple仅有性,因而就会抵消掉锥形设备的端口发散作用。锥形设备不是用端口来确保仅有性吗?紧接着的沙漏设备刚好也要这样,就会引起抵触,如下图所示:


试想一下,以往的一对多的衔接被一对一的衔接替代,咱们即便都用IP-端口对,tuple空间也会减小!现在看一下究竟是什么引发了倒锥型现象!
4.4.NAT方法-地址束缚前面提到过,能够经过方针NAT的方法将数据包导入本地七层,这样的结果便是很多的实在效劳器的IP地址映射成了少数的本机IP地址,原本能够用相同的锥形设备的IP地址和锥形设备的源端口拜访不同的效劳器的衔接,此刻不得不运用不同的锥形设备的源端口。留意,即便TPROXY前面的锥形设备运用了相同的源端口,也会被TPROXY的NAT模块改成不同的端口,由于TPROXY设备要确保tuple仅有性。这会导致什么问题呢?TPROXY上的端口将会快速被竭尽,使得前面的锥形设备不得不运用不同的端口才干衔接成功,这就会导致前面锥形设备的端口快速缭绕。
或许你懂得比较多,会说,我能够多增加几个DNAT,乃至运用port range,那么请问,关于前者,面临众多的客户端地址空间,你在你的一块网卡上加多少IP地址算多呢?关于后者,面临众多的实在客户端的地址空间,你又能树立多少个效劳呢?这种主意当然能够缓解倒锥的压力,可是在很多短衔接的状况下,很多的TIME_WAIT状况的socket会占有很多的tuple空间。或许关于较真儿的同学,他们会说,有一种TCP的优化,关于客户端初始序列号单调递加的景象,效劳端的TIME_WAIT套接字能够重用。面临这样的人,我供认,我输了,我玩不过这些学院派,可是我面临的这台署理效劳器并没有完成这个优化!
4.5.纯TPROXY方法-端口束缚NAT居然带来这么多的问题,那好吧,我不必NAT,运用纯TPROXY的方法来截获实在前端锥形设备发来的数据包可好?和NAT方法不同的是,纯TPROXY方法并没有任何的本机IP地址参加,因而本机IP地址也不会占有任何tuple空间的元素,这难道不是把问题处理了吗?是的,在侦听熟知端口的状况下,和前端锥形设备之间的抵触看似处理了,可是和后端效劳器的抵触却开端了。假定后端效劳器均是侦听80端口的WEB效劳,你在TPROXY上也运用IP_TRANSPARENT选项侦听一切地址的80,此刻一个来自锥形设备的衔接被捕获,此tuple将被记录在TPROXY体系内,此刻TPROXY需求初始化一个抵达实在效劳器的衔接,为了tuple仅有性,它将不能运用锥形设备建议端的源端口,而不得不运用别的一个端口,计算下来,一半的恳求将无法接入。
4.6.优化我只能说,最好别优化。在我被罚款的那次,我优化了,由于我知道我的效劳器和客户端的行为,这些都是咱们自己开发的,我当然能够统揽大局,可是关于你把控不了大局的状况下,最好仍是坚持现状。我的优化方法是,纯TPROXY和NAT混合运用。


版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表众发娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章