نگاهی عمیق به DNS over HTTPS

می‌خوام درمورد DNS over HTTPS (DoH) صحبت کنم. چی هست؟ چطوری کار می‌کنه؟ چرا مهمه که همه شروع کنیم به استفاده کردنش؟ و چطوری شروع کنیم.

یک مقدمه خـــیـــلـــی خلاصه از DNS: همین سایت ویرگول رو در نظر بگیرید آدمها تایپ می‌کنن virgool.io اما کامپیوتر باید یه راهی پیدا کنه تا اون رو تبدیل کنه به 172.64.201.24 که بتونه باهاش ارتباط برقرار کنه. تکنولوژی این کار متعلق به 35 سال پیش هست، زمانی که اینترنت خیلی ساده کار می‌کرد و به اندازه امروز دله دزد و سانسور چی و «علی حکر» نداشت.

الان ما توی زمانه‌ای زندگی می‌کنیم که با متادیتا‌ها میشه آدم کشت! درواقع DNS زیادی دهنش لقه خیلی بی‌ریا آدرس سایتی که بازدید می‌کنید رو جار میزنه. آدم‌های زیادی هستن که خوراکشون خریدن این داده‌ها و تحلیل اونهاست. مثلا ازش برای تبلیغات استفاده می‌کنن، بدون اینکه بدونن شما کی هستین می‌فهمن که چی دوست دارین و همون رو بهتون نشون میدن. [اگه به اندازه کافی متادیتا به دست بیارن می‌تونن یقین پیدا کنن که شما کی هستین.]

جدای از این، شرکت‌های ارائه دهنده اینترنت می‌تونن با DNS hijacking جلوی دسترسی به سایت‌ها رو بگیرن که این قضیه جز DPI محسوب نمیشه در نتیجه از نظر قانونی (و فنی) منع کمتری داره - مثلا توی حادثه تیراندازی مسجدهای کرایست‌چرچ ارائه دهنده‌های اینترنتی نیوزیلند از این روش استفاده کردن برای محدود کردن دسترسی کاربرها (منبع)


پس این DNS over HTTPS چی‌هست؟ چطوری‌ کار می‌کنه؟

به شکل خلاصه؛ درخواست‌های DNS رو در بدنه یک درخواست HTTP می‌پیچیم. این باعث می شه بتونیم از TLS استفاده کنیم در نتیجه درخواست‌ها رو در قالب HTTPS ارسال کنیم.

اینکه دقیقا چطوری‌ کار‌ می‌کنه جای بحث داره. مشخصات لازم برای درست کردن یک سرور و کلاینت DoH طوری تعریف شده که دست توسعه دهنده‌ها برای پیاده سازی اون نسبتا باز هست (باز تر از چیزی مثل TCP برای همین هر کسی می‌تونه ایده خودش رو با رعایت مقررات ذکر شده پیاده کنه اما محدود بهشون نیست.)

Implementations of DoH clients and servers need to consider the
benefit and privacy impact of these features, and their deployment
context, when deciding whether or not to enable them.
Implementations are advised to expose the minimal set of data needed
to achieve the desired feature set. (rfc8484 page 13)
These requirements are listed here to help readers understand the current protocol, not to limit how the protocol might be developed in the future. (rfc8484 Appendix A)

چیزایی که لازمه:

  • پروتکل باید از شماتیک و مفاهیم HTTP استفاده کنه [پس حق ندارین پروتکل شخصی توسعه بدین]
  • کوئری (پرسش‌های سمت کلاینت) و پاسخ‌ها (جواب سمت سرور) باید مثل DNS معمولی (*) باشه (سعی خودش رو بکنه که شبیه به اون در بیاد -- انعطاف پذیر باشه) اما درخواست‌هایی که نیازدارن به دریافت چندتا پاسخ رو نیاز نیست پیاده سازی کنید.
  • پروتکل باید قالب و ساختارهای جدیدی که [در آینده] برای DNS در نظر گرفته می‌شه رو پیاده سازی کنه. [پا به پای ساختار DNS بره جلو، خودش قالب جدیدی تولید نکنه]
  • پروتکل باید https استفاده کنه (شرایطی رو پیروی کنه که بر عملکرد https حاکمه)
  • نسخه دوم HTTP/2 به عنوان «حداقل» پیش نیاز پیاده سازی این پروتکل هست.
  • حداقل متادیتای لازم رو استفاده کنه [چیزایی مثل User-Agent و Accept-Language جز پروتکل http هستن اینا هنوزم می‌تونن کاربرها رو لو بدن؛ مگر ثابت بشه که وجودش نیازه در غیر این صورت پیاده سازی اون پیشنهاد نمیشه]

* منظور DNS over UDP هست.

با این چندتا شرط میشه فهمید که DoH درواقع یک تونل هست نه یک پروتکل جدید. برای همین شرکت Cloudflare تونسته نسخه خودش رو درست کنه (که یه قضیه جالب هست در ادامه اونم کالبد شکافی می‌کنم)

مشکلات منطقی در رابطه با DoH

اینا دلیل نمیشه که بگیم DoH خرابه! بلکه مشکلات منطقی هستن که راه حل خودشون رو دارن. شاید «بهترین راه حل» نباشن. اما «یه راه حل» هستن.

خب ساختار زیر رو در نظر بگیرید:

GET myserver.com/dns-query?dns=AAABAAABAAAAAAAAAWE-NjJjaGFyYWN0ZXJsYWJl

من قراره یک درخواست GET بفرستم به myserver.com تا اون به من IP گوگل رو بده. خب کی قراره IP خود myserver.com رو بده؟ نمیشه که از HOST NAME بپرسیم آدرس IP خودت چیه؟

سه تا راه حل داره:

  • آدرس IP سرور داخل برنامه کلاینت کد نویسی بشه (hard-coded) -- یا داخل فایل hosts سیستم میزبان نوشته بشه.
  • به جای آدرس دامنه مستقیم از آدرس IP استفاده کنیم (اصلا دامنه ثبت نکنیم IP رو همه بتونن استفاده کنن به صورت مستقیم نیازی هم به هارد کد کردنش نباشه).
  • از یه DNS دیگه آدرس این سرور رو درخواست بدیم بعد بقیه درخواست‌ها رو به سرور DoH بفرستیم

به عنوان مثال فایرفاکس الان از گزینه اول استفاده می‌کنه. آدرس سرور‌های کلاودفلر رو داخل سورس خودش ذخیره کرده.

مشکل منطقی دیگه به انتخاب http به عنوان قالب داده مربوط میشه. دوتاش رو بالا مثال زدم که باعث لو رفتن وضعیت کاربر میشن. بیاید یه لایه بریم پایین تر، http روی لایه TCP سوار شده.

و توی لایه TCP هرچقدر که اتصال طولانی تر باشه کیفیت اون بهتره. اما اتصال طولانی باعث به وجود اومدن همبستگی داده‌ (data correlation) می‌شه. به عبارت دیگه اگه خیلی به یه چیزی وصل باشین متادیتا تولید میشه.

از یه جهت دیگه نگاه کنیم، اگر سرور قابلیت TCP Fast Open رو پیاده سازی کنه به خاطر استفاده از کوکی باعث می‌شه سشن های TCP به هم ارتباط پیدا کنن (بازم متادیتا تولید می‌شه).

راه حل؟ «خواهی نشوی رسوا، همرنگ جماعت شو» -- اگر خودتون می‌خواین سرور DoH رو میزبانی کنید اونو پشت یه CDN قایم کنید. درخواست های زیادی روزانه به سمت CDN ها میرن و در نتیجه داده شما بین اون همه داده گم می‌شه.

نکته مهم: اگر سرور «تحریم شکن» دارین؛ هیچوقت روی همون سرور DoH هم میزبانی نکنید. [قیمه ها رو نریزید تو ماستا]. به خاطر اینکه میزان تمرکز شما روی اون سرور زیاد میشه. تمرکز زیاد متادیتا به وجود میاره.

فرض کنید روی اون سرور OpenVPN میزبانی می‌کنید و الان DoH هم اضافه شده. خب دوتا جریان داده به وجود میاد که میشه ازشون متادیتا استخراج کرد و چون هردوتاشون به یه نقطه وصل میشن، میشه اینا رو بهم مرتبط کرد تا به یک «یقین» رسید.

یادتون باشه، الگوریتمها چه تبلیغاتی و چه سانسورینگ بر اساس یقین عمل می کنن، نه شک و شبهه هرچقدر میزان یقین کمتر باشه شما بیشتر در امان هستین.

نحوه استفاده فایرفاکس از DoH ارائه شده توسط cloudflare

تا اینجای داستان فهمیدیم DoH چیه و چطوری کار می‌کنه. ولی گفتم دست توسعه دهنده‌ها بازه مثلا کلاودفلر به یه شکل جذاب اون رو پیاده سازی کرده.

توی مسیر ارسال درخواست سه تا نقطه وجود داره که داده می‌تونه دستکاری بشه (این مربوط بحث اعتماد هست)

داده می‌تونه توسط resolver شنود بشه، می‌تونه در راه رسیدن به DNS Server دستکاری بشه و یا خود سرور یه مقصد غیرقابل اعتماد باشه.

خب برای امن کردن مسیر انتقال می‌تونیم از DoH استفاده کنیم. اما کسی که DoH رو ارائه میده (resolver) باید مورد اعتماد باشه درسته؟ همچنین اون resolver باید خودش یه راهی پیدا کنه که مطمئن بشه سرور DNS قابل اعتماد هست.

اینجا فایرفاکس می‌گه من کلاینت DoH رو توی سورس کد خودم اضافه می‌کنم و بعدش به تو (کلاودفلر) اعتماد می‌کنم که resolver من بشی. تو هم باید یه راهی پیدا کنی که به DNS Server ها اعتماد کنی.

چرا فایرفاکس همچین کاری می‌کنه؟ خب کلاودفلر یه شرکت شناخته شده هست که خدمات زیادی ارائه میده مهم ترین اون خدمات CDN هست (یادتونه؟ همرنگ جماعت شدن...) بعلاوه کلاودفلر بحث حذف داده‌ها رو ماموریت خودش قرار داده و بر اون نظارت می‌کنه. طبق خط مشی اونها داده‌ها بعد از 24 ساعت از بین میرن.

چه داده ای؟ چه چیزایی قراره به کلاودفلر بره؟

من یه چیزی رو اول مطلب نگفتم درمورد DNS معمولی، اینکه دقیقا چه چیزایی رو جار میزنه و چرا؟

یک درخواست DNS معمولی آدرس IP شما و آدرس کامل دامنه‌ای که می‌خواید ببینید رو ارسال می‌کنه. اما چه نیازی هست به اینکه کاملا جار بزنه آدرس IP شما چیه؟ به خاطر اینکه موقعیت شما رو تشخیص بده و درخواست رو بفرسته به نزدیک ترین سرور DNS موجود. [این قسمت رو حتما یادتون باشه دوباره بخونید اگر نفهمیدین]

یه درخواست DoH چطور؟ گفتیم که باید «سعی کنه» مثل درخواست DNS باشه. پس یه سرور معمولی DoH که شما بخوای به صورت خود مختار میزبانی کنی هنوزم نیاز داره آدرس IP تون رو ذخیره کنه تا اون رو به نزدیک ترین DNS بفرسته فقط اونو به صورت https می‌فرسته که کسی نبینه اما مقصد نهایی می‌فهمه که شما کی هستین.

یه تیکه مهم دیگه (بالا بهش اشاره کردم):

Implementations are advised to expose the minimal set of data needed

یعنی پیشنهاد میشه که [اگر می‌تونید] کمترین متادیتای ممکن رو به کار ببرید / تولید کنید. خب کلاودفلر می‌تونه.

این چیزیه که cloudflare برای پیاده سازی DoH نیاز داره. داده ها هنوز «شبیه» درخواست DNS هستن اما خیلی خیلی نامفهوم شدن.

  • آدرس IP شما به طور کل حذف شده اصلا نیاز نیست یادداشت بشه
  • آدرس دامنه ای که درخواست می‌کنید حذف شده فقط TLD ارسال می‌شه (در این مثال org)

چطوری ممکنه؟ خب کلاودفلر یک CDN هست درسته؟ یعنی شبکه توزیع محتوا. پس کلاودفلر می‌تونه به جای آدرس IP شما، آدرس IP نزدیک ترین سرور خودش به شما رو بفرسته برای سرور DNS

اما چطوری فقط TLD رو نیاز داره؟ با استفاده از تکنیک Query Name Minimisation که خودش یه مقاله می‌شه.

پس نتیجه می‌گیریم کسی که DoH رو پیاده سازی کرده بسیار مهمه.

چه چیزایی هنوزم قابل شنود هستن؟

خب ببنید اولین باری که مرورگر درخواست دیدن یک وبسایت رو میده یک بسته SNI ارسال می‌کنه. توی این بسته آدرس کامل دامنه ذکر شده و متاسفانه رمزنگاری نشده. این یعنی ISP هنوزم می‌تونه با شنود کردن این بسته بفهمه مقصد شما کجاست و اون درخواست رو متوقف کنه.

این «شنود کردن» از نوع Deep Packet Inspection هست. سرویس دهنده اینترنت خودش نمی‌تونه همچین حرکتی انجام بده قانونی نیست. مگر به فرمان قضایی و دولتی. و اینم بدونید این عملیات هم از نظر تجهیزات و هم مالی هزینه بر هست.

برای همینه که توی چین، ایران، سوریه، قزاقستان و ... نمی‌تونید با DoH سانسور رو دور بزنید پس منع قانونی نداره استفاده ازش.

در آینده ESNI هم فراگیر میشه درواقع یه راهی پیدا شده که درخواست SNI رو رمزنگاری کرد اونموقع تجهیزات شنود هم باید خیلی پیشرفته تر بشن. چون متادیتا به اندازه کافی تولید نمیشه که به یقین برسن.

به عنوان آخرین نکنه این بحث، یادتونه گفتم سرور DoH باید حد اقل از https/2 پشتیبانی کنه؟ به خاطر اینکه توی این نسخه یه ویژگی هست به اسم connection coalescing درواقع یعنی استفاده مجدد از اتصال قبلی.

وقتی دوباره به یک وبسایت وصل بشید دیگه درخواست SNI ارسال نمیشه یعنی متادیتایی که تولید میشه فقط یک بار اتفاق میوفته در نتیجه بازم میزان پیدا کردن یقین کاهش پیدا می‌کنه. (این موضوع در گذشته رعایت نمی‌شد مرورگرها انقدر احمق بودن که نمی‌تونستن بفهمن SNI ارسال شده و همیشه ارسالش می کردن اما از فایرفاکس 62 به بعد این مشکل برطرف شده -- درمورد مرورگرهای دیگه نمی‌دونم)

با وجود CDN ها، چه داخلی و چه خارجی آدمهای زیادی حالا دیگه به یک نقطه وصل می‌شن این نشون میده فیلتر کردن اون نقطه منطقی نیست چون خیلی چیزا تحت تاثیر اون قرار می‌گیرن. حتی دولت چین هم کلاودفلر رو فیلتر نکرده! درضمن CDN ها باعث می‌شن تعداد دفعاتی که SNI فرستاده می‌شه کمتر بشه. مثلا وقتی x و y هردو روی کلاودفلر میزبانی بشن با دیدن x شما دیگه نیاز نیست برای دیدن y هم درخواست SNI بفرستید.

چطوری شروع کنیم به استفاده از DoH؟

فایرفاکس نصب کنید! روی همه دستگاه هاتون حتی موبایل. راهنمای استفاده اش خیلی سادست.

به کلاودفلر اعتماد ندارین؟ مشکلی نیست فایرفاکس بهتون اجازه می‌ده از DoH دلخواهتون استفاده کنید.

منابع:

A cartoon intro to DNS over HTTPS
rfc8484: DNS Queries over HTTPS

هووف! سرم درد گرفت. امیدوارم این مطلب مورد توجه تون قرار گرفته باشه؛ لطفا اون رو با بقیه به اشتراک بذارید تا منم برای انتشار محتوای بهتر انگیزه پیدا کنم.