Como rompemos o gran firewall chinés (parte 2)

Ola!

Nikita está contigo de novo, unha enxeñeira de sistemas da empresa SEMrush. E con este artigo sigo coa historia de como chegamos a unha solución alternativa Firewall chinés para o noso servizo semrush.com.

В parte anterior Eu dixen:

  • que problemas xorden despois de tomar a decisión "Necesitamos que o noso servizo funcione en China"
  • Que problemas ten Internet chinesa?
  • por que precisa unha licenza ICP?
  • como e por que decidimos probar os nosos bancos de probas con Catchpoint
  • cal foi o resultado da nosa primeira solución baseada en Cloudflare China Network
  • Como atopamos un erro en Cloudflare DNS

Esta parte é a máis interesante, na miña opinión, porque se centra en implementacións técnicas específicas da posta en escena. E comezaremos, ou mellor dito, continuaremos Alibaba Cloud.

Alibaba Cloud

Alibaba Cloud é un provedor de nube bastante grande, que ten todos os servizos que lle permiten chamarse honestamente provedor de nube. É bo que teñan a oportunidade de rexistrarse para usuarios estranxeiros e que a maior parte do sitio estea traducido ao inglés (para China é un luxo). Nesta nube, podes traballar con moitas rexións do mundo, China continental e Asia oceánica (Hong Kong, Taiwán, etc.).

IPSEC

Comezamos pola xeografía. Dado que o noso sitio de proba estaba situado en Google Cloud, necesitabamos "vincular" Alibaba Cloud con GCP, polo que abrimos unha lista de localizacións nas que Google está presente. Nese momento aínda non tiñan o seu propio centro de datos en Hong Kong.
A rexión máis próxima resultou ser asia-leste 1 (Taiwán). Alí resultou ser a rexión da China continental máis próxima a Taiwán cn-shenzhen (Shenzhen).

Con terraform describiu e levantou toda a infraestrutura en GCP e Ali. Un túnel de 100 Mbit/s entre as nubes subiu case ao instante. Do lado de Shenzhen e Taiwán, levantáronse máquinas virtuais proxy. En Shenzhen, o tráfico de usuarios finaliza, envíase un proxy a través dun túnel a Taiwán e desde alí vai directamente á IP externa do noso servizo en us-leste (Costa Este dos EUA). Facer ping entre máquinas virtuais a través dun túnel 24ms, que non está tan mal.

Ao mesmo tempo, colocamos unha zona de proba Alibaba Cloud DNS. Despois de delegar a zona en NS Ali, o tempo de resolución diminuíu de 470 ms a ms 50. Antes disto, a zona tamén estaba en Cloudlfare.

Paralelo ao túnel para asia-leste 1 levantou outro túnel de Shenzhen directamente a us-leste4. Alí crearon máis máquinas virtuais proxy e comezaron a probar ambas solucións, enrutando o tráfico de proba mediante Cookies ou DNS. O banco de probas descríbese esquemáticamente na seguinte figura:

A latencia dos túneles resultou ser a seguinte:
Ali cn-shenzhen <—> GCP asia-east1 — 24 ms
Ali cn-shenzhen <—> GCP us-east4 — 200 ms

As probas do navegador Catchpoint informaron de excelentes melloras.

Compare os resultados das probas para dúas solucións:

decisión
Uptime
Mediana
75 percentil
95 percentil

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

Estes son datos dunha solución que usa un túnel IPSEC vía asia-leste 1. A través de nós-east4 os resultados foron peores, e houbo máis erros, así que non vou dar os resultados.

En base aos resultados desta proba de dous túneles, un dos cales remata na rexión máis próxima a China e o outro no destino final, quedou claro que é importante "surgir" debaixo do firewall chinés o máis rápido posible. posible e, a continuación, use redes rápidas (provedores de CDN, provedores de nube, etc.). Non hai necesidade de tentar atravesar o firewall e chegar ao seu destino dun só golpe. Este non é o xeito máis rápido.

En xeral, os resultados non son malos, con todo, semrush.com ten unha mediana de 8.8 segundos e un percentil 75 de 9.4 segundos (na mesma proba).
E antes de seguir adiante, gustaríame facer unha pequena digresión lírica.

Digresión lírica

Despois de que o usuario entre no sitio www.semrushchina.cn, que se resolve mediante servidores DNS chineses "rápidos", a solicitude HTTP pasa pola nosa solución rápida. A resposta devólvese polo mesmo camiño, pero o dominio especifícase en todos os scripts JS, páxinas HTML e outros elementos da páxina web semrush.com para recursos adicionais que se deben cargar cando se renderiza a páxina. É dicir, o cliente resolve o rexistro A "principal". www.semrushchina.cn e entra no túnel rápido, recibe rapidamente unha resposta: unha páxina HTML que indica:

  • descarga tal ou tal js de sso.semrush.com,
  • Obtén os ficheiros CSS de cdn.semrush.com,
  • e tamén tira algunhas fotos de dab.semrush.com
  • e así por diante.

O navegador comeza a ir á Internet "externa" para estes recursos, pasando cada vez por un firewall que consume o tempo de resposta.

Pero a proba anterior mostra os resultados cando non hai recursos na páxina semrush.comsemrushchina.cn, e *.semrushchina.cn resolve o enderezo da máquina virtual en Shenzhen para despois entrar no túnel.

Só deste xeito, empurrando ao máximo todo o tráfico posible a través da súa solución para pasar rapidamente o firewall chinés, pode obter velocidades aceptables e indicadores de dispoñibilidade do sitio web, así como resultados honestos das probas da solución.
Fixémolo sen unha soa edición de código no lado do produto do equipo.

Subfiltro

A solución naceu case inmediatamente despois de que xurdiu este problema. Necesitabamos PoC (Proba de concepto) que as nosas solucións de penetración de firewall funcionan realmente ben. Para iso, cómpre envolver todo o tráfico do sitio nesta solución na medida do posible. E aplicamos subfiltro en nginx.

Subfiltro é un módulo bastante sinxelo en nginx que che permite cambiar unha liña do corpo da resposta a outra liña. Así que cambiamos todas as ocorrencias semrush.com en semrushchina.cn en todas as respostas.

E... non funcionou porque recibimos contido comprimido dos backends, polo que o subfiltro non atopou a liña requirida. Tiven que engadir outro servidor local a nginx, que descomprimiu a resposta e pasouna ao seguinte servidor local, que xa estaba ocupado substituíndo a cadea, comprimindoa e enviándoa ao seguinte servidor proxy da cadea.

Como resultado, onde recibiría o cliente .semrush.com, recibiu .semrushchina.cn e obedecimos a nosa decisión.

Non obstante, non abonda con simplemente cambiar o dominio dun xeito, porque os backends aínda esperan que semrush.com en solicitudes posteriores do cliente. En consecuencia, no mesmo servidor onde se fai a substitución unidireccional, mediante unha simple expresión regular obtemos o subdominio da solicitude e despois facemos pase_proxy con variable $host, exposto en $subdomain.semrush.com. Pode parecer confuso, pero funciona. E funciona ben. Para dominios individuais que requiren unha lóxica diferente, simplemente cree os seus propios bloques de servidor e realice unha configuración separada. Abaixo amósanse as configuracións de nginx acurtadas para claridade e demostración deste esquema.

A seguinte configuración procesa todas as solicitudes de China para .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;
    }
}

Esta configuración proxy para localhost ao porto 83, e a seguinte configuración está esperando alí:

    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;
    }
}

Repito, estas son configuracións recortadas.

Así. Pode parecer complicado, pero é en palabras. De feito, todo é máis sinxelo que os grelos ao vapor :)

Fin da digresión

Durante un tempo estivemos contentos porque o mito sobre a caída de túneles IPSEC non estaba confirmado. Pero entón os túneles comezaron a caer. Varias veces ao día durante uns minutos. Un pouco, pero iso non nos cabía. Dado que ambos túneles terminaron no lado de Ali no mesmo enrutador, decidimos que quizais este era un problema rexional e necesitabamos elevar a rexión de reserva.

Eles colleron. Os túneles comezaron a fallar en diferentes momentos, pero a conmutación por fallo funcionou ben para nós a nivel ascendente en nginx. Pero entón os túneles comezaron a caer aproximadamente ao mesmo tempo 🙂 E comezaron de novo os 502 e 504. O tempo de actividade comezou a deteriorarse, polo que comezamos a traballar na opción con Alibaba CEN (Cloud Enterprise Network).

CEN

CEN - Esta é a conectividade de dúas VPC de diferentes rexións dentro de Alibaba Cloud, é dicir, podes conectar entre si redes privadas de calquera rexión da nube. E o máis importante: esta canle ten unha canle bastante estrita SLA. É moi estable tanto en velocidade como en tempo de actividade. Pero nunca é tan sinxelo:

  • é MOI difícil de obter se non es cidadáns chineses ou unha persoa xurídica,
  • Debes pagar por cada megabit de capacidade da canle.

Ter a oportunidade de conectarse China continental и no exterior, creamos un CEN entre dúas rexións de Ali: cn-shenzhen и us-leste-1 (punto máis próximo a nós-leste4). En Ali us-leste-1 levantou outra máquina virtual para que haxa unha máis salto.

Resultou así:

Os resultados da proba do navegador están a continuación:

decisión
Uptime
Mediana
75 percentil
95 percentil

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

O rendemento é lixeiramente mellor que IPSEC. Pero a través de IPSEC podes descargar potencialmente a unha velocidade de 100 Mbit/s, e a través de CEN só a unha velocidade de 5 Mbit/s e máis.

Parece un híbrido, non? Combina velocidade IPSEC e estabilidade CEN.

Isto é o que fixemos, permitindo o tráfico tanto a través de IPSEC como de CEN en caso de falla no túnel IPSEC. O tempo de actividade foi moito maior, pero a velocidade de carga do sitio aínda deixa moito que desexar. Despois debuxei todos os circuítos que xa tiñamos usados ​​e probados, e decidín tentar engadir un pouco máis de GCP a este circuíto, é dicir. gorra.

gorra

gorra - É Balanceador de carga global (ou Google Cloud Load Balancer). Ten unha vantaxe importante para nós: no contexto dunha CDN que ten IP anycast, que che permite dirixir o tráfico ao centro de datos máis próximo ao cliente, para que o tráfico ingrese rapidamente á rede rápida de Google e pase menos pola Internet "normal".

Sen pensalo dúas veces, plantexamos HTTP/HTTPS LB Instalamos as nosas máquinas virtuais con subfiltro en GCP e como backend.

Había varios esquemas:

  • Usa Rede Cloudflare China, pero esta vez Origin debería especificar global IP GLB.
  • Cancelar clientes en cn-shenzhen, e desde alí proxy o tráfico directamente a gorra.
  • Vaia directamente desde China a gorra.
  • Cancelar clientes en cn-shenzhen, desde alí proxy para asia-leste 1 vía IPSEC (en us-leste4 vía CEN), de aí vai a GLB (con calma, haberá unha imaxe e explicación a continuación)

Probamos todas estas opcións e varias máis híbridas:

  • Cloudflare + GLB

Este esquema non nos conveña debido ao tempo de actividade e aos erros de DNS. Pero a proba levouse a cabo antes de que se corrixese o erro no lado CF, quizais agora sexa mellor (non obstante, isto non exclúe os tempos de espera HTTP).

  • Ali + GLB

Este esquema tampouco nos axeitaba en termos de tempo de actividade, xa que GLB a miúdo caía fóra da liña ascendente debido á imposibilidade de conectarse nun tempo ou tempo de espera aceptable, porque para un servidor dentro de China, o enderezo GLB permanece fóra e, polo tanto, detrás do Firewall chinés. A maxia non ocorreu.

  • Só GLB

Unha opción similar á anterior, só que non utilizaba servidores na propia China: o tráfico ía directamente a GLB (modificáronse os rexistros DNS). En consecuencia, os resultados non foron satisfactorios, xa que os clientes chineses comúns que utilizan os servizos de provedores de Internet comúns teñen unha situación moito peor ao pasar o firewall que Ali Cloud.

  • Shenzhen -> (CEN/IPSEC) -> Proxy -> GLB

Aquí decidimos usar a mellor de todas as solucións:

  • estabilidade e SLA garantido por CEN
  • alta velocidade de IPSEC
  • A rede "rápida" de Google e o seu anycast.

O esquema ten un aspecto así: o tráfico de usuarios remata nunha máquina virtual en ch-shenzhen. Alí están configurados os fluxos ascendentes de Nginx, algúns dos cales apuntan a servidores IP privados situados no outro extremo do túnel IPSEC e outros apuntan a enderezos privados dos servidores do outro lado do CEN. IPSEC configurado para a rexión asia-leste 1 en GCP (era a rexión máis próxima a China no momento en que se creou a solución. GCP agora tamén ten presenza en Hong Kong). CEN - á rexión us-leste1 en Ali Cloud.

Despois dirixiuse o tráfico desde ambos os dous extremos anycast IP GLB, é dicir, ata o punto de presenza máis próximo de Google, e pasou polas súas redes ata a comarca us-leste4 en GCP, no que había máquinas virtuais de substitución (con subfiltro en nginx).

Esta solución híbrida, como esperabamos, aproveitou as vantaxes de cada tecnoloxía. En xeral, o tráfico pasa por IPSEC rápido, pero se comezan os problemas, expulsamos estes servidores de forma rápida e durante uns minutos e enviamos tráfico só a través do CEN ata que o túnel se estabilice.

Ao implementar a cuarta solución da lista anterior, conseguimos o que queriamos e o que a empresa requiría de nós nese momento.

Resultados das probas do navegador para a nova solución en comparación coas anteriores:

decisión
Uptime
Mediana
75 percentil
95 percentil

Cloudflare
86.6
18s
30s
60s

IPsec
99.79
18s
21s
30s

CEN
99.75
16s
21s
27s

CEN/IPsec + GLB
99.79
13s
16s
25s

CDN

Todo está ben na solución que implementamos, pero non hai ningunha CDN que poida acelerar o tráfico a nivel rexional e mesmo de cidade. En teoría, isto debería acelerar o sitio para os usuarios finais utilizando as canles de comunicación rápidas do provedor de CDN. E pensabamos niso todo o tempo. E agora chegou o momento da seguinte iteración do proxecto: buscar e probar provedores de CDN en China.

E falareivos disto na seguinte parte final :)

Fonte: www.habr.com

Engadir un comentario