چرا پرسوجوهای dnsmasq پس از تغییر مسیر DNS از VPN خارج میشوند
یک قاعدهٔ REDIRECT در سمت روتر، پرسوجوی DNS شبکهٔ محلی را به یک سوکت تازهٔ resolver تبدیل میکند. نشانههای روی جریان کلاینت هرگز به آن نمیرسند، پس خروجی بالادست را مستقیم تنظیم کنید.
کلاینت شبکهٔ محلی بهدرستی به VPN خود میرسد و با این حال پرسوجوهای DNS آن روی لینک بالاروی نادرست ظاهر میشوند. این به معنای معمول نشت نیست؛ این همان چیزی است که رخ میدهد وقتی روتر از بازفرستادن یک پرسوجو دست میکشد و خودش به آن پاسخ میدهد. رهگیری مقصد را به یک سوکت محلی بازنویسی میکند، و سپس resolver گفتوگویی دوم و بیارتباط با نشانی مبدأ خودش و تصمیم مسیریابی خودش باز میکند. نشانههایی که روی جریان کلاینت اعمال شدهاند گفتوگوی نخست را توصیف میکنند و هیچ چیز دربارهٔ دومی نمیگویند.
نشانه با پرسوجو سفر نمیکند
نشانههای بسته روی یک ورودی conntrack و روی بستهٔ در پرواز زندگی میکنند. یک قاعدهٔ REDIRECT آن پرواز را پایان میدهد: بار داده به سوکت محلی تحویل میشود و ورودی اصلی کار خود را کرده است. آنچه پس از آن از روتر خارج میشود سوکتی تازه است که فرایند resolver ساخته و مبدأ آن نشانی خود روتر است.
به همین دلیل مسیر سیاستی که بر نشانی کلاینت شبکهٔ محلی کلید خورده هرگز با پرسوجوی بالادست مطابقت ندارد. سوکت تازه به dnsmasq تعلق دارد نه به کلاینت، و هسته مسیر را برای ترافیک خود روتر ارزیابی میکند. قواعد مبدأ، قواعد واسط و قواعد نشانه همگی چندتایی متفاوتی میبینند. فرض اینکه نشانه منتشر میشود رایجترین خطا در این چیدمان است و در گرفتن بسته در سمت کلاینت دیده نمیشود.
این دو گفتوگو در واقع یک نام و یک زمان را شریکاند، و همین است که هنگام مرور سریع یک فایل گرفتهشده آنها را مانند یک جریان واحد نشان میدهد.
کجا بازفرستادن به حل محلی تبدیل میشود
با این شروع کنید که بفهمید آیا پورت 53 تغییر مسیر مییابد، به میزبان دیگری ترجمه میشود یا دستنخورده میماند، چون این سه حالت رفتار متفاوتی دارند. تغییر مسیر به یک پورت محلی بازفرستادن را پایان میدهد، در حالی که ترجمه به ماشینی دیگر بسته را در حرکت نگه میدارد و چندتایی کلاینت را معنادار نگه میدارد.
به هر دو پروتکل نگاه کنید. یک resolver که از طریق UDP و TCP در دسترس است با هر دو آزموده میشود، و مجموعهقاعدهای که فقط UDP را پوشش میدهد سوراخی خاموش برای پاسخهای بزرگ باقی میگذارد. قواعدی که مدیر پیکربندی خود روتر تولید میکند هم به حساب میآیند، و ویرایش یک فایل تولیدشده معمولاً در برابر بارگذاری بعدی میبازد.
sudo nft list ruleset | grep -n -B2 -A4 'dport 53'
sudo iptables -t nat -L -n -v | grep -E ':53|dns'
sudo ss -lunp | grep ':53'
این خروجیها به سه پرسش به ترتیب پاسخ میدهند: چه چیزی پرسوجو را بازنویسی میکند، چه چیزی آن را میگیرد، و کدام فرایند مالک سوکت شنونده است. وقتی مالک شناخته شد، سیاست بالادست جایی برای زیستن دارد.
به resolver سیاست خروج خودش را بدهید
بالادست مخصوص یک دامنه پاکترین ابزار است وقتی فقط برخی نامها به تونل نیاز دارند. dnsmasq خط server محدود به یک دامنه را میپذیرد، با واسط یا نشانی مبدأ اختیاری که پرسوجو را از دستگاهی برگزیده بیرون میبرد. همان هدایت است که گفتوگوی دوم را وادار به پیروی از VPN میکند.
server=/corp.example/10.30.0.53@tun_work
log-queries
دامنه، نشانی و واسط بالا جانگهدارهایی برای مقادیر خودتان هستند. انتخاب دامنه و کنترل خروج تصمیمهایی جدا میمانند: مسیر باید وجود داشته باشد، نشانی مبدأ باید از سوی resolver بالادست مجاز باشد و دیوار آتش باید پاسخ را اجازه دهد. هدایت تنها از طریق واسط fail-closed نیست، چون تونلی که ناپدید شود میتواند resolver را به مسیر دیگری بیندازد. هر جایگزین عمومی را از فضای نامی که باید خصوصی بماند دور نگه دارید.
خط را در مالک پیکربندی که روتر پشتیبانی میکند بگذارید نه در یک فایل تولیدشده، وگرنه بارگذاری بعدی اصلاح را پاک میکند.
کاری که یک کش مشترک نمیتواند حفظ کند
یک بازفرستنده با یک کش به هر کلاینت شبکهٔ محلی خدمت میکند و این تمایزی را که برخی شبکهها نیاز دارند فرو میریزد. اگر دو کلاینت باید یک نام را به شکل متفاوت حل کنند، سوکت مشترک هیچ راهی برای بازیابی اینکه کدام کلاینت پرسیده ندارد. سیاست بهازای هر کلاینت باید در نمونههای جدای resolver یا در ویژگی بازفرستادنی که هویت را نگه میدارد زندگی کند.
پاسخ کششده هم شاهدی دربارهٔ مسیر تازه نیست. پاسخ میتواند از حافظه بیاید در حالی که مسیر بالادست شکسته میماند.
قواعد پورت 53 هیچ چیزی دربارهٔ برنامههایی که DNS را روی HTTPS یا روی TLS صحبت میکنند نمیگویند. آن پرسوجوها هرگز به تغییر مسیر نمیرسند، پس سیاستی که تنها بر پورت 53 بنا شده زیرمجموعهای از ترافیک را توصیف میکند و باید بهعنوان یک زیرمجموعه مستند شود.
گفتوگوی دوم را بررسی کنید، نه نخست را
با نامی که خودتان کنترل میکنید بیازمایید و هر دو سو را ببینید. گرفتن بسته در سمت کلاینت ثابت میکند پرسوجو شبکهٔ محلی را ترک کرده؛ تنها سمت روتر ثابت میکند که بعد به کجا رفته است.
sudo tcpdump -ni tun_work udp port 53
ip route get 10.30.0.53
dig +short corp.example @10.30.0.53
پیش از هر تلاش کش را خالی کنید، چون پاسخی گرم بالادست شکسته را پنهان میکند. روی TCP تکرار کنید، سپس با تونل خاموش تکرار کنید تا ببینید resolver وقتی مسیر ترجیحیاش رفته چه میکند. همان رفتار آخر تعیین میکند که طراحی fail-closed است یا فقط خوششانس.