我们如何刺穿中国大防火墙(第2部分)

你好


Nikita再次与您在一起-SEMrush的系统工程师。 在本文中,我继续讲述我们如何为我们的服务semrush.com提供绕过中文防火墙的解决方案。


上一部分中,我告诉:


  • 做出决定后会出现什么问题“我们需要在中国开展服务”
  • 中国互联网有什么问题
  • 为什么我需要ICP许可证
  • 我们如何以及为什么决定使用catchpoint测试我们的测试平台
  • 我们基于Cloudflare中国网络的第一个解决方案的结果是什么
  • 我们如何在DNS Cloudflare中发现错误


在我看来,这部分是最有趣的,因为它专注于登台的特定技术实施。 而且,我们将开始或什至继续使用阿里云


阿里云


阿里云是一个相当大的云提供商,其提供的所有服务使其可以诚实地称自己为云提供商。 他们有机会在外国用户中注册非常好,而且大多数网站都已翻译成英文(对中国而言,这是一种奢侈)。 在这个云中,您可以与世界许多地区,中国大陆以及亚洲海洋(香港,台湾等)合作。


IPSEC


从地理开始。 由于我们的测试站点位于Google Cloud上,因此我们必须将“阿里云”与GCP“链接”,因此我们打开了存在Google的位置列表。 当时,他们在香港还没有自己的数据中心。
最近的地区是Asia-east1 (台湾)。 阿里将cn-shenzhen (深圳)作为中国大陆距离台湾最近的地区。


他们使用terraform描述并提出了GCP和Ali的整个基础架构。 云之间的100 Mbps隧道几乎立即上升。 在深圳和台湾,他们提出了代理虚拟机。 在深圳,用户流量被终止,通过一条通往台湾的隧道进行代理,并从那里直接到达我们在美国东部 (美国东海岸)的服务的外部IP。 在24ms隧道上的虚拟设备之间执行ping操作 ,这还不错。


同时,我们在阿里云DNS中放置了一个测试区域。 将区域委派给NS Ali后,解析时间从470毫秒减少到50毫秒 。 在此之前,该区域还位于Cloudlfare上。


通往Asia-east1的隧道平行,另一条隧道从深圳直接升至us-east4 。 他们在那里创建了更多的代理虚拟机,并开始评估这两种解决方案,使用Cookies或DNS路由测试流量。 下图示意性地描述了测试台:



隧道的延迟如下:
阿里cn深圳<-> GCP asia-east1-24ms
阿里cn深圳<-> GCP us-east4-200ms


Catchpoint浏览器测试报告了出色的性能改进。



比较两种解决方案的测试结果:


解决方案乌梅中位数75%95%
云耀斑86.618岁30秒60年代
安全协议99.7918岁21秒30秒

这是使用通过asia-east1的IPSEC隧道的解决方案数据。 通过us-east4,结果更糟,错误更多,因此我将不给出结果。


根据此测试的结果,两条隧道(其中一条在距中国最近的区域终止,另一条在最终目的地)终止,很明显,尽快从中国防火墙下方“出现”,然后使用快速网络(CDN提供商)非常重要。 ,云提供商等)。 无需费劲就可以穿过防火墙到达目的地。 这不是最快的方法。


通常,结果还不错,但是semrush.com的中位数为8.8s,而75%的百分数为9.4s(在同一测试中)。
在继续之前,我想谈一下题外话。


抒情离题


用户访问www.semrushchina.cn站点 ,该站点通过“快速”中文DNS服务器进行解析,HTTP请求通过了我们的快速解决方案。 答案以相同的方式返回,但是在所有JS脚本,HTML页面和网页的其他元素中,都为域semrush.com指明了呈现页面时必须加载的其他资源。 也就是说,客户端解析www.semrushchina.cn的“ main” A记录并进入快速通道,快速接收响应-一个HTML页面,其中指出:


  • 从sso.semrush.com下载诸如此类的js,
  • 从cdn.semrush.com获取CSS文件,
  • 并从dab.semrush.com拍摄更多照片
  • 等等。

浏览器开始通过这些资源访问“外部” Internet,每次通过防火墙都占用了响应时间。


但是在先前的测试中,当页面上没有semrush.com资源时,只有semrushchina.cn和* .semrushchina.cn被解析到深圳的虚拟机地址,以便稍后进入隧道,才会显示结果


只有这样,您才能通过决策使所有可能的流量快速通过中国防火墙,您才能获得可接受的速度和站点可用性指标,以及可靠的解决方案测试结果。
我们做到了这一点,而无需在团队产品方面进行任何代码编辑。


子过滤器


这个问题浮出水面后,解决方案就诞生了。 我们需要PoC (概念证明),以确保我们的防火墙通过解决方案能够正常运行。 为此,您必须在此解决方案中最大限度地增加到该站点的所有流量。 并且我们在nginx中应用了子过滤器


子过滤器是nginx中一个相当简单的模块,它允许您将响应正文中的一行更改为另一行。 因此,我们将所有出现的semrush.com都更改为semrushchina.cn


并且...这不起作用,因为我们从后端收到了压缩的内容,所以子过滤器找不到必要的行。 我必须在nginx中添加另一个本地服务器,以扩展响应并将其传输到下一个本地服务器,该本地服务器已经在进行行替换,压缩并将其交付给链中的下一个代理。



结果,在客户将收到<subdomain> .semrush.com的地方 ,他将收到<subdomain> .semrushchina.cn并听从了我们的决定。


但是,仅在一个方向上更改域是不够的,因为后端仍然期望semrush.com在客户端的后续请求中。 因此,在同一方向上进行替换的同一台服务器上,我们使用一个简单的正则表达式从请求中获取子域,然后对$ subdomain.semrush.com中设置的$ host变量执行proxy_pass 。 它可能看起来令人困惑,但是可以。 而且效果很好。 对于需要不同逻辑的单个域,它们仅创建服务器块并进行单独的配置。 以下是简化的nginx配置,以简化和演示此方案。


以下配置处理从中国到.semrushchina.cn的所有请求

listen 80; server_name ~^(?<subdomain>[\w\-]+)\.semrushchina.cn$; sub_filter '.semrush.com' '.semrushchina.cn'; sub_filter_last_modified on; sub_filter_once off; sub_filter_types *; gzip on; gzip_proxied any; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; location / { proxy_pass http://127.0.0.1:8083; proxy_set_header Accept-Encoding ""; proxy_set_header Host $subdomain.semrush.com; proxy_set_header X-Accept-Encoding $http_accept_encoding; } } 

此配置在端口83上代理到localhost ,在此等待以下配置:


  listen 127.0.0.1:8083; server_name *.semrush.com; location / { resolver 8.8.8.8 ipv6=off; gunzip on; proxy_pass https://$host; proxy_set_header Accept-Encoding gzip; } } 

同样,这些是裁剪的配置。


这样的东西。 它可能看起来很复杂,但实际上是用语言表达的。 实际上,一切都比蒸萝卜要容易:)


抒情离题的终结


有一阵子,我们很高兴,因为尚未证实IPSEC隧道掉落的神话。 但是后来隧道开始倒塌了。 一天几次,持续几分钟。 有点,但它不适合我们。 由于两个隧道均在同一路由器的Ali端终止,因此我们认为这可能是区域性问题,因此需要增加备用区域。


拿起。 隧道在不同的时间开始下降,但是我们在nginx的上游级别进行了微调的故障转移。 但是随后,隧道几乎同时开始倒塌:) 502和504又开始了,正常运行时间开始恶化,因此我们开始与阿里巴巴CEN (云企业网络)一起制定解决方案。



CEN是来自阿里云内不同区域的两个VPC的连通性,也就是说,您可以将云内任何区域的专用网络相互连接。 最重要的是:此通道具有相当严格的SLA 。 它在速度和正常运行时间上都非常稳定。 但这从未如此简单:


  • 如果您不是中国公民或法人实体,将很难获得
  • 您需要为每兆位的带宽付费。

有了连接中国大陆海外的机会,我们在两个阿里地区( cn-shenzhenus-east-1 (最接近us-east4))之间创建了一个CEN。 在Ali us-east-1中,他们提出了另一个虚拟机以进行另一


原来是这样的:



浏览器测试结果如下:



解决方案乌梅中位数75%95%
云耀斑86.618岁30秒60年代
安全协议99.7918岁21秒30秒
99.7516岁21秒27岁

性能略优于IPSEC。 但是,通过IPSEC,您可以以100 Mbps的速度进行下载,而通过CEN只能以5 Mbps的速度进行下载,而且价格更高。


混合乞求吧? 结合IPSEC速度和CEN稳定性。


这是在IPSEC隧道崩溃的情况下,让流量同时通过IPSEC和CEN进行的操作。 正常运行时间变得更长了,但是网站的加载速度很差。 然后,我画出了我们已经使用和测试的所有方案,并决定尝试向该方案中添加更多的GCP,即GLB


GLB


GLB全局负载平衡器 (或Google Cloud Load Balancer)。 它对我们有一个重要的优势:在CDN的上下文中,它具有任播IP ,可以将流量路由到距离客户端最近的数据中心,因此,流量可以通过“常规” Internet更快,更少地到达快速的Google网络。


不用三思而后行,我们将HTTP / HTTPS LB提升到GCP,并将我们的虚拟机带有子过滤器后端。


有几种方案:


  • 使用Cloudflare中国网络 ,但这一次Origin指定全球GLB IP
  • cn-shenzhen终止客户端,然后从那里立即将代理流量发送到GLB
  • 从中国直奔GLB
  • 终止在cn-shenzhen的客户,从那里通过IPSEC代理到Asia -east1(通过CEN在us-east4中 ),从那里转到GLB(冷静,下面将有图片和说明)

我们测试了所有这些选项以及其他一些混合选项:


  • Cloudflare + GLB


该方案不适用于正常运行时间和DNS错误。 但是测试是在修复CF部分的错误之前进行的,也许现在更好了(但是,这并不排除HTTP超时)。


  • 阿里+ GLB


该方案也不适合我们的正常运行时间,因为由于无法在可接受的时间或超时进行连接,GLB经常从上游掉线,因为对于中国境内的服务器,GLB地址仍在外部,因此位于中国防火墙之后。 魔术没有发生。


  • 仅GLB


一种类似于前一种的变体,只不过它本身未在中国使用服务器:流量立即转到GLB(已更改的DNS记录)。 因此,结果并不令人满意,因为使用普通Internet提供商服务的普通中国客户通过防火墙的情况要比Ali Cloud差得多。


  • 深圳->(CEN / IPSEC)->代理-> GLB


在这里,我们决定使用所有解决方案中最好的:


  • CEN的稳定性和有保证的SLA
  • 来自IPSEC的高速
  • Google的“快速”网络及其任意播出。

该方案如下所示:用户流量在ch-shenzhen的虚拟机上终止。 在此处配置了Nginx上游设置,其中一些是指位于IPSEC隧道另一端的私有IP服务器,而一些上游连接是指向CEN另一端的私有服务器地址。 IPSEC已配置为位于GCP 的Asia-east1地区 (创建解决方案时距中国最近的地区。现在GCP在香港也设有办事处)。 CEN-阿里云中的us-east1地区


此外,来自两端的流量都定向到任播IP GLB ,即到Google存在的最近点,并通过其网络到达GCP中的us-east4区域 ,在该区域中存在替代虚拟机(nginx中带有子过滤器)。


正如我们所期望的,这种混合解决方案使我们能够利用每种技术。 通常,流量通过快速IPSEC,但是如果问题开始出现,我们很快就会在几分钟之内将这些服务器从上游扔出去,并仅通过CEN发送流量,直到隧道稳定为止。


实施了上面列出的第四个解决方案后,我们达到了当时想要的和业务对我们的要求。


与以前的解决方案相比,新解决方案的浏览器测试结果:


解决方案乌梅中位数75%95%
云耀斑86.618岁30秒60年代
安全协议99.7918岁21秒30秒
99.7516岁21秒27岁
CEN / IPsec + GLB99.7913秒16岁25秒

光盘


在我们已实施的解决方案中,一切都很好,但是没有CDN可以在地区甚至城市层面上加速流量。 从理论上讲,这应该通过使用CDN提供程序的快速通信渠道来加快最终用户的站点访问速度。 我们一直在考虑。 现在,该项目下一次迭代的时机已到:在中国搜索和测试CDN提供商。


接下来的最后一部分,我将告诉您:


所有零件


第一部分
第三部分

Source: https://habr.com/ru/post/zh-CN458840/


All Articles