Kumusta Habr, ang pangalan ko ay Ilya, nagtatrabaho ako sa pangkat ng platform sa Exness. Binubuo at ipinapatupad namin ang mga pangunahing bahagi ng imprastraktura na ginagamit ng aming mga team sa pagbuo ng produkto.
Sa artikulong ito, nais kong ibahagi ang aking karanasan sa pagpapatupad ng naka-encrypt na teknolohiyang SNI (ESNI) sa imprastraktura ng mga pampublikong website.
Ang paggamit ng teknolohiyang ito ay magpapataas ng antas ng seguridad kapag nagtatrabaho sa isang pampublikong website at sumusunod sa mga panloob na pamantayan ng seguridad na pinagtibay ng Kumpanya.
Una sa lahat, nais kong ituro na ang teknolohiya ay hindi pamantayan at nasa draft pa rin, ngunit sinusuportahan na ito ng CloudFlare at Mozilla (sa
Isang kaunting teorya
ESNI ay isang extension sa TLS 1.3 protocol na nagbibigay-daan sa SNI encryption sa TLS handshake na "Client Hello" na mensahe. Narito ang hitsura ng Client Hello sa suporta ng ESNI (sa halip na ang karaniwang SNI na nakikita natin sa ESNI):
Upang magamit ang ESNI, kailangan mo ng tatlong bahagi:
- DNS;
- Suporta sa kliyente;
- Suporta sa gilid ng server.
DNS
Kailangan mong magdagdag ng dalawang tala ng DNS β AAt TXT (Ang tala ng TXT ay naglalaman ng pampublikong key kung saan maaaring i-encrypt ng kliyente ang SNI) - tingnan sa ibaba. Bilang karagdagan, dapat mayroong suporta DoH (DNS over HTTPS) dahil hindi pinapagana ng mga available na kliyente (tingnan sa ibaba) ang suporta sa ESNI nang walang DoH. Ito ay lohikal, dahil ang ESNI ay nagpapahiwatig ng pag-encrypt ng pangalan ng mapagkukunan na aming ina-access, iyon ay, walang saysay na i-access ang DNS sa UDP. Bukod dito, ang paggamit
Kasalukuyang magagamit
CloudFlare
Π entry:
curl 'https://dns.google.com/resolve?name=www.cloudflare.com&type=A'
-s -H 'accept: application/dns+json'
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "www.cloudflare.com.",
"type": 1
}
],
"Answer": [
{
"name": "www.cloudflare.com.",
"type": 1,
"TTL": 257,
"data": "104.17.210.9"
},
{
"name": "www.cloudflare.com.",
"type": 1,
"TTL": 257,
"data": "104.17.209.9"
}
]
}
TXT record, ang kahilingan ay nabuo ayon sa isang template _esni.FQDN:
curl 'https://dns.google.com/resolve?name=_esni.www.cloudflare.com&type=TXT'
-s -H 'accept: application/dns+json'
{
"Status": 0,
"TC": false,
"RD": true,
"RA": true,
"AD": true,
"CD": false,
"Question": [
{
"name": "_esni.www.cloudflare.com.",
"type": 16
}
],
"Answer": [
{
"name": "_esni.www.cloudflare.com.",
"type": 16,
"TTL": 1799,
"data": ""/wEUgUKlACQAHQAg9SiAYQ9aUseUZr47HYHvF5jkt3aZ5802eAMJPhRz1QgAAhMBAQQAAAAAXtUmAAAAAABe3Q8AAAA=""
}
],
"Comment": "Response from 2400:cb00:2049:1::a29f:209."
}
Kaya, mula sa pananaw ng DNS, dapat nating gamitin ang DoH (mas mabuti na may DNSSEC) at magdagdag ng dalawang entry.
Suporta sa Customer
Kung pinag-uusapan natin ang tungkol sa mga browser, sa ngayon
Siyempre, dapat gamitin ang TLS 1.3 upang suportahan ang ESNI, dahil ang ESNI ay isang extension sa TLS 1.3.
Para sa layunin ng pagsubok sa backend na may suporta sa ESNI, ipinatupad namin ang kliyente sa go, Ngunit higit pa tungkol diyan mamaya.
Suporta sa gilid ng server
Sa kasalukuyan, ang ESNI ay hindi sinusuportahan ng mga web server tulad ng nginx/apache, atbp., dahil gumagana ang mga ito sa TLS sa pamamagitan ng OpenSSL/BoringSSL, na hindi opisyal na sumusuporta sa ESNI.
Samakatuwid, nagpasya kaming gumawa ng sarili naming front-end na bahagi (ESNI reverse proxy), na susuportahan ang TLS 1.3 na pagwawakas sa ESNI at proxy HTTP(S) na trapiko sa upstream, na hindi sumusuporta sa ESNI. Pinapayagan nito ang teknolohiya na magamit sa isang umiiral nang imprastraktura, nang hindi binabago ang mga pangunahing bahagi - iyon ay, gamit ang kasalukuyang mga web server na hindi sumusuporta sa ESNI.
Para sa kalinawan, narito ang isang diagram:
Tandaan ko na ang proxy ay idinisenyo na may kakayahang wakasan ang isang koneksyon sa TLS nang walang ESNI, upang suportahan ang mga kliyente na walang ESNI. Gayundin, ang protocol ng komunikasyon sa upstream ay maaaring HTTP o HTTPS na may bersyon ng TLS na mas mababa sa 1.3 (kung hindi sinusuportahan ng upstream ang 1.3). Nagbibigay ang scheme na ito ng maximum na flexibility.
Pagpapatupad ng suporta sa ESNI sa go hiniram namin
Para makabuo ng mga ESNI key na ginamit namin
Sinubukan namin ang build gamit ang go 1.13 sa Linux (Debian, Alpine) at MacOS.
Ang ilang mga salita tungkol sa mga tampok sa pagpapatakbo
Nagbibigay ang ESNI reverse proxy ng mga sukatan sa format na Prometheus, gaya ng rps, upstream latency at mga response code, nabigo/matagumpay na TLS handshake at TLS handshake na tagal. Sa unang tingin, ito ay tila sapat upang suriin kung paano pinangangasiwaan ng proxy ang trapiko.
Nagsagawa din kami ng pagsubok sa pagkarga bago gamitin. Mga resulta sa ibaba:
wrk -t50 -c1000 -d360s 'https://esni-rev-proxy.npw:443' --timeout 15s
Running 6m test @ https://esni-rev-proxy.npw:443
50 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.77s 1.21s 7.20s 65.43%
Req/Sec 13.78 8.84 140.00 83.70%
206357 requests in 6.00m, 6.08GB read
Requests/sec: 573.07
Transfer/sec: 17.28MB
Nagsagawa kami ng puro qualitative load testing para ikumpara ang scheme gamit ang ESNI reverse proxy at wala. "Ibinuhos" namin ang trapiko nang lokal upang maalis ang "panghihimasok" sa mga intermediate na bahagi.
Kaya, sa suporta ng ESNI at pag-proxy sa upstream mula sa HTTP, nakakuha kami ng humigit-kumulang ~550 rps mula sa isang pagkakataon, na may average na pagkonsumo ng CPU/RAM ng ESNI reverse proxy:
- 80% Paggamit ng CPU (4 vCPU, 4 GB RAM host, Linux)
- 130 MB Mem RSS
Para sa paghahambing, ang RPS para sa parehong nginx upstream na walang TLS (HTTP protocol) na pagwawakas ay ~ 1100:
wrk -t50 -c1000 -d360s 'http://lb.npw:80' β-timeout 15s
Running 6m test @ http://lb.npw:80
50 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 1.11s 2.30s 15.00s 90.94%
Req/Sec 23.25 13.55 282.00 79.25%
393093 requests in 6.00m, 11.35GB read
Socket errors: connect 0, read 0, write 0, timeout 9555
Non-2xx or 3xx responses: 8111
Requests/sec: 1091.62
Transfer/sec: 32.27MB
Ang pagkakaroon ng mga timeout ay nagpapahiwatig na may kakulangan ng mga mapagkukunan (gumamit kami ng 4 na vCPU, 4 GB RAM host, Linux), at sa katunayan ang potensyal na RPS ay mas mataas (nakatanggap kami ng mga figure na hanggang 2700 RPS sa mas malakas na mapagkukunan).
Sa konklusyon, tandaan ko mukhang promising ang teknolohiyang ESNI. Marami pa ring bukas na tanong, halimbawa, ang mga isyu sa pag-imbak ng pampublikong ESNI key sa DNS at pag-ikot ng ESNI key - ang mga isyung ito ay aktibong tinatalakay, at ang pinakabagong bersyon ng ESNI draft (sa oras ng pagsulat) ay nasa
Pinagmulan: www.habr.com