ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ื”ืืชืจ ื”ืฆื™ื‘ื•ืจื™ ืฉืœืš ืขื ESNI

ืฉืœื•ื ื”ื‘ืจ, ืฉืžื™ ืื™ืœื™ื”, ืื ื™ ืขื•ื‘ื“ ื‘ืฆื•ื•ืช ื”ืคืœื˜ืคื•ืจืžื” ื‘ืืงืกื ืก. ืื ื• ืžืคืชื—ื™ื ื•ืžื™ื™ืฉืžื™ื ืืช ืจื›ื™ื‘ื™ ื”ืชืฉืชื™ืช ื”ืžืจื›ื–ื™ื™ื ืฉื‘ื”ื ืžืฉืชืžืฉื™ื ืฆื•ื•ืชื™ ืคื™ืชื•ื— ื”ืžื•ืฆืจื™ื ืฉืœื ื•.

ื‘ืžืืžืจ ื–ื”, ื‘ืจืฆื•ื ื™ ืœื—ืœื•ืง ืืช ื”ื ื™ืกื™ื•ืŸ ืฉืœื™ ื‘ื™ื™ืฉื•ื ื˜ื›ื ื•ืœื•ื’ื™ื™ืช SNI ืžื•ืฆืคื ืช (ESNI) ื‘ืชืฉืชื™ืช ืฉืœ ืืชืจื™ื ืฆื™ื‘ื•ืจื™ื™ื.

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ื”ืืชืจ ื”ืฆื™ื‘ื•ืจื™ ืฉืœืš ืขื ESNI

ื”ืฉื™ืžื•ืฉ ื‘ื˜ื›ื ื•ืœื•ื’ื™ื” ื–ื• ื™ื’ื‘ื™ืจ ืืช ืจืžืช ื”ืื‘ื˜ื—ื” ื‘ืขื‘ื•ื“ื” ืขื ืืชืจ ืฆื™ื‘ื•ืจื™ ื•ื™ืขืžื•ื“ ื‘ืชืงื ื™ ืื‘ื˜ื—ื” ืคื ื™ืžื™ื™ื ืฉืื•ืžืฆื• ืขืœ ื™ื“ื™ ื”ื—ื‘ืจื”.

ืงื•ื“ื ื›ืœ, ืื ื™ ืจื•ืฆื” ืœืฆื™ื™ืŸ ืฉื”ื˜ื›ื ื•ืœื•ื’ื™ื” ืื™ื ื” ืกื˜ื ื“ืจื˜ื™ืช ื•ืขื“ื™ื™ืŸ ื ืžืฆืืช ื‘ื˜ื™ื•ื˜ื”, ืื‘ืœ CloudFlare ื•ืžื•ื–ื™ืœื” ื›ื‘ืจ ืชื•ืžื›ื•ืช ื‘ื” (ื‘ ื˜ื™ื•ื˜ื” 01). ื–ื” ื”ื ื™ืข ืื•ืชื ื• ืœื ื™ืกื•ื™ ื›ื–ื”.

ืงืฆืช ืชื™ืื•ืจื™ื”

ESNI ื”ื•ื ื”ืจื—ื‘ื” ืœืคืจื•ื˜ื•ืงื•ืœ TLS 1.3 ื”ืžืืคืฉืจ ื”ืฆืคื ืช SNI ื‘ื”ื•ื“ืขืช ืœื—ื™ืฆืช ื”ื™ื“ ืฉืœ TLS "Client Hello". ื›ืš ื ืจืื” Client Hello ืขื ืชืžื™ื›ืช ESNI (ื‘ืžืงื•ื ื”-SNI ื”ืจื’ื™ืœ ืื ื• ืจื•ืื™ื ืืช ESNI):

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ื”ืืชืจ ื”ืฆื™ื‘ื•ืจื™ ืฉืœืš ืขื ESNI

 ื›ื“ื™ ืœื”ืฉืชืžืฉ ื‘-ESNI, ืืชื” ืฆืจื™ืš ืฉืœื•ืฉื” ืจื›ื™ื‘ื™ื:

  • DNS; 
  • ืชืžื™ื›ืช ืœืงื•ื—ื•ืช;
  • ืชืžื™ื›ื” ื‘ืฆื“ ื”ืฉืจืช.

DNS

ืขืœื™ืš ืœื”ื•ืกื™ืฃ ืฉืชื™ ืจืฉื•ืžื•ืช DNS - Aื• - TXT (ืจืฉื•ืžืช ื”-TXT ืžื›ื™ืœื” ืืช ื”ืžืคืชื— ื”ืฆื™ื‘ื•ืจื™ ืฉื‘ืขื–ืจืชื• ื”ืœืงื•ื— ื™ื›ื•ืœ ืœื”ืฆืคื™ืŸ SNI) - ืจืื” ืœื”ืœืŸ. ื‘ื ื•ืกืฃ, ื—ื™ื™ื‘ืช ืœื”ื™ื•ืช ืชืžื™ื›ื” DoH (DNS ืขืœ HTTPS) ืžื›ื™ื•ื•ืŸ ืฉืœืงื•ื—ื•ืช ื–ืžื™ื ื™ื (ืจืื” ืœื”ืœืŸ) ืื™ื ื ืžืืคืฉืจื™ื ืชืžื™ื›ืช ESNI ืœืœื DoH. ื–ื” ื”ื’ื™ื•ื ื™, ืžื›ื™ื•ื•ืŸ ืฉ-ESNI ืžืจืžื–ืช ืขืœ ื”ืฆืคื ื” ืฉืœ ืฉื ื”ืžืฉืื‘ ืฉืืœื™ื• ืื ื—ื ื• ื ื™ื’ืฉื™ื, ื›ืœื•ืžืจ, ืื™ืŸ ื˜ืขื ืœื’ืฉืช ืœ-DNS ื“ืจืš UDP. ื™ืชืจ ืขืœ ื›ืŸ, ื”ืฉื™ืžื•ืฉ DNSSEC ืžืืคืฉืจ ืœืš ืœื”ื’ืŸ ืžืคื ื™ ื”ืชืงืคื•ืช ื”ืจืขืœืช ืžื˜ืžื•ืŸ ื‘ืชืจื—ื™ืฉ ื–ื”.

ื–ืžื™ืŸ ื›ืจื’ืข ืžืกืคืจ ืกืคืงื™ DoH, ื‘ื™ื ื™ื”ื:

CloudFlare ืžืฆื”ื™ืจ (ื‘ื“ื•ืง ืืช ื”ื“ืคื“ืคืŸ ืฉืœื™ โ†’ SNI ืžื•ืฆืคืŸ โ†’ ืœืžื™ื“ืข ื ื•ืกืฃ) ืฉื”ืฉืจืชื™ื ืฉืœื”ื ื›ื‘ืจ ืชื•ืžื›ื™ื ื‘-ESNI, ื›ืœื•ืžืจ, ืขื‘ื•ืจ ืฉืจืชื™ CloudFlare ื‘-DNS ื™ืฉ ืœื ื• ืœืคื—ื•ืช ืฉืชื™ ืจืฉื•ืžื•ืช - A ื•-TXT. ื‘ื“ื•ื’ืžื” ืฉืœืžื˜ื” ืื ื• ืžื‘ืฆืขื™ื ืฉืื™ืœืชื•ืช ืฉืœ Google DNS (ืขืœ HTTPS): 

ะ ื›ึผึฐื ึดื™ืกึธื”:

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 ืจืฉื•ืžื”, ื”ื‘ืงืฉื” ื ื•ืฆืจืช ืขืœ ืคื™ ืชื‘ื ื™ืช _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."
}

ืื–, ืžื ืงื•ื“ืช ืžื‘ื˜ ืฉืœ DNS, ืขืœื™ื ื• ืœื”ืฉืชืžืฉ ื‘-DoH (ืจืฆื•ื™ ืขื DNSSEC) ื•ืœื”ื•ืกื™ืฃ ืฉื ื™ ืขืจื›ื™ื. 

ืฉื™ืจื•ืช ืœืงื•ื—ื•ืช

ืื ืื ื—ื ื• ืžื“ื‘ืจื™ื ืขืœ ื“ืคื“ืคื ื™ื, ืื– ื›ืจื’ืข ื”ืชืžื™ื›ื” ืžื™ื•ืฉืžืช ืจืง ื‘-Firefox. ื›ืืŸ ืœื”ืœืŸ ื”ื•ืจืื•ืช ื›ื™ืฆื“ ืœื”ืคืขื™ืœ ืืช ืชืžื™ื›ืช ESNI ื•-DoH ื‘-Firefox. ืœืื—ืจ ื”ื’ื“ืจืช ื”ื“ืคื“ืคืŸ, ืื ื• ืืžื•ืจื™ื ืœืจืื•ืช ืžืฉื”ื• ื›ื–ื”:

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ื”ืืชืจ ื”ืฆื™ื‘ื•ืจื™ ืฉืœืš ืขื ESNI

ืงืฉืจ ื›ื“ื™ ืœื‘ื“ื•ืง ืืช ื”ื“ืคื“ืคืŸ.

ื›ืžื•ื‘ืŸ, ื™ืฉ ืœื”ืฉืชืžืฉ ื‘-TLS 1.3 ื›ื“ื™ ืœืชืžื•ืš ื‘-ESNI, ืžื›ื™ื•ื•ืŸ ืฉ-ESNI ื”ื™ื ื”ืจื—ื‘ื” ืœ-TLS 1.3.

ืœืฆื•ืจืš ื‘ื“ื™ืงืช ื”-backend ืขื ืชืžื™ื›ืช ESNI, ื”ื˜ืžืขื ื• ืืช ื”ืœืงื•ื— ื‘- go, ืื‘ืœ ืขืœ ื›ืš ื‘ื”ืžืฉืš.

ืชืžื™ื›ื” ื‘ืฆื“ ื”ืฉืจืช

ื ื›ื•ืŸ ืœืขื›ืฉื™ื•, ESNI ืื™ื ื• ื ืชืžืš ืขืœ ื™ื“ื™ ืฉืจืชื™ ืื™ื ื˜ืจื ื˜ ื›ืžื• nginx/apache ื•ื›ื•', ืžื›ื™ื•ื•ืŸ ืฉื”ื ืขื•ื‘ื“ื™ื ืขื TLS ื“ืจืš OpenSSL/BoringSSL, ืฉืื™ื ื ืชื•ืžื›ื™ื ื‘-ESNI ื‘ืื•ืคืŸ ืจืฉืžื™.

ืœื›ืŸ, ื”ื—ืœื˜ื ื• ืœื™ืฆื•ืจ ืจื›ื™ื‘ ื—ื–ื™ืชื™ ืžืฉืœื ื• (ESNI reverse proxy), ืืฉืจ ื™ืชืžื•ืš ื‘ืกื™ื•ื TLS 1.3 ืขื ืชืขื‘ื•ืจืช ESNI ื•-proxy HTTP(S) ืœ-upstream, ืฉืื™ื ื• ืชื•ืžืš ื‘-ESNI. ื–ื” ืžืืคืฉืจ ืฉื™ืžื•ืฉ ื‘ื˜ื›ื ื•ืœื•ื’ื™ื” ื‘ืชืฉืชื™ืช ืฉื›ื‘ืจ ืงื™ื™ืžืช, ืžื‘ืœื™ ืœืฉื ื•ืช ืืช ื”ืžืจื›ื™ื‘ื™ื ื”ืขื™ืงืจื™ื™ื โ€“ ื›ืœื•ืžืจ, ืฉื™ืžื•ืฉ ื‘ืฉืจืชื™ ืื™ื ื˜ืจื ื˜ ืงื™ื™ืžื™ื ืฉืื™ื ื ืชื•ืžื›ื™ื ื‘-ESNI. 

ืœืฉื ื”ื‘ื”ื™ืจื•ืช, ื”ื ื” ืชืจืฉื™ื:

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ื”ืืชืจ ื”ืฆื™ื‘ื•ืจื™ ืฉืœืš ืขื ESNI

ืื ื™ ืžืฆื™ื™ืŸ ืฉื”ืคืจื•ืงืกื™ ืชื•ื›ื ืŸ ืขื ื”ื™ื›ื•ืœืช ืœืกื™ื™ื ื—ื™ื‘ื•ืจ TLS ืœืœื ESNI, ื›ื“ื™ ืœืชืžื•ืš ื‘ืœืงื•ื—ื•ืช ืœืœื ESNI. ื›ืžื• ื›ืŸ, ืคืจื•ื˜ื•ืงื•ืœ ื”ืชืงืฉื•ืจืช ื‘ืžืขืœื” ื”ื–ืจื ื™ื›ื•ืœ ืœื”ื™ื•ืช HTTP ืื• HTTPS ืขื ื’ืจืกืช TLS ื ืžื•ื›ื” ืž-1.3 (ืื ื‘ืžืขืœื” ื”ื–ืจื ืื™ื ื• ืชื•ืžืš ื‘-1.3). ืชื›ื ื™ืช ื–ื• ืžืขื ื™ืงื” ื’ืžื™ืฉื•ืช ืžืจื‘ื™ืช.

ื™ื™ืฉื•ื ืชืžื™ื›ืช ESNI ืขืœ go ื”ืฉืืœื ื• ืžืžื ื• CloudFlare. ืื ื™ ืจื•ืฆื” ืœืฆื™ื™ืŸ ืžื™ื“ ืฉื”ื™ื™ืฉื•ื ืขืฆืžื• ื”ื•ื ื“ื™ ืœื ื˜ืจื™ื•ื•ื™ืืœื™, ืžื›ื™ื•ื•ืŸ ืฉื”ื•ื ื›ืจื•ืš ื‘ืฉื™ื ื•ื™ื™ื ื‘ืกืคืจื™ื™ื” ื”ืกื˜ื ื“ืจื˜ื™ืช crypto/tls ื•ืœื›ืŸ ื“ื•ืจืฉ "ืชื™ืงื•ืŸ" GOROOT ืœืคื ื™ ื”ื”ืจื›ื‘ื”.

ื›ื“ื™ ืœื™ืฆื•ืจ ืžืคืชื—ื•ืช ESNI ื”ืฉืชืžืฉื ื• esnitool (ื’ื ืคืจื™ ื™ืฆื™ืจืชื• ืฉืœ CloudFlare). ืžืคืชื—ื•ืช ืืœื” ืžืฉืžืฉื™ื ืœื”ืฆืคื ื”/ืคืขื ื•ื— SNI.
ื‘ื“ืงื ื• ืืช ื”ืžื‘ื ื” ื‘ืืžืฆืขื•ืช go 1.13 ื‘-Linux (Debian, Alpine) ื•-MacOS. 

ื›ืžื” ืžื™ืœื™ื ืขืœ ืชื›ื•ื ื•ืช ืชืคืขื•ืœื™ื•ืช

ืคืจื•ืงืกื™ ื”ืคื•ืš ืฉืœ ESNI ืžืกืคืง ืžื“ื“ื™ื ื‘ืคื•ืจืžื˜ ืฉืœ Prometheus, ื›ื’ื•ืŸ rps, ื—ื‘ื™ื•ืŸ ื‘ืžืขืœื” ื”ื–ืจื ื•ืงื•ื“ื™ ืชื’ื•ื‘ื”, ืœื—ื™ืฆื•ืช ื™ื“ ืฉืœ TLS ื ื›ืฉืœื•ืช/ืžื•ืฆืœื—ื•ืช ื•ืžืฉืš ืœื—ื™ืฆืช ื™ื“ ืฉืœ TLS. ื‘ืžื‘ื˜ ืจืืฉื•ืŸ, ื–ื” ื ืจืื” ืžืกืคื™ืง ื›ื“ื™ ืœื”ืขืจื™ืš ื›ื™ืฆื“ ื”-proxy ืžื˜ืคืœ ื‘ืชืขื‘ื•ืจื”. 

ื‘ื™ืฆืขื ื• ื’ื ื‘ื“ื™ืงื•ืช ืขื•ืžืก ืœืคื ื™ ื”ืฉื™ืžื•ืฉ. ืชื•ืฆืื•ืช ืœืžื˜ื”:

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 

ื‘ื™ืฆืขื ื• ื‘ื“ื™ืงื•ืช ืขื•ืžืก ืื™ื›ื•ืชื™ื•ืช ื‘ืœื‘ื“ ื›ื“ื™ ืœื”ืฉื•ื•ืช ืืช ื”ืกื›ื™ืžื” ื‘ืืžืฆืขื•ืช ืคืจื•ืงืกื™ ื”ืคื•ืš ืฉืœ ESNI ื•ืœืœื. "ืฉืคื›ื ื•" ืชืขื‘ื•ืจื” ืžืงื•ืžื™ืช ืขืœ ืžื ืช ืœืžื ื•ืข "ื”ืคืจืขื•ืช" ื‘ืจื›ื™ื‘ื™ ื‘ื™ื ื™ื™ื.

ืื–, ืขื ืชืžื™ื›ื” ื‘-ESNI ื•-proxy ืœ-upstream ืž-HTTP, ืงื™ื‘ืœื ื• ื›-550 rps ืžืžื•ืคืข ืื—ื“, ืขื ืฆืจื™ื›ืช ื”-CPU/RAM ื”ืžืžื•ืฆืขืช ืฉืœ ESNI ื”ืคื•ืš ืคืจื•ืงืกื™:

  • 80% ืฉื™ืžื•ืฉ ื‘ืžืขื‘ื“ (4 vCPU, ืžืืจื—ื™ื ืฉืœ 4 GB RAM, ืœื™ื ื•ืงืก)
  • 130 MB Mem RSS

ื›ื™ืฆื“ ืœื”ื’ืŸ ืขืœ ื”ืืชืจ ื”ืฆื™ื‘ื•ืจื™ ืฉืœืš ืขื ESNI

ืœืฉื ื”ืฉื•ื•ืื”, RPS ืขื‘ื•ืจ ืื•ืชื• nginx ื‘ืžืขืœื” ื”ื–ืจื ืœืœื ืกื™ื•ื TLS (ืคืจื•ื˜ื•ืงื•ืœ HTTP) ื”ื•ื ~ 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 

ื ื•ื›ื—ื•ืชื ืฉืœ ืคืกืงื™ ื–ืžืŸ ืžืฆื‘ื™ืขื” ืขืœ ืžื—ืกื•ืจ ื‘ืžืฉืื‘ื™ื (ื”ืฉืชืžืฉื ื• ื‘-4 vCPUs, ืžืืจื—ื™ื ืฉืœ 4 GB RAM, ืœื™ื ื•ืงืก), ื•ืœืžืขืฉื” ืคื•ื˜ื ืฆื™ืืœ ื”-RPS ื’ื‘ื•ื” ื™ื•ืชืจ (ืงื™ื‘ืœื ื• ื ืชื•ื ื™ื ืฉืœ ืขื“ 2700 RPS ืขืœ ืžืฉืื‘ื™ื ื—ื–ืงื™ื ื™ื•ืชืจ).

ืœืกื™ื›ื•ื, ืื ื™ ืžืฆื™ื™ืŸ ืฉื˜ื›ื ื•ืœื•ื’ื™ื™ืช ESNI ื ืจืื™ืช ื“ื™ ืžื‘ื˜ื™ื—ื”. ื™ืฉ ืขื“ื™ื™ืŸ ื”ืจื‘ื” ืฉืืœื•ืช ืคืชื•ื—ื•ืช, ืœืžืฉืœ, ื”ื‘ืขื™ื•ืช ืฉืœ ืื—ืกื•ืŸ ืžืคืชื— ื”-ESNI ื”ืฆื™ื‘ื•ืจื™ ื‘-DNS ื•ืžืคืชื—ื•ืช ESNI ืกื™ื‘ื•ื‘ื™ื™ื - ื ื•ืฉืื™ื ืืœื• ื ื™ื“ื•ื ื™ื ื‘ืื•ืคืŸ ืคืขื™ืœ, ื•ื”ื’ืจืกื” ื”ืขื“ื›ื ื™ืช ื‘ื™ื•ืชืจ ืฉืœ ื˜ื™ื•ื˜ืช ESNI (ื‘ื–ืžืŸ ื›ืชื™ื‘ืช ืฉื•ืจื•ืช ืืœื”) ื›ื‘ืจ ื ืžืฆืืช 7.

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”