كيفية حماية موقع الويب العام الخاص بك مع ESNI

مرحبًا حبر، اسمي إيليا، وأعمل ضمن فريق المنصة في Exness. نقوم بتطوير وتنفيذ مكونات البنية التحتية الأساسية التي تستخدمها فرق تطوير المنتجات لدينا.

في هذه المقالة، أود أن أشارك تجربتي في تطبيق تقنية SNI المشفرة (ESNI) في البنية التحتية للمواقع العامة.

كيفية حماية موقع الويب العام الخاص بك مع ESNI

سيؤدي استخدام هذه التقنية إلى زيادة مستوى الأمان عند العمل مع موقع ويب عام والامتثال لمعايير الأمان الداخلي التي تعتمدها الشركة.

بادئ ذي بدء، أود أن أشير إلى أن التكنولوجيا ليست موحدة ولا تزال في المسودة، ولكن CloudFlare وMozilla يدعمانها بالفعل (في مشروع01). هذا حفزنا لمثل هذه التجربة.

بعض نظرية

إسني هو امتداد لبروتوكول TLS 1.3 الذي يسمح بتشفير SNI في رسالة مصافحة TLS "Client Hello". إليك ما يبدو عليه Client Hello مع دعم ESNI (بدلاً من SNI المعتاد الذي نراه ESNI):

كيفية حماية موقع الويب العام الخاص بك مع ESNI

 لاستخدام ESNI، تحتاج إلى ثلاثة مكونات:

  • DNS ؛ 
  • دعم العميل؛
  • دعم جانب الخادم.

DNS

تحتاج إلى إضافة سجلين DNS – Aو TXT (يحتوي سجل TXT على المفتاح العام الذي يمكن للعميل من خلاله تشفير SNI) - انظر أدناه. وبالإضافة إلى ذلك، يجب أن يكون هناك دعم دوه (DNS عبر HTTPS) لأن العملاء المتاحين (انظر أدناه) لا يقومون بتمكين دعم ESNI بدون DoH. هذا أمر منطقي، نظرا لأن ESNI يعني تشفير اسم المورد الذي نصل إليه، أي أنه لا معنى للوصول إلى DNS عبر UDP. علاوة على ذلك، الاستخدام DNSSEC يسمح لك بالحماية من هجمات تسميم ذاكرة التخزين المؤقت في هذا السيناريو.

متاح حاليا العديد من مقدمي خدمات وزارة الصحة، فيما بينها:

كلودفلاري الدول (تحقق من متصفحي → 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.

لغرض اختبار الواجهة الخلفية بدعم ESNI، قمنا بتنفيذ العميل على go، ولكن أكثر عن ذلك لاحقا.

دعم جانب الخادم

حاليًا، لا يتم دعم ESNI بواسطة خوادم الويب مثل nginx/Apache وما إلى ذلك، نظرًا لأنها تعمل مع TLS عبر OpenSSL/BoringSSL، والتي لا تدعم ESNI رسميًا.

لذلك، قررنا إنشاء مكون الواجهة الأمامية الخاص بنا (وكيل ESNI العكسي)، والذي سيدعم إنهاء TLS 1.3 مع ESNI وحركة مرور HTTP(S) الوكيل إلى المنبع، والتي لا تدعم ESNI. وهذا يسمح باستخدام التكنولوجيا في البنية التحتية الموجودة بالفعل، دون تغيير المكونات الرئيسية - أي استخدام خوادم الويب الحالية التي لا تدعم ESNI. 

وللتوضيح، إليك الرسم البياني:

كيفية حماية موقع الويب العام الخاص بك مع ESNI

ألاحظ أن الوكيل تم تصميمه مع القدرة على إنهاء اتصال TLS بدون ESNI، لدعم العملاء بدون ESNI. أيضًا، يمكن أن يكون بروتوكول الاتصال مع المنبع إما HTTP أو HTTPS بإصدار TLS أقل من 1.3 (إذا كان المنبع لا يدعم 1.3). هذا المخطط يعطي أقصى قدر من المرونة.

تنفيذ دعم ESNI على go اقترضنا من كلودفلاري. أود أن أشير على الفور إلى أن التنفيذ في حد ذاته ليس بالأمر التافه تمامًا، لأنه يتضمن تغييرات في المكتبة القياسية التشفير/TLS وبالتالي يتطلب "التصحيح" جورووت قبل التجميع.

استخدمنا لإنشاء مفاتيح ESNI esnitool (أيضًا من بنات أفكار CloudFlare). تُستخدم هذه المفاتيح لتشفير/فك تشفير SNI.
لقد اختبرنا البنية باستخدام go 1.13 على Linux (Debian وAlpine) وMacOS. 

بضع كلمات حول الميزات التشغيلية

يوفر الوكيل العكسي ESNI مقاييس بتنسيق Prometheus، مثل rps وزمن الوصول الأولي ورموز الاستجابة ومصافحات TLS الفاشلة/الناجحة ومدة مصافحة TLS. للوهلة الأولى، بدا هذا كافيًا لتقييم كيفية تعامل الوكيل مع حركة المرور. 

لقد أجرينا أيضًا اختبار الحمل قبل الاستخدام. النتائج أدناه:

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 والخادم الوكيل للمنبع من HTTP، حصلنا على حوالي 550 دورة في الثانية من مثيل واحد، مع متوسط ​​استهلاك وحدة المعالجة المركزية/ذاكرة الوصول العشوائي للوكيل العكسي ESNI:

  • استخدام وحدة المعالجة المركزية بنسبة 80% (4 وحدات معالجة مركزية افتراضية، ومضيفات ذاكرة الوصول العشوائي سعة 4 جيجابايت، ونظام التشغيل Linux)
  • 130 ميغابايت ميم آر إس إس

كيفية حماية موقع الويب العام الخاص بك مع ESNI

للمقارنة، فإن RPS لنفس nginx upstream بدون إنهاء 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 وحدات معالجة مركزية افتراضية، ومضيفات ذاكرة الوصول العشوائي بسعة 4 جيجابايت، ونظام التشغيل Linux)، وفي الواقع فإن عدد RPS المحتمل أعلى (لقد تلقينا أرقامًا تصل إلى 2700 RPS على موارد أكثر قوة).

وفي الختام، أشير أن تقنية ESNI تبدو واعدة جدًا. لا تزال هناك العديد من الأسئلة المفتوحة، على سبيل المثال، مشكلات تخزين مفتاح ESNI العام في DNS وتدوير مفاتيح ESNI - تتم مناقشة هذه المشكلات بشكل نشط، وتم بالفعل إصدار أحدث إصدار من مسودة ESNI (في وقت كتابة هذا التقرير) 7.

المصدر: www.habr.com

إضافة تعليق