مقدمة

تتشابه أنظمة تصفية المحتوى الحديثة للشركات من الشركات المصنعة الشهيرة مثل Cisco وBlueCoat وFireEye في الكثير مع نظيراتها الأكثر قوة - أنظمة DPI، والتي يتم تنفيذها بشكل مكثف على المستوى الوطني. جوهر عمل كل منهما هو فحص حركة المرور الواردة والصادرة عبر الإنترنت، واتخاذ قرار بحظر الاتصال بالإنترنت بناءً على القوائم السوداء/البيضاء. وبما أن كليهما يعتمد على مبادئ مماثلة في أسس عمله، فإن الأساليب المستخدمة لتجاوزها ستكون لها أيضًا الكثير من القواسم المشتركة.
إحدى التقنيات التي تسمح لك بتجاوز أنظمة DPI والشركات بفعالية كبيرة هي تقنية واجهة النطاق. جوهرها هو أننا نذهب إلى مورد محظور، مختبئًا خلف مورد آخر، مجال عام يتمتع بسمعة طيبة، والذي من الواضح أنه لن يتم حظره بواسطة أي نظام، على سبيل المثال google.com.
لقد تم بالفعل كتابة العديد من المقالات حول هذه التكنولوجيا وتم تقديم العديد من الأمثلة. ومع ذلك، فإن التقنيات الشائعة والتي تمت مناقشتها مؤخرًا مثل DNS-over-HTTPS وencrypted-SNI، بالإضافة إلى الإصدار الجديد من بروتوكول TLS 1.3، تجعل من الممكن النظر في خيار آخر لإدارة النطاق.
فهم التكنولوجيا
أولاً، دعونا نحدد بعض المفاهيم الأساسية حتى يفهم الجميع من هو من ولماذا كل هذا مطلوب. لقد ذكرنا آلية eSNI، والتي سيتم مناقشتها لاحقًا. آلية eSNI (إشارة اسم الخادم المشفر) هي نسخة آمنة من SNI، ومتاحة فقط لبروتوكول TLS 1.3. الفكرة الرئيسية هي تشفير المعلومات حول المجال الذي يتم إرسال الطلب إليه.
الآن دعونا نلقي نظرة على كيفية عمل آلية eSNI في الممارسة العملية.
لنفترض أن لدينا مورد إنترنت محظور بواسطة حل DPI حديث (دعنا نأخذ على سبيل المثال متعقب التورنت الشهير - rutracker.nl). عند محاولة الوصول إلى موقع تعقب التورنت، نرى رمز المزود القياسي الذي يشير إلى أن المورد محظور:

على موقع RKN، تم إدراج هذا المجال بالفعل في قوائم المنع:

عندما تستفسر عن whois، يمكنك أن ترى أن المجال نفسه "مخفي" خلف مزود الخدمة السحابية Cloudflare.

ولكن على النقيض من "المتخصصين" من شركة RKN، فإن الموظفين الأكثر دراية بالجوانب التقنية من شركة Beeline (أو أولئك الذين تعلموا من التجربة المريرة التي خاضتها هيئتنا التنظيمية الشهيرة) لم يحظروا الموقع عن طريق عنوان IP فحسب، بل أضافوا اسم النطاق إلى قائمة الإيقاف. يمكن التحقق من ذلك بسهولة من خلال النظر إلى المجالات الأخرى المخفية خلف نفس عنوان IP، وزيارة أحدها والتأكد من عدم حظر الوصول:

كيف يحدث هذا؟ كيف يعرف مزود خدمة DPI النطاق الذي سينتقل إليه متصفحي، حيث أن جميع الاتصالات تتم عبر بروتوكول https، ولم نلاحظ أي استبدال لشهادات https من Beeline حتى الآن؟ هل هو عراف أم أنني أتبع؟
دعونا نحاول الإجابة على هذا السؤال من خلال النظر إلى حركة المرور عبر Wireshark

تظهر لقطة الشاشة أن المتصفح يحصل أولاً على عنوان IP الخاص بالخادم عبر DNS، ثم يحدث مصافحة TCP قياسية مع الخادم الوجهة، ثم يحاول المتصفح إنشاء اتصال SSL مع الخادم. وللقيام بذلك، فإنه يرسل حزمة SSL Client Hello، والتي تحتوي على اسم المجال الأصلي بنص واضح. هذا الحقل مطلوب من قبل خادم الواجهة الأمامية لـ cloudflare لتوجيه الاتصال بشكل صحيح. هذا هو المكان الذي يقع فيه DPI الخاص بالموفر، مما يؤدي إلى قطع اتصالنا. في هذه الحالة، لا نتلقى أي رد من المزود، ونرى خطأً قياسيًا في المتصفح كما لو كان الموقع معطلاً أو ببساطة لا يعمل:

الآن دعنا نقوم بتفعيل آلية eSNI في المتصفح، كما هو موضح في التعليمات الخاصة بـ :
للقيام بذلك، نفتح صفحة تكوين Firefox حول: التكوين وتفعيل الإعدادات التالية:
network.trr.mode = 2;
network.trr.uri = https://mozilla.cloudflare-dns.com/dns-query
network.security.esni.enabled = true
بعد ذلك سوف نتحقق من صحة عمل الإعدادات على موقع cloudflare ولنحاول استخدام نفس الحيلة مع متتبع التورنت الخاص بنا مرة أخرى.

فويلا. تم فتح تطبيق التتبع المفضل لدينا، بدون أي VPN أو خوادم وكيلة. دعونا الآن نلقي نظرة على تفريغ حركة المرور في Wireshark، ماذا حدث.

هذه المرة، لا تحتوي حزمة hello لعميل SSL صراحةً على نطاق الوجهة، ولكن بدلاً من ذلك، ظهر حقل جديد في الحزمة — encrypted_server_name — وهذا هو المكان الذي تحتوي فيه قيمة rutracker.nl، ويمكن فقط لخادم الواجهة الأمامية لـ Cloudflare فك تشفير هذا الحقل. إذا كان الأمر كذلك، فلن يكون أمام مزود خدمة الإنترنت خيار سوى غسل يديه من هذا الأمر والسماح بمثل هذه الحركة. لا توجد خيارات أخرى للتشفير.
لذا، نظرنا إلى كيفية عمل التكنولوجيا في المتصفح. والآن دعونا نحاول تطبيقه على أشياء أكثر تحديدًا وإثارة للاهتمام. وللبدء، سوف نعلم نفس curl كيفية استخدام eSNI للعمل مع TLS 1.3، وفي نفس الوقت سوف نرى كيف تعمل واجهة المجال نفسها بناءً على eSNI.
واجهة النطاق مع eSNI
نظرًا لأن curl يستخدم مكتبة openssl القياسية للاتصال عبر https، فنحن بحاجة أولاً إلى التأكد من دعم eSNI هناك. لا يوجد دعم eSNI في فروع openssl الرئيسية حتى الآن، لذا نحتاج إلى تنزيل فرع openssl خاص وتجميعه وتثبيته.
نقوم باستنساخ المستودع من GitHub ونقوم بتجميعه كالمعتاد:
$ git clone https://github.com/sftcd/openssl
$ cd openssl
$ ./config
$ make
$ cd esnistuff
$ make
بعد ذلك، نقوم باستنساخ المستودع باستخدام curl وتكوين التجميع الخاص به باستخدام مكتبة openssl التي قمنا ببنائها:
$ cd $HOME/code
$ git clone https://github.com/niallor/curl.git curl-esni
$ cd curl-esni
$ export LD_LIBRARY_PATH=/opt/openssl
$ ./buildconf
$ LDFLAGS="-L/opt/openssl" ./configure --with-ssl=/opt/openssl --enable-esni --enable-debug
من المهم هنا تحديد جميع الدلائل التي يوجد بها openssl بشكل صحيح (في حالتنا، هو /opt/openssl/) والتأكد من أن عملية التكوين تتم دون أخطاء.
إذا كان التكوين ناجحًا، فسوف نرى السطر:
تحذير: تم تمكين esni ESNI ولكن تم وضع علامة تجريبية عليها. استخدم بحذر!
$ makeبعد بناء الحزمة بنجاح، سوف نستخدم ملف bash خاص من openssl لتكوين وتشغيل curl. دعنا ننسخه إلى دليل curl للراحة:
cp /opt/openssl/esnistuff/curl-esni وأجري طلب اختبار https إلى خادم cloudflare، وتسجيل حزم DNS وTLS في Wireshark في نفس الوقت.
$ ESNI_COVER="www.hello-rkn.ru" ./curl-esni https://cloudflare.com/في استجابة الخادم، بالإضافة إلى الكثير من معلومات التصحيح من openssl و curl، سنتلقى استجابة HTTP مع الكود 301 من cloudflare.
HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 13:12:55 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: max-age=3600
< Expires: Sun, 03 Nov 2019 14:12:55 GMT
< Location: https://www.cloudflare.com/
مما يشير إلى أن طلبنا تم تسليمه بنجاح إلى الخادم الوجهة، وتم الاستماع إليه ومعالجته.
الآن دعونا نلقي نظرة على تفريغ حركة المرور في Wireshark، أي ما رآه مزود DPI في هذه الحالة.

من الواضح أن curl اتصل أولاً بخادم DNS للحصول على مفتاح eSNI العام لخادم cloudflare - طلب TXT DNS إلى _esni.cloudflare.com (الحزمة رقم 13). بعد ذلك، باستخدام مكتبة openssl، أرسل curl طلب TLS 1.3 إلى خادم cloudflare حيث تم تشفير حقل SNI باستخدام المفتاح العام الذي تم الحصول عليه في الخطوة السابقة (الحزمة رقم 22). ولكن بالإضافة إلى حقل eSNI، تضمنت حزمة SSL-hello أيضًا حقلًا يحتوي على SNI مفتوح عادي، والذي يمكننا تحديده بأي ترتيب (في هذه الحالة، ).
لم يتم أخذ حقل SNI المفتوح هذا في الاعتبار بأي شكل من الأشكال عند معالجته بواسطة خوادم Cloudflare وكان مجرد وكيل إخفاء لـ DPI الخاص بالموفر. لقد قبل خادم cloudflare حزمة ssl-hello الخاصة بنا، وفك تشفير eSNI، واستخراج SNI الأصلي من هناك ومعالجته كما لو لم يحدث شيء (لقد فعل كل شيء بالضبط كما هو مخطط له عند تطوير eSNI).
الشيء الوحيد الذي يمكن اكتشافه في هذه الحالة من وجهة نظر DPI هو طلب DNS الأساسي إلى _esni.cloudflare.com. لكننا جعلنا استعلام DNS مفتوحًا فقط لإظهار كيفية عمل هذه الآلية من الداخل.
لكي نتمكن أخيرًا من إخراج DPI من تحت أقدامها، فإننا نستخدم آلية DNS-over-HTTPS التي ذكرناها سابقًا. شرح مختصر: DOH هو بروتوكول يسمح لك بحماية نفسك من هجوم الرجل في المنتصف عن طريق إرسال طلب DNS عبر بروتوكول HTTPS.
دعنا ننفذ الطلب مرة أخرى، ولكن هذه المرة سنتلقى مفاتيح eSNI العامة عبر بروتوكول https، وليس DNS:
ESNI_COVER="www.hello-rkn.ru" DOH_URL=https://mozilla.cloudflare-dns.com/dns-query ./curl-esni https://cloudflare.com/يظهر تفريغ حركة المرور للطلب في لقطة الشاشة أدناه:

من الواضح أن curl يتصل أولاً بخادم mozilla.cloudflare-dns.com عبر بروتوكول DoH (اتصال https بالخادم 104.16.249.249) للحصول على قيم المفتاح العام لتشفير SNI منهم، ثم إلى الخادم الوجهة، مختبئًا خلف المجال .
بالإضافة إلى مُحلل DoH المذكور أعلاه mozilla.cloudflare-dns.com، يمكننا أيضًا استخدام خدمات DoH الشهيرة الأخرى، على سبيل المثال، من الشركة الشريرة الشهيرة.
دعونا ننفذ الاستعلام التالي:
ESNI_COVER="www.kremlin.ru" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/ونحصل على الجواب:
< HTTP/1.1 301 Moved Permanently
< Date: Sun, 03 Nov 2019 14:10:22 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Set-Cookie: __cfduid=da0144d982437e77b0b37af7d00438b1a1572790222; expires=Mon, 02-Nov-20 14:10:22 GMT; path=/; domain=.rutracker.nl; HttpOnly; Secure
< Location: https://rutracker.nl/forum/index.php
< CF-Cache-Status: DYNAMIC
< Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< Server: cloudflare
< CF-RAY: 52feee696f42d891-CPH

في هذه الحالة، اتصلنا بالخادم المحظور rutracker.nl، باستخدام محلل DoH dns.google (لا يوجد خطأ مطبعي، والآن تمتلك الشركة الشهيرة نطاق المستوى الأعلى الخاص بها) وقمنا بتغطية أنفسنا بنطاق آخر، والذي يُمنع جميع DPIs من حظره تمامًا تحت طائلة عقوبة الإعدام. ومن خلال الرد الذي تلقيناه، يمكننا أن نفهم أن طلبنا تمت معالجته بنجاح.
كفحص إضافي للتأكد من أن DPI الخاص بالموفر يستجيب لـ SNI المفتوح الذي نمرره كغطاء، يمكننا تنفيذ طلب إلى rutracker.nl تحت ستار بعض الموارد المحظورة الأخرى، على سبيل المثال، متعقب تورنت "جيد" آخر:
$ ESNI_COVER="rutor.info" DOH_URL=https://dns.google/dns-query ./curl-esni https://rutracker.nl/لن نتلقى ردًا من الخادم، لأن طلبنا سيتم حظره بواسطة نظام DPI.
خاتمة مختصرة للجزء الأول
وبالتالي، تمكنا من توضيح وظيفة eSNI باستخدام openssl و curl والتحقق من وظيفة واجهة النطاق استنادًا إلى eSNI. وبنفس الطريقة، يمكننا تكييف أدواتنا المفضلة التي تستخدم مكتبة openssl للعمل "تحت غطاء" المجالات الأخرى. المزيد عن هذا في مقالاتنا القادمة.
المصدر: www.habr.com
