云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

企业邮箱_林州网站建设_怎么买

小七 141 0

这里很拥挤!

我们最近在葡萄牙里斯本举行的2019年Linux管道工大会上做了一个关于使用BPF编程套接字查找的演示。这篇博客文章是对问题陈述和我们提出的解决方案的概述呈现.CC0公共域,px这里我们的边缘服务器很拥挤。我们经营着十几家面向公众的服务机构,撇开所有内部的服务机构场景。快小测验1:你能说出多少人?我们在博客上写了他们!跳转到回答。这些服务暴露在被划分成100多个网络的100多万个选播公共IPv4地址上前缀。到保持统一每个Cloudflare边缘服务器运行所有服务并响应每个选播地址。这使我们能够通过平衡所有机器之间的流量来有效地利用硬件。我们在博客上分享了Cloudflare edge架构的细节以前。同意并非所有服务都在所有地址上工作,而是在其中的一个子集上工作,覆盖一个或多个网络前缀。所以如何设置您的网络服务来监听数百个IP地址,而不将网络堆栈推向边缘?多年来,Cloudflare的工程师们不得不不止一次地问自己这个问题,而随着我们的优势不断发展,答案也发生了变化。这种发展迫使我们寻找创造性的方法来使用berkeleysocketsapi,这是一种用于为应用程序分配网络地址和端口号的POSIX标准。这是一段相当长的旅程,我们还没有结束但是,什么时候生活很简单,一个地址,一个插座(IP地址,端口号)和我们可以想象的服务之间最简单的一对一的关联。服务器在一个已知端口的单个地址上响应客户机请求。要设置它,应用程序必须为它想要支持的每个传输协议(无论是TCP还是UDP)打开一个套接字。像我们的权威DNS这样的网络服务器会打开两个套接字(一个用于UDP,一个用于TCP):(192.0.2.1,53/TCP)⇨("auth DNS",pid=1001,fd=3)(192.0.2.1,53/udp)⇨("身份验证dns",pid=1001,fd=4)要将其扩展到Cloudflare级别,该服务可能必须至少接收到一个/20网络前缀,这是一个IP范围,其中包含4096个地址它。这个转换为为为每个传输协议打开4096个套接字。在查看ss工具输出时不太可能忽视的东西。$sudo ss-ulpn'sport=53'本地状态接收-Q发送-Q地址:端口对等地址:港口…uncon 0 0 192.0.2.40:53 0.0.0:*用户:(("auth dns",pid=77556,fd=11076))uncon 0 0 192.0.2.39:53 0.0.0:*用户:(("auth dns",pid=77556,fd=11075))uncon 0 0 192.0.2.38:53 0.0.0.0:*用户:(("auth dns",pid=77556,fd=11074))uncon 0 0 192.0.2.37:53 0.0.0.0:*用户:(("auth dns",pid=77556,fd=11073))uncon 0 0 192.0.2.36:53 0.0.0.0:*用户:(("auth dns",pid=77556,fd=11072))uncon 0 0 192.0.2.31:53 0.0.0.0:*用户:(("auth dns",pid=77556,fd=11071))…CC BY 2.0,Luca Nebuloni,Flickrth这种方法虽然幼稚,但有一个优势:当来自范围的IP受到UDP洪水攻击时,绑定到其余IP地址的套接字的接收队列不会受到攻击受影响。生活可以更简单-所有地址,一个socketIt似乎相当愚蠢,为一个服务创建这么多的套接字来接收流量在一系列地址上。不仅如此,侦听套接字越多,套接字查找哈希表中的链就越长。我们已经明白,朝这个方向发展会损害数据包处理延迟时间sockets API附带了一个大锤子,它可以让我们的生活变得更轻松——INADDR_ANY aka 0.0.0.0通配符地址。使用INADDR_ANY,我们可以在分配给主机的所有地址上使用单个套接字接收,只指定端口。s=套接字(AF_INET,SOCK_STREAM,0)s、 绑定(('0.0.0.0',12345))s、 听(16)快速测试#2:是否有其他方法将套接字绑定到所有本地地址?跳转到回答。进来换句话说,与天真的"一个地址,一个套接字"方法相比,INADDR iu ANY允许我们为整个IP范围提供一个单一的catch-all侦听套接字,在这个范围内,我们接受传入连接。英寸Linux这是可能的,这要归功于两阶段的侦听套接字查找,在这里,如果更具体的匹配还没有找到了。又一个绑定到0.0.0.0的好处是,我们的应用程序不需要知道我们分配给主机的地址。我们还可以在绑定监听套接字后自由分配或删除地址。在侦听IP范围时,无需重新配置服务更改。打开另一方面,如果我们的服务只监听A.B.C.0/20前缀,那么绑定到所有本地地址就超出了我们的需要。我们可能无意中向外部流量公开了一个只提供内部服务的服务,而没有适当的防火墙或套接字过滤器地点。那么这是安全角度。由于我们现在只有一个套接字,试图淹没服务端口上分配给主机的任何IP的攻击都会命中catch all套接字及其接收队列。在这种情况下,Linux-TCP协议栈支持你,UDP需要特别小心,否则合法流量可能会淹没在大量丢弃的数据中包。可能不过,最大的缺点是监听通配符INADDR iu ANY地址的服务只为自己声明端口号。由于地址已被占用(EADDRINUSE),通过具有特定IP和端口的通配符侦听套接字的绑定失败得很惨bind(4,{sa_family=AF_INET,sin_port=htons(12345),sin_addr=INET_addr("127.0.0.1")},16)=-1 EADDRINUSE(地址已在使用中)除非您的服务是UDP only,否则设置SO\u REUSEADDR socket选项将无法帮助您克服此限制。唯一的出路是求助于SO\u REUSEPORT,它通常用于构造负载平衡套接字组。只有当您足够幸运地以同一用户(UID)运行端口冲突服务时,才会出现这种情况。这是另一个故事发帖。快测试3:当存在绑定冲突时,设置soreuseaddr套接字选项是否有任何效果?跳转到回答。生活实际情况是一个端口,两个服务,在Cloudflare边缘,我们提供共享相同端口号的主机服务,但是在不重叠的IP范围内响应请求。这种端口共享的一个突出例子是我们的1.1.1.1递归DNS解析程序,它与我们提供给所有人的权威DNS服务并排运行可悲的是顾客socketsapi不允许我们表示两个服务共享一个端口并接受不相交IP上的请求的设置范围。但是,如Linux开发历史所示,任何网络API限制都可以通过引入一个新的socket选项来克服,该选项有60多个可用选项(而且还在计数!)。输入SO_BINDTOPREFIX.背面2016年,我们提出了对Linux网络堆栈的扩展。它允许服务将通配符绑定的套接字约束到属于网络前缀的IP范围net1,plen1='127.0.0.0',20bindprefix1=结构包('bbbbb xxx',*inet_aton(net1),阻燃1)s1=套接字(AF_INET,SOCK_STREAM,0)s1.setsockopt(SOL_-IP,IP-BINDTOPREFIX,bindprefix1)s1.绑定(('0.0.0.0',1234))听(1)#服务2,127.0.16.0/20,1234/tcpnet2,plen2='127.0.16.0',20bindprefix2=结构包('bbbbb xxx',*inet_aton(net2),阻燃2)s2=套接字(AF_INET,SOCK_STREAM,0)s2.setsockopt(SOL iu IP,IP_BINDTOPREFIX,bindprefix2)s2.绑定(('0.0.0.0',1234))s2.听(1)从那时起,这一机制对我们起到了很好的作用。不幸的是,由于对我们的用例过于具体,它没有被上游接受。没有更好的选择,我们最终在内核中维护了这个补丁白天。生活变得复杂了-所有的端口,一个服务就在我们以为事情解决的时候,我们面临着一个新的挑战。如何构建一个接受65535端口上的连接的服务?最终的反向代理,如果你愿意的话,代码是光谱。这个当syssocket调用端口映射时,它提供了一个非常灵活的端口映射。您可以指定所需的号码,也可以让网络堆栈为您选择一个未使用的号码。没有对应的INADDR_ANY,一个通配符值来选择所有端口(INPORT_ANY?)。为了达到我们想要的效果,我们不得不求助于TPROXY,一个Netfilter/iptables扩展,用于拦截前向路径上的远程目标流量。然而,我们使用它来引导本地目的包,即针对我们主机的数据包,以捕获所有端口插座.iptables-t-mangle-I预路由\-d 192.0.2.0/24-p tcp\-j TPROXY--on ip=127.0.0.1--on port=1234基于TPROXY的设置是有代价的。对于初学者,您的服务需要提升特权来创建一个特殊的catch all套接字(请参阅IP_TRANSPARENT socket选项)。然后,您还必须了解并考虑TPROXY和您的流量配置文件的接收路径之间的微妙交互,对于示例:does连接跟踪寄存器用TPROXY重定向的流?使用TPROXY时,在SYN flood期间侦听套接字争用是否值得关注?网络堆栈的其他部分,比如XDP程序,是否需要了解TPROXY重定向数据包?这些是我们需要回答的一些问题,在投入生产一段时间后,我们对使用TPROXY的后果有了一个很好的了解是的。那他说,如果明天我们能发现一些关于TPROXY的新东西,那就不会让人吃惊了。由于它的复杂性,我们一直认为使用它来引导本地目的地流量是一种黑客行为,一种超出其预期应用程序的用例。不管人们如何理解,黑客攻击仍然是黑客。可以BPF让生活更轻松?尽管TPROXY的性质很复杂,但它向我们展示了一些重要的东西。不管监听套接字绑定到哪个IP或端口,只要有网络堆栈的支持,我们就可以引导任何连接到它。只要应用程序准备好处理这种情况工作。快点测验4:真的没有问题吗