دو ماشین روی یک VPN، یک نام میزبان، و تنها یکی از آن‌ها آن را حل می‌کند: تفاوت معمولاً در تونل نیست، بلکه در این است که کدام resolver پاسخ داده است. روی دسکتاپ Linux آن نام می‌تواند از میان سامانهٔ سوئیچ سرویس نام، از میان stub مربوط به systemd-resolved، یا از میان resolverی که برنامه همراه خود آورده است عبور کند، و هر یک از این‌ها قاعدهٔ خود را بر همان پسوند اعمال می‌کند. پسوند همان جایی است که قواعد از هم جدا می‌شوند، چون .local یک برچسب خنثی نیست. پیش از تغییر ترتیبی که هر چیزی در آن اجرا می‌شود، مشخص کنید برنامهٔ شکست‌خورده در واقع کدام مسیر را طی می‌کند.

دو resolver، دو پاسخ متفاوت

جست‌وجوی سنتی glibc خط hosts: در nsswitch.conf را می‌پیماید و به نوبت از هر ماژول می‌پرسد تا یکی پاسخ دهد. کلاینتی که از طریق شنوندهٔ stub با systemd-resolved صحبت می‌کند، به‌جای آن از یک فرایند واحد می‌پرسد، و آن فرایند سیاست هر پیوند به‌همراه موارد خاص خودش را اعمال می‌کند. برنامه‌ای که resolver خودش را می‌آورد یا کتابخانه‌ای را پیوند می‌دهد که این کار را می‌کند، می‌تواند از هر دو عبور کند. بنابراین یک نام میزبان می‌تواند سه مالک روی یک ماشین داشته باشد، و فقط یکی از آن‌ها می‌داند VPN چه قصدی داشته است.

پیش از تغییر هر چیزی مالک را شناسایی کنید، چون راه‌حل برای هر یک از آن سه متفاوت است. مرورگر و یک ابزار خط فرمان روی یک دسکتاپ می‌توانند به‌طور مشروع اختلاف داشته باشند، و همین اختلاف سرنخ است نه باگ. اگر مرورگر نام را حل می‌کند و ابزار نمی‌کند، شما در حال عیب‌یابی مسیر resolver هستید نه مسیر VPN. مسیر را جداگانه تأیید کنید تا خطای مسیریابی با خطای سرویس نام اشتباه نشود. وقتی هر دو هم‌داستان باشند، خطا بالادست میزبان است و پیکربندی resolver اینجا ارزش یک ویرایش دیگر را ندارد.

کدام فرمان واقعاً از resolver شما پرسید

دو فرمان فقط‌خواندنی به پرسش‌های مرتبط پاسخ می‌دهند، و مقایسهٔ آن‌ها مشکل را سریع‌تر از خواندن پیکربندی مکان‌یابی می‌کند. از یک نام داخلی واقعی استفاده کنید و خروجی را خصوصی نگه دارید، چون سوابق داخلی همچنان داخلی‌اند. هر دو را در همان نشستی اجرا کنید که برنامهٔ شکست‌خورده در آن اجرا می‌شود:

getent ahosts files.corp.local
resolvectl query files.corp.local
resolvectl status

اولی از طریق ماژول‌های پیکربندی‌شده می‌پرسد، که همان چیزی است یک برنامهٔ معمولی تجربه می‌کند. دومی مستقیماً از systemd-resolved می‌پرسد و پیوند، پروتکل و سروری که پاسخ داده را گزارش می‌کند. پرسیدن از سرور سازمانی بر اساس نشانی فقط اثبات می‌کند که سرور آن سابقه را دارد، چون چیزی دربارهٔ این که آیا برنامه هرگز از آن پرسیده است یا نه نمی‌گوید. پیوندی را که VPN را حمل می‌کند و دامنه‌هایی که ادعا می‌کند بخوانید، سپس آن فهرست را با پسوند در نام شکست‌خورده مقایسه کنید.

چرا .local از ناحیهٔ unicast شما رد می‌شود

مرجع systemd-resolved می‌گوید نام‌های چندبرچسبی که به .local ختم می‌شوند معمولاً وقتی mDNS فعال است به DNS چندپخشی می‌روند، نه به DNS یک‌پخشی معمولی. RFC 6762 آن فضای نام را برای چندپخشی پیوند-محلی کنار می‌گذارد، بنابراین یک ناحیهٔ سازمانی می‌تواند سابقهٔ درستی داشته باشد که هرگز برای آن پسوند پرسیده نمی‌شود. تونل می‌تواند resolver را بی‌عیب مسیریابی کند و باز هم مسابقه را ببازد. یک ping موفق از حافظهٔ نهان چیزی دربارهٔ جست‌وجویی که همین حالا رخ داد نمی‌گوید.

یک استثنای مستند وجود دارد، و بیشتر این موارد را حل می‌کند: وقتی پیوندی آن پسوند را به‌عنوان دامنهٔ جست‌وجو یا دامنهٔ مسیریابی اعلام کند، daemon آن را روی مسیر unicast نگه می‌دارد و مورد خاص چندپخشی را نادیده می‌گیرد. این سیاست هر پیوند است نه یک ترجیح جهانی. دو ماشین با سرور VPN یکسان می‌توانند رفتار متفاوت داشته باشند وقتی یک نمایهٔ شبکه دامنه را اعلام می‌کند و دیگری نمی‌کند، پس نمایهٔ فعال را بخوانید نه آن یکی که یادتان است ویرایش کرده‌اید.

استثنای باریک بر بازآرایی جهانی پیروز می‌شود

برای ناحیه‌ای موجود که نمی‌توانید نامش را عوض کنید، از مالکان resolver و VPN بخواهید دامنه را روی اتصالی که آن را حمل می‌کند اعلام کنند. یک ورودی دامنهٔ مسیریابی برای همان یک پسوند به‌همراه نشانی سرور موردنظر تغییری کوچک با مالکی نام‌دار است، و با پیوند زندگی می‌کند نه در فایلی که دستی ویرایش شده است.

از قطع اتصال هم جان سالم به در می‌برد، چون سیاست پیوند هنگام بازگشت پیوند دوباره اعمال می‌شود. ویرایش nsswitch.conf مشترک جایگزین وسوسه‌انگیز و گران‌تر است، چون رفتار جست‌وجو را برای هر نام روی ماشین تغییر می‌دهد، از جمله کشف محلی. غیرفعال کردن daemon چندپخشی هم معادل نیست: رفتار محلی را حذف می‌کند بدون آنکه به هیچ resolverی دربارهٔ ناحیهٔ سازمانی آموزش دهد. اگر سرویس تازه است نه موروثی، آن را زیر دامنه‌ای بگذارید که سازمان شما کنترل می‌کند و رقابت را کاملاً نادیده بگیرید. وقتی نام در firmware ثابت شده یا روی برچسب چاپ شده است استثنای باریک را انتخاب کنید، و وقتی هنوز کلاینت را کنترل می‌کنید دامنهٔ جدید را انتخاب کنید.

پس از تغییر چه چیزی را اثبات کنید

اصلاح را با جست‌وجوی خود برنامه اثبات کنید نه با ابزاری که برای آزمودن نصب کرده‌اید، و هر حافظهٔ نهانی را که می‌تواند به‌جای آن پاسخ دهد پاک کنید. سپس مسیر resolver و پیوندی که پاسخ را ارائه کرد تأیید کنید. در پایان بررسی کنید که کشف محلی همان‌طور که پیش از تغییر بود رفتار می‌کند، چون چاپگری که از ظاهر شدن باز می‌ماند همان بخشی است که مردم آخر از همه متوجه می‌شوند. این سه فرمان نام، مسیر و هویت TLS را به همین ترتیب بررسی می‌کنند:

getent ahosts files.corp.local
resolvectl query files.corp.local
curl -sv --max-time 5 https://files.corp.local/ 2>&1 | head -n 20

نشانی درست با گواهی نادرست هنوز کلاینت سخت‌گیر را شکست می‌دهد، پس وقتی حل نام کار کرد نامی را که برنامه انتظار دارد بررسی کنید. تأیید کنید که سرویس اتصال‌ها را از نشانی VPN می‌پذیرد نه فقط از محدودهٔ دفتر. دامنهٔ ناحیه، سرور و مالک را در مستندات اتصال بنویسید. در غیر این صورت نفر بعدی که با این خرابی روبه‌رو می‌شود به همان ویرایش جهانی دست می‌برد که شما همین حالا از آن پرهیز کردید.

مقالات مرتبط