Hai
Nikita bersama Anda lagi - seorang insinyur sistem dari SEMrush . Dan dengan artikel ini, saya melanjutkan kisah tentang bagaimana kami menemukan solusi untuk mem-bypass Firewall Cina untuk layanan kami semrush.com.
Pada bagian sebelumnya saya katakan:
- masalah apa yang muncul setelah keputusan dibuat "Kita perlu membuat layanan kami bekerja di Cina"
- masalah apa yang dimiliki Internet Cina
- mengapa saya memerlukan lisensi ICP
- bagaimana dan mengapa kami memutuskan untuk menguji bangku tes kami menggunakan catchpoint
- apa hasil dari solusi pertama kami berdasarkan Cloudflare China Network
- bagaimana kami menemukan bug di DNS Cloudflare

Bagian ini menurut saya paling menarik, karena berfokus pada implementasi teknis spesifik pementasan. Dan kami akan mulai, atau lebih tepatnya melanjutkan, dengan Alibaba Cloud .
Cloud Alibaba
Alibaba Cloud adalah penyedia cloud yang cukup besar, yang memiliki semua layanan yang memungkinkannya untuk dengan jujur ββmenyebut dirinya penyedia cloud. Sangat baik bahwa mereka memiliki kesempatan untuk mendaftar dengan pengguna asing, dan bahwa sebagian besar situs telah diterjemahkan ke dalam bahasa Inggris (untuk China itu sebuah kemewahan). Di cloud ini, Anda dapat bekerja dengan banyak wilayah di dunia, daratan Cina, serta Samudra Asia (Hong Kong, Taiwan, dll.).
IPSEC
Dimulai dengan geografi. Karena situs pengujian kami berlokasi di Google Cloud, kami harus "menautkan" Alibaba Cloud dengan GCP, jadi kami membuka daftar lokasi di mana Google hadir. Pada saat itu, mereka belum memiliki pusat data sendiri di Hong Kong.
Wilayah terdekat adalah asia-east1 (Taiwan). Ali memiliki cn-shenzhen (Shenzhen) sebagai wilayah terdekat dari daratan Cina ke Taiwan.
Menggunakan terraform, mereka menggambarkan dan mengangkat seluruh infrastruktur di GCP dan Ali. Terowongan 100 Mbps di antara awan naik hampir seketika. Di sisi Shenzhen dan Taiwan mereka mengangkat mesin virtual proxy. Di Shenzhen, lalu lintas pengguna diakhiri, diproyeksikan melalui terowongan ke Taiwan, dan dari sana langsung menuju ke IP eksternal dari layanan kami di us-east (Pantai Timur Amerika Serikat). Ping antara virtual di terowongan 24ms , yang tidak terlalu buruk.
Pada saat yang sama, kami menempatkan zona pengujian di Alibaba Cloud DNS . Setelah mendelegasikan zona ke NS Ali, waktu penyelesaian menurun dari 470 ms ke 50 ms . Sebelum ini, zona itu juga di Cloudlfare.
Sejalan dengan terowongan ke asia-east1 , terowongan lain dibesarkan dari Shenzhen langsung ke kami-east4 . Di sana mereka menciptakan lebih banyak mesin virtual proksi dan mulai mengukur kedua solusi, merutekan lalu lintas pengujian menggunakan Cookie atau DNS. Bangku tes secara skematis dijelaskan pada gambar berikut:

Latensi untuk terowongan adalah sebagai berikut:
Ali cn-shenzhen <--> GCP asia-east1 - 24ms
Ali cn-shenzhen <--> GCP us-east4 - 200ms
Tes browser Catchpoint telah melaporkan peningkatan kinerja luar biasa.

Bandingkan hasil tes untuk dua solusi:
Ini adalah solusi data menggunakan terowongan IPSEC melalui asia-east1 . Melalui kami-east4, hasilnya lebih buruk, dan ada lebih banyak kesalahan, jadi saya tidak akan memberikan hasilnya.
Menurut hasil tes ini, dua terowongan, satu di antaranya diakhiri di wilayah terdekat dengan China, dan yang lainnya di tujuan akhir, menjadi jelas bahwa penting untuk "muncul" dari bawah firewall Cina sesegera mungkin, dan kemudian menggunakan jaringan cepat (penyedia CDN) , penyedia cloud, dll.). Tidak perlu mencoba satu langkah untuk pergi melalui firewall dan sampai ke tujuan. Ini bukan cara tercepat.
Secara umum, hasilnya tidak buruk, bagaimanapun, semrush.com memiliki median 8,8 dan 75 Persen dari 9,4 (pada tes yang sama).
Dan sebelum melanjutkan, saya ingin melakukan penyimpangan.
Penyimpangan liris
Setelah pengguna mengunjungi situs www.semrushchina.cn , yang diselesaikan melalui server DNS China "cepat", permintaan HTTP melewati solusi cepat kami. Jawabannya dikembalikan dengan cara yang sama, tetapi di semua skrip JS, halaman HTML, dan elemen lain dari halaman web, domain semrush.com diindikasikan untuk sumber daya tambahan yang harus dimuat saat merender halaman. Artinya, klien menyelesaikan "utama" catatan www.semrushchina.cn dan masuk ke terowongan cepat, dengan cepat menerima respons - halaman HTML yang menyatakan:
- unduh js ini dan itu dari sso.semrush.com,
- Ambil file CSS dari cdn.semrush.com,
- dan ambil lebih banyak gambar dari dab.semrush.com
- dan sebagainya.
Browser mulai masuk ke Internet "eksternal" untuk sumber daya ini, setiap kali melewati firewall memakan waktu respons.
Tetapi dalam pengujian sebelumnya, hasilnya disajikan ketika tidak ada sumber daya semrush.com pada halaman, hanya semrushchina.cn , dan * .semrushchina.cn diselesaikan ke alamat mesin virtual di Shenzhen untuk masuk ke terowongan nanti.
Hanya dengan cara ini, melemparkan semua lalu lintas yang mungkin melalui keputusan Anda untuk dengan cepat melewati firewall Cina secara maksimal, Anda bisa mendapatkan kecepatan dan indikator ketersediaan situs yang dapat diterima, serta hasil uji solusi yang jujur.
Kami melakukan ini tanpa mengedit kode tunggal di sisi produk tim.
Subfilter
Solusinya lahir segera setelah masalah ini muncul. Kami membutuhkan PoC (Bukti Konsep) bahwa solusi firewall pass kami benar-benar berfungsi dengan baik. Untuk melakukan ini, Anda harus memaksimalkan semua lalu lintas ke situs dalam solusi ini. Dan kami menerapkan subfilter di nginx.
Subfilter adalah modul yang cukup sederhana dalam nginx yang memungkinkan Anda untuk mengubah satu baris dalam tubuh respons ke baris lain. Jadi kami mengubah semua kemunculan semrush.com menjadi semrushchina.cn dalam semua jawaban.
Dan ... ini tidak berhasil, karena kami menerima konten terkompresi dari backend, sehingga subfilter tidak dapat menemukan baris yang diperlukan. Saya harus menambahkan server lokal lain ke nginx, yang memperluas respons dan mengirimkannya ke server lokal berikutnya, yang sudah terlibat dalam penggantian jalur, kompresi, dan pengiriman ke proksi berikutnya dalam rantai.

Akibatnya, di mana klien akan menerima <subdomain> .semrush.com , ia akan menerima <subdomain> .semrushchina.cn dan dengan patuh mengikuti keputusan kami.
Namun, tidak cukup hanya dengan mengubah domain dalam satu arah, karena para backend masih mengharapkan semrush.com dalam permintaan berikutnya dari klien. Dengan demikian, pada server yang sama di mana penggantian dilakukan dalam satu arah, menggunakan ekspresi reguler sederhana kita mendapatkan subdomain dari permintaan, dan kemudian melakukan proxy_pass dengan variabel host $ ditetapkan dalam $ subdomain.semrush.com . Ini mungkin tampak membingungkan, tetapi berhasil. Dan itu bekerja dengan baik. Untuk masing-masing domain yang memerlukan logika berbeda, mereka cukup membuat blok server mereka dan membuat konfigurasi terpisah. Di bawah ini adalah nginx config yang disingkat untuk kejelasan dan demonstrasi skema ini.
Konfigurasi berikut memproses semua permintaan dari Cina ke .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; } }
Konfigurasi ini diproksikan ke localhost di port 83, dan di sana menunggu konfigurasi berikut:
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; } }
Sekali lagi, ini adalah konfigurasi yang dipotong.
Sesuatu seperti itu. Ini mungkin terlihat rumit, tetapi dalam kata-kata. Bahkan, semuanya lebih mudah daripada lobak kukus :)
Akhir dari penyimpangan lirik
Untuk sementara, kami senang karena mitos terowongan IPSEC yang jatuh belum dikonfirmasi. Tapi kemudian terowongan mulai turun. Beberapa kali sehari selama beberapa menit. Sedikit, tapi itu tidak cocok untuk kita. Karena kedua terowongan diakhiri di sisi Ali pada router yang sama, kami memutuskan bahwa mungkin ini adalah masalah regional dan kami perlu meningkatkan wilayah cadangan.
Dijemput. Terowongan mulai jatuh pada waktu yang berbeda, tetapi kami memiliki failover fine-tuned di tingkat hulu di nginx. Tapi kemudian terowongan mulai turun pada waktu yang hampir bersamaan :) Dan lagi, 502 dan 504. Waktu kerja mulai memburuk, jadi kami mulai mengerjakan opsi dengan Alibaba CEN (Cloud Enterprise Network).
Cen
CEN adalah konektivitas dua VPC dari berbagai daerah di dalam Alibaba Cloud, yaitu, Anda dapat menghubungkan jaringan pribadi dari setiap wilayah di dalam cloud satu sama lain. Dan yang paling penting: saluran ini memiliki SLA yang agak ketat. Ini sangat stabil baik dalam kecepatan maupun waktu aktif. Tapi itu tidak pernah sesederhana itu:
- SANGAT sulit didapat jika Anda bukan warga negara Tiongkok atau badan hukum,
- Anda perlu membayar untuk setiap megabit bandwidth.
Memiliki kesempatan untuk menghubungkan China Daratan dan Luar Negeri , kami menciptakan CEN antara dua wilayah Ali: cn-shenzhen dan us-east-1 (titik terdekat dengan kami-east4). Di Ali us-east-1, mereka mengangkat mesin virtual lain untuk mendapatkan hop lain.
Ternyata seperti ini:

Hasil pengujian browser di bawah ini:

Performanya sedikit lebih baik daripada IPSEC. Tetapi melalui IPSEC Anda berpotensi mengunduh dengan kecepatan 100 Mbps, dan melalui CEN hanya pada kecepatan 5 Mbps dan lebih mahal.
Hibrida memohon, kan? Kombinasikan kecepatan IPSEC dan stabilitas CEN.
Inilah yang kami lakukan dengan membiarkan lalu lintas melalui IPSEC dan CEN jika terjadi tabrakan terowongan IPSEC. Waktu kerja telah menjadi jauh lebih tinggi, tetapi kecepatan pemuatan situs buruk. Kemudian saya menggambar semua skema yang telah kami gunakan dan uji, dan memutuskan untuk mencoba menambahkan sedikit lebih banyak GCP ke skema ini, yaitu GLB .
GLB
GLB adalah Penyeimbang Beban Global (atau Google Cloud Load Balancer). Ini memiliki keuntungan penting bagi kami: dalam konteks CDN ia memiliki IP siaran , yang memungkinkan Anda untuk merutekan lalu lintas ke pusat data yang paling dekat dengan klien, berkat lalu lintas yang mencapai jaringan Google cepat lebih cepat dan lebih sedikit melalui Internet "normal".
Tanpa berpikir dua kali, kami menaikkan HTTP / HTTPS LB ke GCP dan menempatkan mesin virtual kami dengan backfilter subfilter.
Ada beberapa skema:
- Gunakan Cloudflare China Network , tapi kali ini Origin menentukan GLB IP global.
- Hentikan klien di cn-shenzhen , dan dari sana proxy lalu lintas segera ke GLB .
- Langsung dari Tiongkok ke GLB .
- Hentikan klien di cn-shenzhen , dari sana proxy ke asia-east1 via IPSEC (di us-east4 via CEN), dari sana pergi ke GLB (dengan tenang, akan ada gambar dan penjelasan di bawah)
Kami menguji semua opsi ini dan beberapa opsi hybrid lainnya:

Skema ini tidak sesuai dengan kami untuk kesalahan waktu kerja dan DNS. Tetapi tes ini dilakukan sebelum memperbaiki bug pada bagian CF, mungkin sekarang lebih baik (namun, ini tidak mengecualikan timeout HTTP).

Skema ini juga tidak sesuai untuk kita uptime, karena GLB sering keluar dari hulu karena ketidakmungkinan menghubungkan pada waktu atau batas waktu yang dapat diterima, karena untuk server di dalam China, alamat GLB tetap di luar, dan oleh karena itu, di belakang firewall Cina. Keajaiban itu tidak terjadi.

Varian yang mirip dengan yang sebelumnya, hanya saja tidak menggunakan server di Cina sendiri: lalu lintas langsung menuju GLB (mengubah catatan DNS). Dengan demikian, hasilnya tidak memuaskan, karena pelanggan Cina biasa yang menggunakan layanan penyedia Internet biasa memiliki situasi yang jauh lebih buruk dengan melewati firewall daripada Ali Cloud.
- Shenzhen -> (CEN / IPSEC) -> Proxy -> GLB

Di sini kami memutuskan untuk menggunakan yang terbaik dari semua solusi:
- stabilitas dan SLA dijamin dari CEN
- kecepatan tinggi dari IPSEC
- Jaringan "cepat" Google dan siaran apa pun.
Skemanya terlihat seperti ini: lalu lintas pengguna diakhiri pada mesin virtual di ch-shenzhen . Pengaturan hulu Nginx dikonfigurasi di sana, beberapa di antaranya merujuk ke server IP pribadi yang terletak di ujung lain terowongan IPSEC, dan beberapa koneksi hulu ke alamat server pribadi di sisi lain CEN. IPSEC dikonfigurasikan ke wilayah asia-east1 di GCP (itu adalah wilayah terdekat dengan China pada saat solusi dibuat. Sekarang GCP juga telah hadir di Hong Kong). CEN - ke wilayah us-east1 di Ali Cloud.
Lebih jauh, lalu lintas dari kedua ujungnya diarahkan ke IP GLB siaran mana pun, yaitu ke titik terdekat keberadaan Google, dan pergi melalui jaringannya ke wilayah us-east4 di GCP, di mana terdapat mesin virtual pengganti (dengan subfilter di nginx).
Solusi hibrida ini, seperti yang kami harapkan, memungkinkan kami untuk memanfaatkan setiap teknologi. Secara umum, lalu lintas melewati IPSEC cepat, tetapi jika masalah dimulai, kami dengan cepat dan selama beberapa menit membuang server ini dari hulu dan mengirim lalu lintas melalui CEN hanya sampai terowongan stabil.
Setelah menerapkan solusi ke-4 dari daftar di atas, kami mencapai apa yang kami inginkan dan apa yang diminta oleh bisnis kami saat itu.
Hasil pengujian browser untuk solusi baru dibandingkan dengan yang sebelumnya:
Cdn
Semuanya bagus dalam solusi yang telah kami terapkan, tetapi tidak ada CDN yang dapat mempercepat lalu lintas di tingkat daerah dan bahkan kota. Secara teori, ini harus mempercepat situs untuk pengguna akhir melalui penggunaan saluran komunikasi cepat dari penyedia CDN. Dan kami memikirkannya sepanjang waktu. Dan sekarang, saatnya telah tiba untuk iterasi proyek berikutnya: mencari dan menguji penyedia CDN di Cina.
Dan saya akan memberi tahu Anda tentang ini di bagian selanjutnya, akhir :)
Semua bagian
Bagian 1
Bagian 3