Herkese açık web sitenizi ESNI ile nasıl korursunuz?

Merhaba Habr, adım İlya, Exness'te platform ekibinde çalışıyorum. Ürün geliştirme ekiplerimizin kullandığı temel altyapı bileşenlerini geliştiriyor ve uyguluyoruz.

Bu yazıda, şifreli SNI (ESNI) teknolojisinin halka açık web sitelerinin altyapısında uygulanmasına ilişkin deneyimimi paylaşmak istiyorum.

Herkese açık web sitenizi ESNI ile nasıl korursunuz?

Bu teknolojinin kullanılması, halka açık bir web sitesiyle çalışırken güvenlik düzeyini artıracak ve Şirket tarafından benimsenen iç güvenlik standartlarına uyum sağlayacaktır.

Öncelikle teknolojinin standartlaşmadığını ve henüz taslak aşamasında olduğunu ancak CloudFlare ve Mozilla'nın zaten desteklediğini belirtmek isterim (içinde taslak01). Bu bizi böyle bir deneye motive etti.

Biraz teori

ESNI TLS el sıkışma "İstemci Merhaba" mesajında ​​SNI şifrelemesine izin veren TLS 1.3 protokolünün bir uzantısıdır. ESNI desteğiyle Client Hello şu şekilde görünüyor (her zamanki SNI yerine ESNI'yi görüyoruz):

Herkese açık web sitenizi ESNI ile nasıl korursunuz?

 ESNI'yi kullanmak için üç bileşene ihtiyacınız vardır:

  • DNS'ler; 
  • Müşteri desteği;
  • Sunucu tarafı desteği.

DNS

İki DNS kaydı eklemeniz gerekir – Ave TXT (TXT kaydı, istemcinin SNI'yı şifreleyebileceği ortak anahtarı içerir) - aşağıya bakın. Ayrıca destek de olmalı Sağlık Bakanlığı (HTTPS üzerinden DNS) çünkü mevcut istemciler (aşağıya bakın) DoH olmadan ESNI desteğini etkinleştirmez. ESNI, eriştiğimiz kaynağın adının şifrelenmesini gerektirdiğinden, bu mantıklıdır, yani DNS'ye UDP üzerinden erişmenin bir anlamı yoktur. Üstelik kullanım DNSSEC bu senaryoda önbellek zehirlenmesi saldırılarına karşı korunmanıza olanak tanır.

Şu anda mevcut birkaç DoH sağlayıcısı, aralarında:

CloudFlare заявляет (Tarayıcımı Kontrol Et → Şifreli SNI → Daha Fazla Bilgi Edinin) sunucularının zaten ESNI'yi desteklediğini, yani DNS'deki CloudFlare sunucuları için en az iki kaydımızın olduğunu - A ve TXT. Aşağıdaki örnekte Google DNS'yi (HTTPS üzerinden) sorguluyoruz: 

А kayıt:

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 kayıt, istek bir şablona göre oluşturulur _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."
}

Dolayısıyla, DNS açısından bakıldığında DoH kullanmalı (tercihen DNSSEC ile) ve iki giriş eklemeliyiz. 

Müşteri desteği

Tarayıcılardan bahsediyorsak, şu anda destek yalnızca FireFox'ta uygulanır. öyle FireFox'ta ESNI ve DoH desteğinin nasıl etkinleştirileceğine ilişkin talimatları burada bulabilirsiniz. Tarayıcı yapılandırıldıktan sonra şöyle bir şey görmeliyiz:

Herkese açık web sitenizi ESNI ile nasıl korursunuz?

Bağlantı Tarayıcıyı kontrol etmek için.

ESNI, TLS 1.3'ün bir uzantısı olduğundan, elbette ESNI'yi desteklemek için TLS 1.3 kullanılmalıdır.

Arka ucu ESNI desteğiyle test etmek amacıyla istemciyi şu adreste uyguladık: go, Ama daha sonra.

Sunucu tarafı desteği

Şu anda ESNI, resmi olarak ESNI'yi desteklemeyen nginx/Apache vb. web sunucuları tarafından OpenSSL/BoringSSL üzerinden TLS ile çalıştıkları için desteklenmemektedir.

Bu nedenle, ESNI ile TLS 1.3 sonlandırmayı ve ESNI'yi desteklemeyen yukarı akışa proxy HTTP(S) trafiğini destekleyecek kendi ön uç bileşenimizi (ESNI ters proxy) oluşturmaya karar verdik. Bu, teknolojinin ana bileşenleri değiştirmeden, yani ESNI'yi desteklemeyen mevcut web sunucularını kullanmadan, halihazırda mevcut bir altyapıda kullanılmasına olanak tanır. 

Açıklık sağlamak için, burada bir diyagram var:

Herkese açık web sitenizi ESNI ile nasıl korursunuz?

Proxy'nin, ESNI olmayan istemcileri desteklemek için ESNI olmadan TLS bağlantısını sonlandırabilecek şekilde tasarlandığını unutmayın. Ayrıca, yukarı akışlı iletişim protokolü HTTP veya TLS sürümü 1.3'ün altında olan HTTPS olabilir (yukarı akış 1.3'ü desteklemiyorsa). Bu şema maksimum esneklik sağlar.

ESNI desteğinin uygulanması go ödünç aldık CloudFlare. Standart kütüphanedeki değişiklikleri içerdiğinden, uygulamanın kendisinin oldukça önemsiz olmadığını hemen belirtmek isterim. kripto/tl ve bu nedenle "yama" yapılmasını gerektirir MUHTEŞEM montajdan önce.

ESNI anahtarlarını oluşturmak için kullandık esnitool (aynı zamanda CloudFlare'in buluşu). Bu anahtarlar SNI şifreleme/şifre çözme için kullanılır.
Yapıyı Linux (Debian, Alpine) ve MacOS'ta go 1.13 kullanarak test ettik. 

Operasyonel özellikler hakkında birkaç kelime

ESNI ters proxy, rps, yukarı akış gecikmesi ve yanıt kodları, başarısız/başarılı TLS anlaşmaları ve TLS anlaşması süresi gibi Prometheus formatında ölçümler sağlar. İlk bakışta bu, proxy'nin trafiği nasıl yönettiğini değerlendirmek için yeterli görünüyordu. 

Kullanmadan önce yük testi de yaptık. Aşağıdaki sonuçlar:

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 ters proxy kullanan ve içermeyen şemayı karşılaştırmak için tamamen niteliksel yük testi gerçekleştirdik. Ara bileşenlerdeki "paraziti" ortadan kaldırmak için trafiği yerel olarak "döktük".

Dolayısıyla, ESNI desteği ve HTTP'den yukarı akışa proxy oluşturma sayesinde, ESNI ters proxy'nin ortalama CPU/RAM tüketimiyle bir örnekten yaklaşık ~550 rps elde ettik:

  • %80 CPU Kullanımı (4 vCPU, 4 GB RAM ana bilgisayarları, Linux)
  • 130 MB Hafıza RSS

Herkese açık web sitenizi ESNI ile nasıl korursunuz?

Karşılaştırma için, TLS (HTTP protokolü) sonlandırması olmayan aynı nginx yukarı akışı için RPS ~ 1100'dür:

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 

Zaman aşımlarının varlığı, kaynak eksikliği olduğunu gösterir (4 vCPU, 4 GB RAM ana bilgisayarı, Linux kullandık) ve aslında potansiyel RPS'nin daha yüksek olduğunu (daha güçlü kaynaklarda 2700 RPS'ye kadar rakamlar aldık).

Sonuç olarak şunu not ediyorum ESNI teknolojisi oldukça umut verici görünüyor. Hala pek çok açık soru var, örneğin, genel ESNI anahtarının DNS'de saklanması ve ESNI anahtarlarının döndürülmesi sorunları - bu konular aktif olarak tartışılıyor ve ESNI taslağının en son sürümü (yazıldığı sırada) zaten mevcut 7.

Kaynak: habr.com

Yorum ekle