عیب‌یابی شبکه

هدف این درس

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

اول ابزارهای لازم را نصب کنید:

1sudo apt update && sudo apt install traceroute mtr-tiny tcpdump dnsutils

گام ۱: لایه‌ی Internet

ping می‌گوید آیا بسته اصلاً به مقصد می‌رسد و با چه تأخیری:

1ping -c 4 example.com

اگر ping به نام کار کرد، هم DNS و هم مسیر شبکه سالم‌اند — خیالتان راحت باشد. اگر به نام کار نکرد ولی به IP (ping -c 4 1.1.1.1) کار کرد، مشکل دقیقاً از DNS است، نه از شبکه. اگر هیچ‌کدام جواب ندادند، مشکل پایین‌تر از این‌هاست: ip addr را چک کنید و ببینید آیا اصلاً آدرس IP دارید و Interface بالاست یا نه.

traceroute مسیر رفتن بسته را قدم‌به‌قدم نشان می‌دهد:

1traceroute example.com

mtr همان کار را انجام می‌دهد، اما زنده و پیوسته، و علاوه‌بر آن درصد Loss بسته‌ها در هر Hop را هم می‌دهد:

1mtr example.com

یک نکته که به کارتان می‌آید: ممکن است بعضی Hopهای وسط راه اصلاً به ICMP جواب ندهند و ستون‌هایشان خالی بماند — این همیشه به معنای خرابی نیست، خیلی از روترها عمداً همین‌طور پیکربندی شده‌اند. برای قضاوت نهایی، به Hop آخر و درصد Loss کلی نگاه کنید، نه به تک‌تک خط‌های وسط.

گام ۲: DNS

با dig می‌توانید DNS را کاملاً از بقیه‌ی مسیر جدا کنید و تنها همان را بررسی کنید:

1dig digikala.com +short
2dig @1.1.1.1 digikala.com +short

اگر این دو خروجی با هم فرق داشتند یا یکی خالی بود، احتمالا مشکل از Resolver پیش‌فرض شماست، نه از خود دامنه. همان پیام NXDOMAIN که در درس DNS دیدید را هم یادتان باشد — کمک می‌کند «این نام واقعاً وجود ندارد» را از «DNS جواب نمی‌دهد» جدا کنید.

گام ۳: لایه‌ی Transport

ss می‌گوید چه چیزی روی سیستم شما در حال گوش‌دادن است:

1ss -tulpn

برای این‌که ببینید آیا اتصال به یک پورت مقصد باز است یا نه، بهتر است curl را کنار بگذارید و مستقیم با nc چک کنید:

1nc -zv 127.0.0.1 80

اگر nc وصل نمی‌شود، مشکل قبل از HTTP اتفاق افتاده — یا سرویس خاموش است یا یک فایروال جلویش را گرفته. اما اگر وصل می‌شود و مشکل فقط این است که پاسخ HTTP اشتباه است، دیگر مشکل داخل خود سرویس است و باید لاگش را دید (یادآوری هفته‌ی دوم: journalctl -u nginx.service).

گام ۴: لایه‌ی Application

curl -v کل گفت‌وگو را برایتان جدا و شفاف نشان می‌دهد:

1curl -v http://127.0.0.1/
2curl -v https://example.com/

دنبال این نشانه‌ها بگردید: Connected to (یعنی TCP موفق شد)، SSL connection using (یعنی TLS هم موفق شد) و در آخر کد وضعیت پاسخ. اگر NGINX از درس‌های قبل هنوز روشن است، یک تست جالب این است که موقتاً خاموشش کنید (sudo systemctl stop nginx.service) و دوباره curl -v http://127.0.0.1/ بزنید — بلافاصله می‌بینید رفتار آن وقتی TCP اصلاً وصل نمی‌شود با وقتی که TCP وصل می‌شود ولی HTTP خطا می‌دهد متفاوت است.

گام ۵: دیدن بسته‌ها با tcpdump

وقتی همه‌چیز به‌ظاهر درست است ولی هنوز چیزی گیر می‌کند، tcpdump یکی از دقیق‌ترین ابزارهاست — ترافیک خام را مستقیم در ترمینال نشان می‌دهد:

1sudo tcpdump -i any -n port 80

در یک ترمینال دیگر یک درخواست بزنید (curl -s http://127.0.0.1/ > /dev/null) و در خروجی tcpdump دنبال بسته‌های SYN، بعد SYN-ACK، بعد ACK و در نهایت تبادل واقعی HTTP بگردید. گزینه‌ی -n Reverse DNS را خاموش می‌کند تا خروجی سریع‌تر و خواناتر باشد. برای پایان دادن، کافی است Ctrl+C بزنید؛ tcpdump خودش خلاصه‌ای از تعداد بسته‌ها چاپ می‌کند.

فقط روی ترافیک خودتان capture بگیرید و خروجی را با احتیاط نگه دارید — محتوای بسته‌ها می‌تواند داده‌ی حساس داشته باشد که نباید هرجایی بماند. برای تحلیل بصری‌تر، همان فایل Capture را در Wireshark باز کنید؛ فرمت فایل بین این دو ابزار مشترک است.

چرخه‌ی عیب‌یابی در یک صفحه

  1. ping به IP — آیا مسیر اصلاً باز است؟
  2. dig — آیا نام درست Resolve می‌شود؟
  3. nc -zv یا ss — آیا TCP روی آن پورت باز است؟
  4. curl -v — آیا HTTP/TLS پاسخ درستی می‌دهد؟
  5. tcpdump یا لاگ سرویس — اگر تا این‌جا هنوز چیزی معلوم نشده، وقتش رسیده بسته‌ها را با چشم خودتان ببینید.

خودتان یک مشکل بسازید و پیدایش کنید

تا اینجا قدم به قدم پیش رفتیم. حالا نوبت شماست که بدون راهنما این چرخه را روی یک مشکل واقعی (که خودتان می‌سازید) پیاده کنید. این سه سناریو می‌توانند مناسب باشند:

  • NGINX را متوقف کنید (sudo systemctl stop nginx.service) و فرض کنید نمی‌دانید چرا سایت بالا نمی‌آید.
  • در پیکربندی NGINX، listen 80 را به listen 8080 تغییر دهید، Reload کنید، و به مسیر http://127.0.0.1/ (بدون پورت) درخواست بزنید.
  • در فایل /etc/hosts، یک نام ساختگی مثل broken.local را به یک IP نامعتبر (مثلاً 10.255.255.1) نگاشت دهید و curl http://broken.local/ بزنید.

برای هرکدام، همان پنج‌قدمِ بالا را طی کنید و در هر قدم به خاطر بسپرید که چه دیدید و از آن چه نتیجه گرفتید. مثلاً برای سناریوی اول: ping باید موفق باشد (چون شبکه سالم است)، dig هم موفق باشد (چون DNS دخیل نیست)، اما nc -zv 127.0.0.1 80 باید Connection refused بدهد — همین یک خط، ریشه‌ی مشکل را نشان می‌دهد. سناریوی دوم و سوم را هم امتحان کنید و ببینید علامت هرکدام در کدام قدم اول ظاهر می‌شود.

نکته‌ی اصلی این تمرین این نیست که پاسخ درست را حفظ کنید؛ نکته این است که تجربه کنید هر دسته از مشکل، در کدام قدم از این پنج‌قدم خودش را نشان می‌دهد. وقتی بار بعد یک سرویس واقعی خراب شد، همین توالی ذهنی — نه حدس‌زدن — مسیر شما خواهد بود. پس از تمرین، حتماً NGINX و /etc/hosts را به حالت اولشان برگردانید.

منابع یادگیری

مستندات و مقالات