DNS از روی لینوکس: dig، resolvectl و عیبیابی نامها
چگونه از لینوکس کوئری DNS بزنید، تفاوت dig و getent، نقش resolv.conf و resolved، و جدا کردن مشکل نام از مشکل شبکه.
بنیانگذار و مهندس محصول

curl به API خطا میدهد، git clone تایماوت میشود، یا گواهی TLS عجیب به نظر میرسد — و همهٔ اینها گاهی فقط بهخاطر این است که نام به IP درست ترجمه نشده. روی لینوکس مسیر رزولوشن ساده نیست: ممکن است از `/etc/hosts`، NSS، `systemd-resolved`، یا یک `resolv.conf` کلاسیک بگذرد. ابزار اشتباه، جواب گمراهکننده میدهد.
این مقاله از دید کلاینت لینوکس است: چگونه بپرسید، چگونه بفهمید چه کسی جواب میدهد، و چگونه مشکل DNS را از قطعی TCP جدا کنید.

پاسخ کوتاه
برای پرسش خام DNS از `dig` استفاده کنید و سرور مشخص را با `@` هدف بگیرید. برای آنچه اپلیکیشنها واقعاً میبینند، `getent hosts` یا تست اتصال واقعی را هم بزنید. روی اوبونتوهای جدید `resolvectl status` و `resolvectl query` وضعیت resolved را نشان میدهند. اگر dig با @8.8.8.8 جواب میدهد ولی بدون @ شکست میخورد، مشکل در resolver محلی یا شبکه تا همان resolver است نه در خودِ نام عمومی.
dig موفقیتآمیز بهتنهایی یعنی «آن سرور DNS آن نام را بلداست»؛ لزوماً یعنی مسیر کامل اپ شما سالم نیست.
زنجیرهٔ رزولوشن بهزبان ساده
- برنامه libc را صدا میزند (getaddrinfo).
- NSS طبق /etc/nsswitch.conf تصمیم میگیرد: فایلها، DNS، mDNS و …
- /etc/hosts میتواند قبل از DNS برنده شود.
- پرسش DNS به stub resolver میرود: اغلب systemd-resolved روی 127.0.0.53 یا محتوای resolv.conf.
- resolver بالادستی (ISP، VPC، AD، 1.1.1.1 و …) پاسخ یا ارجاع میدهد.
به همین دلیل ممکن است dig مستقیم به ۸.۸.۸.۸ درست باشد، ولی برنامه هنوز IP داخلیِ hosts را ببیند.
dig: ابزار تشخیصی اصلی
bash
dig example.com dig example.com A +short dig @1.1.1.1 example.com A dig example.com NS +short dig -x 203.0.113.10
- بخش ANSWER را از AUTHORITY و ADDITIONAL جدا بخوانید.
- فیلد status مثل NOERROR، NXDOMAIN، SERVFAIL معنی جدا دارد.
- Query time و SERVER نشان میدهند کدام resolver و با چه تأخیری جواب داد.
- +trace مسیر ریشه تا authoritative را قدمبهقدم نشان میدهد — برای فهم تفویض مفید است، نه برای هر عیب روزمره.
`nslookup` هنوز رایج است ولی dig برای اسکریپت و جزئیات معمولاً شفافتر است. `host` برای پرسشهای کوتاه مناسب است.
آنچه اپ میبیند: getent و تست واقعی
bash
getent hosts example.com getent ahosts example.com ping -c1 example.com curl -vI https://example.com 2>&1 | head
اگر dig درست و getent غلط است، hosts یا NSS یا کش resolved را مظنون کنید. اگر نام resolve میشود ولی TCP/TLS شکست میخورد، از مرحلهٔ DNS بیرون آمدهاید و باید به شبکه، فایروال یا سرویس بروید.
resolv.conf و systemd-resolved
فایل `/etc/resolv.conf` ممکن است symlink به stub resolved باشد. ویرایش دستی آن روی سیستمهایی که Netplan/NetworkManager/resolved مالک پیکربندیاند ناپایدار است؛ بعد از reboot برمیگردد یا با واقعیت فاصله میگیرد.
bash
ls -l /etc/resolv.conf resolvectl status resolvectl query example.com resolvectl dns resolvectl flush-caches
روی اوبونتو سرور، DNS معمولاً از Netplan به resolved میرسد. برای تغییر پایدار، منبع حقیقت همان لایهٔ شبکه است نه یک echo تکی در resolv.conf.
سناریوهای رایج عیبیابی
| نشانه | احتمال | تست |
|---|---|---|
| NXDOMAIN | نام واقعاً نیست یا zone اشتباه | dig @authoritative |
| SERVFAIL | resolver بالادست یا DNSSEC/پیکربندی | dig @دیگر؛ لاگ resolver |
| timeout | فایروال UDP/TCP 53 یا مسیر | dig +tcp؛ پینگ مسیر |
| جواب قدیمی | TTL/کش | flush-caches؛ پرسش مستقیم authoritative |
| IP خصوصی غیرمنتظره | hosts یا DNS داخلی | getent؛ cat /etc/hosts |
DNS خصوصی، split-horizon و VPN
روی لپتاپ شرکتی یا سرور داخل VPC، همان نام عمومی ممکن است IP داخلی برگرداند. وقتی VPN قطع است، رزولوشن میشکند یا به اینترنت عمومی میرود. قبل از متهم کردن «اینترنت»، ببینید کدام resolver و کدام search domain فعال است (`resolvectl domain`).
امنیت و بهداشت عملیاتی
- ترافیک DNS رمز نشده روی مسیر نامطمئن قابل شنود/دستکاری است؛ DNS over TLS در resolved در برخی محیطها قابل فعالسازی است.
- برای سرویسهای حیاتی، اتکا به یک resolver عمومی بدون قرارداد عملیاتی ریسک است.
- در لاگ اپ، هم نام و هم IP نهایی را ثبت کنید تا بعداً بفهمید به کجا وصل شدهاید.
اشتباههای رایج
- ویرایش موقت resolv.conf و فراموش کردن منبع پایدار.
- نتیجهگیری از dig بدون تست getent/curl.
- نادیده گرفتن /etc/hosts در محیط توسعه.
- اشتباه گرفتن کندی DNS با کندی TLS handshake.
- استفاده از +short تنها و از دست دادن status=SERVFAIL پنهان در ابزار دیگر.
مثال: SERVFAIL در برابر NXDOMAIN
NXDOMAIN یعنی نام در zone موجود نیست (یا به شما چنان گفتهاند). SERVFAIL یعنی resolver نتوانسته پاسخ معتبر بسازد — مشکل شبکه تا authoritative، شکست DNSSEC، یا باگ/محدودیت resolver. درمان NXDOMAIN معمولاً اصلاح رکورد یا نام اشتباه در کانفیگ اپ است؛ درمان SERVFAIL با عوض کردن نام دامنه حل نمیشود. همیشه status را در dig بدون +short ببینید.
bash
dig api.example.com A # به خط status: توجه کنید dig @ns1.example.com api.example.com A +norecurse
search domain و نامهای کوتاه
اگر در resolv.conf یا resolved یک search domain مثل `corp.example` دارید، پرسش `db` ممکن است به `db.corp.example` گسترش یابد. این رفتار در لپتاپ اداری مفید و در سرور production گاهی غافلگیرکننده است. در واحدهای systemd و کانتینر، DNS و search را صریح کنید تا وابسته به محیط لپتاپ توسعهدهنده نباشد.
کش منفی و TTL
پس از ساخت رکورد جدید، ممکن است NXDOMAIN منفی هنوز در کش resolver باشد. TTL منفی و رفتار stub متفاوت است. برای تأیید نهایی از dig مستقیم روی authoritative استفاده کنید و در کلاینت `resolvectl flush-caches` یا TTL را در نظر بگیرید — نه اینکه هر ۳۰ ثانیه رکورد را در پنل DNS عوض کنید و نتیجه را «خراب» بنامید.
DNS در مسیر استقرار و CI
پایپلاین CI که به نام داخلی وابسته است باید resolver درست را در runner داشته باشد؛ در غیر این صورت تستها سبزِ دروغین روی لپتاپ و قرمز در CI میشوند یا برعکس. ترجیح بدهید در اسکریپتهای حساس نام کامل (FQDN) بنویسید و از search domain پنهان پرهیز کنید. برای سرویسهای ابری، گاهی endpoint باید منطقهای باشد نه نام عمومی که به IP در دسترس نمیرسد.
هنگام قطعی DNS بالادست، داشتن IP ثابت در کانفیگ ضدالگو است چون failover نام را از دست میدهید؛ ولی برای تشخیص، مقایسهٔ dig با IP مستقیم همچنان ابزار جداسازی است. تفاوت «تشخیص» و «پیکربندی دائمی» را در تیم یکسان کنید.
رکوردهای TTL خیلی کوتاه به شما چابکی تغییر میدهند و به resolverها بار بیشتر. TTL خیلی بلند برش را کند میکند. عدد را بر اساس نرخ تغییر واقعی و تحمل کش انتخاب کنید نه بر اساس عادت. بعد از تغییر بحرانی، از مناطق جغرافیایی مختلف dig بزنید تا ببینید کدام جمعیت هنوز کش قدیمی دارد.
اگر از CDN استفاده میکنید، جواب DNS ممکن است به anycast یا CNAME زنجیرهای برسد. عیبیابی origin را با `--resolve` در curl از لایهٔ DNS CDN جدا کنید تا مشکل گواهی یا کش لبه را به «DNS خراب» نسبت ندهید.
چکلیست سریع قطعی «نام باز نمیشود»
۱) آیا IP مستقیم کار میکند؟ ۲) dig @resolver-شرکت چه status میدهد؟ ۳) dig @1.1.1.1 برای نام عمومی چه میگوید؟ ۴) getent همان جواب dig را میدهد؟ ۵) ساعت سیستم و VPN وصلاند؟ با این پنج سؤال معمولاً میفهمید مشکل از hosts است، از DNS داخلی، از اینترنت، یا از لایهٔ بعد از DNS. بدون این ترتیب، افراد همزمان کانفیگ اپ، فایروال و رکورد DNS را عوض میکنند و علت گم میشود.
برای سرویسهای حیاتی، یک صفحهٔ «DNS owner» مشخص کنید: چه کسی رکورد را عوض میکند، TTL چیست، و پنجرهٔ انتشار تقریبی چقدر است. مالک مبهم یکی از علتهای طولانی شدن حادثههای نام است.
اگر از رکوردهای alias چندلایه استفاده میکنید، زنجیره را در مستند بیاورید. عیبیابی CNAME تودرتو بدون نقشه مثل دنبال کردن سیم بدون برچسب است.
و در نهایت: بعد از رفع، یک تست از شبکهٔ متفاوت و یک dig ذخیرهشده در تیکت بگذارید تا باز شدن دوبارهٔ همان مشکل قابلمقایسه باشد.
جمعبندی عملی برای on-call
برای حادثهٔ نام: اول IP مستقیم، بعد dig با status، بعد getent، بعد مسیر VPN/resolver. نتیجه را در چهار کلمه خلاصه کنید: hosts، DNS داخلی، DNS عمومی، یا پسا-DNS. این برچسب تعیین میکند تیکت برای کدام تیم است و از جنگ بیحاصل بین «بکاند» و «شبکه» کم میکند.
اگر تغییر رکورد دادهاید، TTL و زمان شروع تغییر را در تیکت بنویسید. بدون TTL، همه میپرسند «چرا هنوز پیر است؟» و کسی جواب دقیق ندارد. یک اسکرینشات dig از authoritative و یک dig از stub همان لحظه، طلاست.
پس از پایداری، بررسی کنید آیا search domain یا فایل hosts روی سرورهای مشابه همان تله را ندارند. حادثههای DNS عاشق تکرار روی میزبان بعدی هستند.
DNS و سلامت سرویسهای کشفشده
در محیطهایی که سرویسها با نام کوتاه یا SRV پیدا میشوند، شکست DNS مثل شکست discovery است. به جای hardcode کردن IP در اپ، روی نام پایدار و TTL معقول تکیه کنید؛ ولی برای عیبیابی همیشه بتوانید IP فعلی را با dig ببینید و با `--resolve` مقایسه کنید. این دوگانگی «پیکربندی با نام / تشخیص با IP» باید در فرهنگ تیم جا بیفتد.
برای Kubernetes یا Consul، لایهٔ DNS خوشه را با DNS عمومی قاطی نکنید. تست را از داخل همان namespace انجام دهید و از لپتاپ فقط با مسیر درست (port-forward یا bastion) قضاوت کنید.
اگر اپ کش DNS خودش دارد (بسیاری از JVM و برخی کتابخانهها)، علاوه بر stub سیستم آن کش را هم در نظر بگیرید؛ گاهی dig تازه است و اپ هنوز قدیمی است.
در عمل، یک برگهٔ یکصفحهای با فرمانهای dig، resolvectl و getent کنار کانال on-call بیشتر از هر ابزار گرانقیمتی به تیم کمک میکند تا نام را از شبکه جدا کنند و زمان میانگین رفع را پایین بیاورند.
خلاصه
از لینوکس، DNS را لایه لایه تست کنید: پرسش خام با dig، مسیر سیستم با getent/resolvectl، رفتار اپ با curl. معلوم کنید مشکل نام است، resolver است، یا اصلاً شبکه. آنگاه تغییر پیکربندی را در جای درست — Netplan/resolved/hosts — اعمال کنید.
سوالات متداول
چرا dig جواب میدهد ولی مرورگر نه؟
مرورگر کش جدا، DoH، یا پراکسی دارد. همچنین ممکن است IPv6 را ترجیح دهد؛ dig A و AAAA را جدا ببینید.
UDP 53 بسته است؛ چه کنم؟
بسیاری resolverها TCP 53 هم پشتیبانی میکنند (`dig +tcp`). ریشه را در فایروال درست کنید؛ دور زدن موقتی تشخیص است نه معماری.
آیا همیشه به 8.8.8.8 dig بزنم؟
برای جدا کردن مشکل مفید است، ولی پاسخ گوگل ممکن است با DNS داخلی شما یکی نباشد. برای نامهای داخلی، همان resolver سازمانی را بپرسید.
منابع و مراجع
- dig(1) ISC BIND manuals: https://bind9.readthedocs.io/en/latest/manpages.html#dig
- resolv.conf(5): https://man7.org/linux/man-pages/man5/resolv.conf.5.html
- resolvectl(1) systemd: https://www.freedesktop.org/software/systemd/man/latest/resolvectl.html
- systemd-resolved.service(8): https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html
- Ubuntu Server — networking / DNS related docs: https://documentation.ubuntu.com/server/
نویسنده
سهیل ابراهیمپور بنیانگذار FutureForge است. روی طراحی محصول، معماری و استقرار نرمافزار سفارشی کار میکند.
یادداشتهای مرتبط
اگر در انتخاب معماری یا مسیر توسعه مطمئن نیستید، میتوانید درباره پروژه صحبت کنیم.
مسئله و محدودیت را بنویسید. اگر تطابق داشته باشیم، برای گفتگو هماهنگ میکنیم.




