توی این درس یاد میگیری هر ماشین در شبکه با یک آدرس IP روی یک interface (مثل eth0) شناخته میشود؛ بستهها برای بیرونرفتن از gateway (دروازه) میگذرند و جدول مسیر تصمیم میگیرد از کجا؛ DNS اسم سایت را به IP تبدیل میکند (/etc/resolv.conf) و فایل /etc/hosts یک فهرست محلی است که قبل از DNS دیده میشود. با ip a، ip route، ping، dig/nslookup و traceroute اتصال را بررسی میکنی. تمرین: مسیر اتصال به یک سایت را قدمبهقدم بررسی میکنی: IP داری؟ gateway جواب میدهد؟ اینترنت هست؟ DNS درست است؟
مسئله: «سایت باز نمیشود»، مشکل کجاست؟
Section titled “مسئله: «سایت باز نمیشود»، مشکل کجاست؟”از لحظهای که آدرس یک سایت را میزنی تا صفحه بیاید، دهها اتفاق در کار است: کامپیوتر باید آدرس IP داشته باشد، بداند اسم سایت چه IP ای است (DNS)، بداند بسته را از کجا بفرستد (gateway)، و مقصد هم جواب بدهد. «اینترنت قطع است» یعنی کدامیک؟ اگر ترتیب بررسی را بدانی، در یک دقیقه پیدایش میکنی.
تشبیه: پست
Section titled “تشبیه: پست”آدرس IP آدرس خانهی توست. gateway ادارهی پست محله است: هر نامهای که مقصدش بیرون از محله باشد را به آنجا میدهی. جدول مسیر دفترچهی راهنمای پست است: «نامههای این کد پستی مستقیم برو، بقیه را بده ادارهی پست». و DNS دفترچهی تلفن است: اسم («علی») را به آدرس تبدیل میکند.
مثالهای عملی
Section titled “مثالهای عملی”همهی آزمایشها روی ماشین آزمایشی من (یک کانتینر Ubuntu) اجرا شدهاند؛ آدرسهای خصوصی (مثل 172.17.0.2) مال شبکهی داخلی داکر است و روی کامپیوتر تو عددهای دیگری میبینی، ولی ساختار خروجیها و دستورها یکی است.
مثال ۱: من چه آدرسی دارم؟ ip a
Section titled “مثال ۱: من چه آدرسی دارم؟ ip a”ip a (کوتاهشدهی ip address) همهی interface ها و آدرسهایشان را میدهد. روی ماشین آزمایشی من چند interface مجازیِ بیاستفاده هم هست که شلوغش میکنند، پس فقط آدرسهای IPv4 را میخواهم (-4)؛ و نسخهی خلاصهی -br (brief):
echo "--- ip -4 a:"ip -4 aecho "--- نسخهی خلاصه (-br):"ip -br -4 aecho "--- آدرس سختافزاری (MAC) کارت شبکه:"ip link show eth0 | grep link/ether | awk '{print $2}'echo "--- فقط IP:"hostname -I--- ip -4 a:1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever11: eth0@if2471: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 65535 qdisc noqueue state UP group default link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever--- نسخهی خلاصه (-br):lo UNKNOWN 127.0.0.1/8eth0@if2471 UP 172.17.0.2/16--- آدرس سختافزاری (MAC) کارت شبکه:2e:05:9a:4f:b5:63--- فقط IP:172.17.0.2دو interface:
lo(loopback): کارت مجازی «خودِ همین ماشین» با آدرس127.0.0.1(همانlocalhost). ترافیکش هرگز بیرون نمیرود.eth0: کارت شبکهی اصلی، با آدرس172.17.0.2/16. (روی سرورهای دیگر نامشens3،enp0s3،wlan0… است.)UPیعنی فعال، وlink/etherآدرس MAC سختافزاری.
عدد بعد از / اندازهی شبکه را میگوید (CIDR): 172.17.0.2/16 یعنی «۱۶ بیت اول آدرس، شبکه است». هر آدرسی با همان ۱۶ بیت اول (172.17.x.x) همشبکه (همسایه) است و مستقیم در دسترس؛ بقیه را باید از gateway فرستاد. با ماژول ipaddress پایتون چند نمونه را حساب میکنم:
python3 - <<'EOF'import ipaddressfor cidr in ['172.17.0.2/16', '192.168.1.37/24', '10.0.0.5/8']: n = ipaddress.ip_interface(cidr).network print(f"{cidr:16} شبکه={n.network_address} ماسک={n.netmask} تعداد آدرس={n.num_addresses}")print("--- خصوصی (private) یا عمومی؟")for a in ['172.17.0.2', '192.168.1.37', '10.0.0.5', '1.1.1.1', '8.8.8.8']: print(f"{a:14}", "خصوصی" if ipaddress.ip_address(a).is_private else "عمومی")EOF172.17.0.2/16 شبکه=172.17.0.0 ماسک=255.255.0.0 تعداد آدرس=65536192.168.1.37/24 شبکه=192.168.1.0 ماسک=255.255.255.0 تعداد آدرس=25610.0.0.5/8 شبکه=10.0.0.0 ماسک=255.0.0.0 تعداد آدرس=16777216--- خصوصی (private) یا عمومی؟172.17.0.2 خصوصی192.168.1.37 خصوصی10.0.0.5 خصوصی1.1.1.1 عمومی8.8.8.8 عمومیسه محدودهی خصوصی (فقط برای شبکههای داخلی، در اینترنت مسیریابی نمیشوند) اینهاست: 10.0.0.0/8، 172.16.0.0/12 و 192.168.0.0/16. هر چه بیرون از اینها باشد (مثل 1.1.1.1) عمومی است. (روتر خانه با NAT آدرسهای خصوصی شبکهی داخل را به یک آدرس عمومی ترجمه میکند.)
مثال ۲: gateway و جدول مسیر، ip route
Section titled “مثال ۲: gateway و جدول مسیر، ip route”echo "--- ip route (جدول مسیر):"ip routeecho "--- بسته برای 1.1.1.1 از کجا میرود؟ (ip route get)"ip route get 1.1.1.1echo "--- و برای یک همسایهی همشبکه (172.17.0.5)؟"ip route get 172.17.0.5--- ip route (جدول مسیر):default via 172.17.0.1 dev eth0172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.2--- بسته برای 1.1.1.1 از کجا میرود؟ (ip route get)1.1.1.1 via 172.17.0.1 dev eth0 src 172.17.0.2 uid 1001 cache--- و برای یک همسایهی همشبکه (172.17.0.5)؟172.17.0.5 dev eth0 src 172.17.0.2 uid 1001 cacheدو سطر جدول مسیر را ببین:
default via 172.17.0.1 dev eth0: مسیر پیشفرض: «هر مقصدی که در سطرهای دیگر نبود، ازeth0به gateway172.17.0.1بده». gateway یک مسیریاب (router) است که بسته را به بیرون میرساند.172.17.0.0/16 dev eth0 ... src 172.17.0.2: «مقصدهای172.17.x.xهمسایهی ما هستند، مستقیم بفرست».
ip route get مقصد دقیقاً نشان میدهد برای یک مقصد خاص کدام سطر انتخاب میشود: برای 1.1.1.1 via (از gateway) و برای همسایه بدون via (مستقیم). هسته برای هر بسته دقیقترین سطر منطبق را انتخاب میکند.
مثال ۳: ping، آیا مقصد جواب میدهد؟
Section titled “مثال ۳: ping، آیا مقصد جواب میدهد؟”ping یک بستهی ICMP «echo request» میفرستد و منتظر پاسخ میماند. -c 2 یعنی دو بار (بدون آن تا Ctrl+C ادامه میدهد). برای عیبیابی از نزدیک به دور ping بزن: خودم، gateway، یک IP در اینترنت، و یک اسم:
echo "=== ۱) خودم (loopback):"ping -c 2 127.0.0.1echo "=== ۲) gateway:"ping -c 2 $(ip route | awk '/^default/ {print $3}')echo "=== ۳) یک آدرس در اینترنت (فقط IP، بدون DNS):"ping -c 2 1.1.1.1echo "=== ۴) یک اسم (DNS هم لازم است):"ping -c 2 example.com=== ۱) خودم (loopback):PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.051 ms64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.074 ms
--- 127.0.0.1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1022msrtt min/avg/max/mdev = 0.051/0.062/0.074/0.011 ms=== ۲) gateway:PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.124 ms64 bytes from 172.17.0.1: icmp_seq=2 ttl=64 time=0.064 ms
--- 172.17.0.1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1015msrtt min/avg/max/mdev = 0.064/0.094/0.124/0.030 ms=== ۳) یک آدرس در اینترنت (فقط IP، بدون DNS):PING 1.1.1.1 (1.1.1.1) 56(84) bytes of data.64 bytes from 1.1.1.1: icmp_seq=1 ttl=63 time=126 ms64 bytes from 1.1.1.1: icmp_seq=2 ttl=63 time=145 ms
--- 1.1.1.1 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1009msrtt min/avg/max/mdev = 126.318/135.719/145.120/9.401 ms=== ۴) یک اسم (DNS هم لازم است):PING example.com (172.66.147.243) 56(84) bytes of data.64 bytes from 172.66.147.243: icmp_seq=1 ttl=63 time=140 ms64 bytes from 172.66.147.243: icmp_seq=2 ttl=63 time=134 ms
--- example.com ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1001msrtt min/avg/max/mdev = 133.652/136.861/140.070/3.209 msخروجی هر سطر: 64 bytes from آدرس: icmp_seq=N ttl=T time=X ms: time زمان رفتوبرگشت (RTT)، و ttl عدد «طول عمر» بسته که با هر مسیریاب یکی کم میشود. آخر کار آمار میآید: 0% packet loss یعنی همهی بستهها جواب گرفتند و rtt min/avg/max خلاصهی زمانها. (در اینترنت واقعی زمان ping به gateway چند میلیثانیه و به یک سرور دور صدها میلیثانیه است.) وقتی کار نکند، دو شکل خطا داری:
echo "--- آدرسی که هیچکس جوابش را نمیدهد:"ping -c 1 -W 2 10.255.255.1echo "--- اسمی که وجود ندارد:"ping -c 1 no-such-host.invalid--- آدرسی که هیچکس جوابش را نمیدهد:PING 10.255.255.1 (10.255.255.1) 56(84) bytes of data.
--- 10.255.255.1 ping statistics ---1 packets transmitted, 0 received, 100% packet loss, time 0ms
--- اسمی که وجود ندارد:ping: no-such-host.invalid: Name or service not known100% packet loss: بسته رفت ولی جوابی برنگشت (مقصد خاموش، مسیر بسته، یا فایروال ICMP را رد میکند).Name or service not known: اسم تبدیل نشد؛ مشکل DNS است، نه شبکهی IP.
این دو را قاطی نکن: مشکل DNS و مشکل اتصال، دو بیماری متفاوتاند.
مثال ۴: DNS، dig و nslookup
Section titled “مثال ۴: DNS، dig و nslookup”DNS (Domain Name System) اسم را به آدرس IP تبدیل میکند. سیستم از فایل /etc/resolv.conf میفهمد DNS را از کجا بپرسد:
echo "--- /etc/resolv.conf (بدون توضیح):"grep -v '^#' /etc/resolv.conf | grep -v '^$'echo "--- dig example.com:"dig example.com--- /etc/resolv.conf (بدون توضیح):nameserver 192.168.65.7--- dig example.com:
; <<>> DiG 9.18.39-0ubuntu0.24.04.7-Ubuntu <<>> example.com;; global options: +cmd;; Got answer:;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63602;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:;example.com. IN A
;; ANSWER SECTION:example.com. 149 IN A 172.66.147.243example.com. 149 IN A 104.20.23.154
;; Query time: 2 msec;; SERVER: 192.168.65.7#53(192.168.65.7) (UDP);; WHEN: Sat Oct 03 21:51:30 UTC 2026;; MSG SIZE rcvd: 83خط nameserver آدرس سرور DNS است (اینجا یک آدرس خصوصی، سرور DNS داخلی داکر). خروجی dig:
QUESTION SECTION: چه چیزی پرسیده شد (example.comو نوع رکوردAیعنی IPv4).ANSWER SECTION: جوابها. عدد وسط (147) TTL است: کشها تا چند ثانیه میتوانند این جواب را نگه دارند. هر نشانی کهIN Aدارد یک سرور برای این اسم است (چند تا یعنی بار بین چند سرور پخش میشود).status: NOERRORیعنی موفق (NXDOMAINیعنی چنین اسمی نیست).Query timeوSERVER: چقدر طول کشید و از کدام DNS پرسیده شد.
برای خروجی کوتاه +short و برای انواع رکوردها بعد از اسم نوع را بنویس:
echo "--- A (IPv4) و AAAA (IPv6):"dig +short example.comdig +short AAAA example.comecho "--- NS (سرورهای نام دامنه):"dig +short NS example.comecho "--- MX (سرورهای ایمیل gmail.com، عدد = اولویت):"dig +short MX gmail.comecho "--- TXT:"dig +short TXT example.com | head -2echo "--- nslookup (ابزار قدیمیتر، همان کار):"nslookup example.com--- A (IPv4) و AAAA (IPv6):172.66.147.243104.20.23.154--- NS (سرورهای نام دامنه):hera.ns.cloudflare.com.elliott.ns.cloudflare.com.--- MX (سرورهای ایمیل gmail.com، عدد = اولویت):10 alt1.gmail-smtp-in.l.google.com.20 alt2.gmail-smtp-in.l.google.com.40 alt4.gmail-smtp-in.l.google.com.5 gmail-smtp-in.l.google.com.30 alt3.gmail-smtp-in.l.google.com.--- TXT:"_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9""v=spf1 -all"--- nslookup (ابزار قدیمیتر، همان کار):Server: 192.168.65.7Address: 192.168.65.7#53
Non-authoritative answer:Name: example.comAddress: 172.66.147.243Name: example.comAddress: 104.20.23.154یک نکتهی مهم: DNS ممکن است از هر resolver جواب متفاوتی بدهد. با @آدرس یک سرور مشخص را میپرسی؛ مثلاً همین اسم را از DNS سیستم و از دو DNS عمومی مقایسه کن:
echo "--- DNS سیستم:"dig +short example.comecho "--- 8.8.8.8:"dig +short @8.8.8.8 example.comecho "--- 1.1.1.1:"dig +short @1.1.1.1 example.comecho "--- سرور DNS که وجود ندارد (خطا):"dig +time=2 +tries=1 @192.0.2.1 example.com | head -1--- DNS سیستم:172.66.147.243104.20.23.154--- 8.8.8.8:104.20.23.154172.66.147.243--- 1.1.1.1:104.20.23.154172.66.147.243--- سرور DNS که وجود ندارد (خطا):;; communications error to 192.0.2.1#53: timed outدر این لحظه هر سه یک مجموعهی آدرس را دادند و فقط ترتیبشان فرق میکند (DNS معمولاً ترتیب آدرسها را میچرخاند تا بار پخش شود). ولی همیشه چنین نیست: سایتهای بزرگ از CDN استفاده میکنند و بسته به مکان تو آدرسهای متفاوتی میدهند، و بعضی DNS ها (برای فیلتر یا سرویسهای دیگر) جواب را عوض میکنند. وقتی «سایت یکجا باز میشود و جای دیگر نه»، مقایسهی DNS ها اولین ابزار توست. آخرین خط: وقتی سرور DNS جواب نمیدهد (communications error ... timed out) تا مدتی منتظر میماند و بعد خطا میدهد.
مثال ۵: /etc/hosts، فهرست محلی اسمها
Section titled “مثال ۵: /etc/hosts، فهرست محلی اسمها”قبل از پرسیدن از DNS، سیستم یک فایل محلی را نگاه میکند. ترتیب در /etc/nsswitch.conf تعیین میشود:
echo "--- /etc/hosts:"cat /etc/hostsecho "--- ترتیب جستجوی اسمها:"grep '^hosts' /etc/nsswitch.conf--- /etc/hosts:127.0.0.1 localhost::1 localhost ip6-localhost ip6-loopbackfe00:: ip6-localnetff00:: ip6-mcastprefixff02::1 ip6-allnodesff02::2 ip6-allrouters172.17.0.2 pc--- ترتیب جستجوی اسمها:hosts: files dnshosts: files dns یعنی اول files (همان /etc/hosts) و بعد dns. هر خط /etc/hosts اول آدرس IP و بعد یک یا چند اسم دارد. پس میشود هر اسمی را موقتاً به یک آدرس بست، مثلاً برای آزمایش یک سایت قبل از انتقال دامنه، یا مسدود کردن یک سایت:
echo "127.0.0.1 example.com" | sudo tee -a /etc/hosts > /dev/nullecho "--- getent hosts (همان راهی که برنامهها اسم را پیدا میکنند: hosts و بعد DNS):"getent hosts example.com | head -1echo "--- ping هم از همان راه:"ping -c 1 example.com | head -1echo "--- ولی dig به /etc/hosts نگاه نمیکند و مستقیم DNS میپرسد:"dig +short example.com | head -1echo "--- برگرداندن به حالت اول:"sudo sh -c "grep -v 'example.com' /etc/hosts > /tmp/hosts.new; cat /tmp/hosts.new > /etc/hosts; rm /tmp/hosts.new"getent hosts example.com | head -1--- getent hosts (همان راهی که برنامهها اسم را پیدا میکنند: hosts و بعد DNS):127.0.0.1 example.com--- ping هم از همان راه:PING example.com (127.0.0.1) 56(84) bytes of data.--- ولی dig به /etc/hosts نگاه نمیکند و مستقیم DNS میپرسد:172.66.147.243--- برگرداندن به حالت اول:172.66.147.243 example.comping و برنامهها آدرس 127.0.0.1 را گرفتند، ولی dig همان IP واقعی را نشان داد. نتیجه: dig و nslookup فقط DNS را میسنجند؛ برای دیدن آنچه برنامهها میبینند getent hosts را بزن. (در این ماشین آزمایشی /etc/hosts را با cat > عوض کردم نه sed -i، چون در کانتینر داکر آن فایل mount شده است و sed -i فایل را جابهجا میکند و خطا میدهد؛ روی سرور معمولی هر دو شکل کار میکنند.)
مثال ۶: traceroute، مسیر بستهها
Section titled “مثال ۶: traceroute، مسیر بستهها”traceroute نشان میدهد بسته برای رسیدن به مقصد از چه مسیریابهایی (hop) میگذرد. ترفندش این است که بستهها را با TTL کوچک میفرستد: مسیریاب اول TTL را صفر میکند و خبر میدهد، دومی با TTL بعدی، و همینطور تا مقصد:
echo "--- traceroute پیشفرض (بستههای UDP):"traceroute -n -m 4 -w 1 1.1.1.1echo "--- با بستههای ICMP (-I):"traceroute -I -n -m 6 -w 2 1.1.1.1--- traceroute پیشفرض (بستههای UDP):traceroute to 1.1.1.1 (1.1.1.1), 4 hops max, 60 byte packets 1 172.17.0.1 0.498 ms 0.417 ms 0.397 ms 2 * * * 3 * * * 4 * * *--- با بستههای ICMP (-I):traceroute to 1.1.1.1 (1.1.1.1), 6 hops max, 60 byte packets 1 172.17.0.1 0.120 ms * 0.015 ms 2 * 1.1.1.1 168.432 ms 168.328 ms-n یعنی اسمها را DNS نکن (سریعتر)، -m حداکثر تعداد hop، و -w چند ثانیه منتظر هر پاسخ بماند. هر سطر یک hop با سه زمانسنجی است. * * * یعنی از آن hop جوابی نیامد: همیشه به معنی قطعبودن نیست، چون بسیاری از مسیریابها (و فایروالها) پاسخدادن به این بستهها را بستهاند. در این ماشین آزمایشی، شبکهی داکر (NAT) مسیریابهای بعد از gateway را از دید ما پنهان میکند و فقط hop اول و مقصد دیده میشوند؛ روی یک سرور واقعی معمولاً ۸ تا ۱۵ hop میبینی و آنجا اولین hop که تأخیر یا ناپایداری ناگهانی نشان داد، مشکوک است.
مثال ۷: قدمبهقدم، اتصال به یک سایت را بررسی کن (تمرین اصلی)
Section titled “مثال ۷: قدمبهقدم، اتصال به یک سایت را بررسی کن (تمرین اصلی)”همهی دانستهها را در یک اسکریپت کوچک میگذارم که ترتیب «از نزدیک به دور» را دنبال میکند: IP ← gateway ← اینترنت با IP ← DNS ← اتصال به سایت:
#!/bin/bash# بررسی قدمبهقدم اتصال به یک سایت (از نزدیک به دور)site=${1:-example.com}ok() { echo " ✓ $1"; }bad() { echo " ✗ $1"; }
echo "۱) interface و IP:"ip -4 -br a | awk '$1 !~ /^lo/ {print " ", $1, $3}'
gw=$(ip route | awk '/^default/ {print $3; exit}')echo "۲) gateway ($gw):"ping -c 1 -W 2 "$gw" > /dev/null 2>&1 && ok "جواب میدهد" || bad "جواب نمیدهد"
echo "۳) اینترنت بدون DNS (1.1.1.1):"ping -c 1 -W 3 1.1.1.1 > /dev/null 2>&1 && ok "در دسترس" || bad "در دسترس نیست"
echo "۴) DNS ($site):"ip=$(dig +short +time=2 +tries=1 "$site" 2>/dev/null | grep -E '^[0-9.]+$' | head -1)[ -n "$ip" ] && ok "$site ← $ip" || bad "اسم تبدیل نشد"
echo "۵) اتصال HTTPS به $site:"code=$(curl -s -o /dev/null -m 6 -w '%{http_code}' "https://$site")[ "$code" != 000 ] && ok "پاسخ HTTP $code" || bad "اتصال برقرار نشد"bash netcheck.sh example.com۱) interface و IP: eth0@if2471 172.17.0.2/16۲) gateway (172.17.0.1): ✓ جواب میدهد۳) اینترنت بدون DNS (1.1.1.1): ✓ در دسترس۴) DNS (example.com): ✓ example.com ← 172.66.147.243۵) اتصال HTTPS به example.com: ✓ پاسخ HTTP 200همهی پنج قدم موفق بود. حالا یک خرابی واقعی بسازم: DNS سیستم را موقتاً به یک آدرس بیجواب (192.0.2.1) تغییر میدهم و همان اسکریپت را اجرا میکنم:
sudo cp /etc/resolv.conf /tmp/resolv.bakecho "nameserver 192.0.2.1" | sudo tee /etc/resolv.conf > /dev/nullbash netcheck.sh example.comecho "--- برگرداندن DNS:"sudo cp /tmp/resolv.bak /etc/resolv.confgrep -v '^#' /etc/resolv.conf | grep -v '^$'۱) interface و IP: eth0@if2471 172.17.0.2/16۲) gateway (172.17.0.1): ✓ جواب میدهد۳) اینترنت بدون DNS (1.1.1.1): ✓ در دسترس۴) DNS (example.com): ✗ اسم تبدیل نشد۵) اتصال HTTPS به example.com: ✗ اتصال برقرار نشد--- برگرداندن DNS:nameserver 192.168.65.7الگو را ببین: قدمهای ۱ تا ۳ سبز (IP، gateway و اینترنت با IP سالماند) و از قدم ۴ قرمز. نتیجه: «اینترنت هست؛ DNS خراب است»، یعنی دقیقاً همان سناریوی ابتدای درس. اگر قدم ۲ قرمز بود مشکل اتصال به شبکهی محلی (کابل، Wi-Fi، gateway) است؛ اگر ۱ قرمز بود، حتی IP نداری (DHCP، کارت شبکه).
ping 1.1.1.1 جواب میدهد ولی ping example.com میگوید Name or service not known. مشکل کجاست؟
اتصال IP سالم است (به 1.1.1.1 رسیدی)، فقط اسم تبدیل نمیشود: /etc/resolv.conf یا سرور DNS را بررسی کن.
پشت پرده: فایلهای شبکه
Section titled “پشت پرده: فایلهای شبکه”همهی این ابزارها در نهایت چند فایل و یک پایگاه دادهی داخل هسته را میخوانند:
| چیز | کجا | چه میگوید |
|---|---|---|
| IP و interface ها | هسته (ip a) |
آدرس هر کارت شبکه |
| جدول مسیر | هسته (ip route) |
بسته برای هر مقصد از کجا برود |
| سرور DNS | /etc/resolv.conf |
از چه آدرسی اسم را بپرس |
| فهرست محلی اسمها | /etc/hosts |
اسم ← IP، قبل از DNS |
| ترتیب جستجو | /etc/nsswitch.conf |
hosts: files dns |
| نام این ماشین | /etc/hostname |
نام ماشین؛ با hostname هم دیده میشود |
echo "--- نام ماشین:"hostnamecat /etc/hostnameecho "--- هر برنامه برای باز کردن یک اسم همین مسیر را میرود: getent hosts localhost"getent hosts localhost--- نام ماشین:pcpc--- هر برنامه برای باز کردن یک اسم همین مسیر را میرود: getent hosts localhost::1 localhost ip6-localhost ip6-loopbackمسیر یک اسم در برنامهها (مثل ping، curl، مرورگر): ۱) /etc/nsswitch.conf را میخواند؛ ۲) اول /etc/hosts؛ ۳) اگر نبود، DNS آدرسهای /etc/resolv.conf؛ ۴) آدرس را میگیرد و بسته را طبق جدول مسیر میفرستد. فایلهایی مثل /etc/resolv.conf را در بعضی سیستمها یک سرویس مدیریت میکند و ویرایش دستیشان گاهی بعد از مدتی بازنویسی میشود؛ در این ماشین آزمایشی داکر آن را ساخته و ویرایش دستی مانده، ولی روی سرور خودت اول ببین چه کسی مدیریتش میکند.
جدولهای مرجع
Section titled “جدولهای مرجع”| دستور | کار |
|---|---|
ip a / ip -br -4 a |
interface ها و آدرسها (کامل / خلاصه) |
ip route |
جدول مسیر و gateway |
ip route get مقصد |
مسیر انتخابشده برای یک مقصد |
ping -c 3 مقصد |
آیا مقصد جواب میدهد؟ |
traceroute -n مقصد |
hop های مسیر (-I ICMP) |
dig اسم / dig +short اسم |
پرسش DNS (کامل / کوتاه) |
dig +short MX اسم |
نوع رکورد (A، AAAA، MX، NS، TXT) |
dig @8.8.8.8 اسم |
پرسیدن از یک DNS مشخص |
nslookup اسم |
پرسش سادهی DNS |
getent hosts اسم |
همان که برنامهها میبینند (hosts + DNS) |
hostname / hostname -I |
نام ماشین / IP ها |
| نوع رکورد DNS | معنی |
|---|---|
A / AAAA |
آدرس IPv4 / IPv6 |
CNAME |
نام مستعار (اسم دیگری که ارجاع میدهد) |
MX |
سرور ایمیل (با اولویت) |
NS |
سرورهای نام دامنه |
TXT |
متن (تأیید دامنه، SPF و…) |
اشتباهات رایج
Section titled “اشتباهات رایج”۱) ifconfig و netstat
Section titled “۱) ifconfig و netstat”ifconfigbash: ifconfig: command not foundifconfig (و netstat، route) از بستهی قدیمی net-tools هستند و روی توزیعهای جدید نصب نمیشوند. راهحل: ip a (بهجای ifconfig)، ip route (بهجای route) و ss (بهجای netstat؛ درس بعد).
۲) فرضکردن اینکه «ping جواب نمیدهد یعنی سرویس خاموش است»
Section titled “۲) فرضکردن اینکه «ping جواب نمیدهد یعنی سرویس خاموش است»”بعضی فایروالها فقط ping (ICMP) را میبندند و بقیهی ترافیک سالم میماند. با یک وبسرور کوچک و یک قانون فایروال روی ماشین systemdدار آزمایشی ببین:
python3 -m http.server 8099 --bind 127.0.0.1 > /dev/null 2>&1 &sleep 1iptables -A INPUT -p icmp --icmp-type echo-request -j DROPecho "--- ping (ICMP بسته شده):"ping -c 1 -W 1 127.0.0.1 | tail -2echo "--- ولی وبسرور سالم است:"curl -sI http://127.0.0.1:8099 | head -1iptables -D INPUT -p icmp --icmp-type echo-request -j DROPkill %1echo "--- بعد از برداشتن قانون، ping دوباره جواب میدهد:"ping -c 1 -W 1 127.0.0.1 | tail -2--- ping (ICMP بسته شده):1 packets transmitted, 0 received, 100% packet loss, time 0ms
--- ولی وبسرور سالم است:HTTP/1.0 200 OK--- بعد از برداشتن قانون، ping دوباره جواب میدهد:1 packets transmitted, 1 received, 0% packet loss, time 0msrtt min/avg/max/mdev = 0.061/0.061/0.061/0.000 ms100% packet loss ولی HTTP/1.0 200 OK: سرویس سالم بود و فقط ping بسته. راهحل: برای سنجش «سرویس» بهجای ping، همان پورت را آزمایش کن (curl، nc -zv؛ درس بعد).
۳) استفاده از dig برای دیدن آنچه برنامه میبیند
Section titled “۳) استفاده از dig برای دیدن آنچه برنامه میبیند”مثال ۵: با یک خط /etc/hosts اسم به 127.0.0.1 رفت ولی dig همان آدرس واقعی را نشان داد. راهحل: getent hosts اسم.
۴) نوشتن /etc/hosts با ترتیب اشتباه
Section titled “۴) نوشتن /etc/hosts با ترتیب اشتباه”echo "myapp.test 127.0.0.1" | sudo tee -a /etc/hosts > /dev/nullecho "--- ترتیب اشتباه (اسم قبل از IP):"getent hosts myapp.test || echo "(پیدا نشد)"ping -c 1 myapp.testecho "--- ترتیب درست (IP بعد اسم):"sudo sh -c "grep -v 'myapp.test' /etc/hosts > /tmp/hosts.new; cat /tmp/hosts.new > /etc/hosts; rm /tmp/hosts.new"echo "127.0.0.1 myapp.test" | sudo tee -a /etc/hosts > /dev/nullgetent hosts myapp.testping -c 1 myapp.test | head -1sudo sh -c "grep -v 'myapp.test' /etc/hosts > /tmp/hosts.new; cat /tmp/hosts.new > /etc/hosts; rm /tmp/hosts.new"--- ترتیب اشتباه (اسم قبل از IP):(پیدا نشد)ping: myapp.test: Name or service not known--- ترتیب درست (IP بعد اسم):127.0.0.1 myapp.testPING myapp.test (127.0.0.1) 56(84) bytes of data.ستون اول /etc/hosts همیشه آدرس IP است و بعدش اسمها. با ترتیب برعکس، خط نادیده گرفته میشود و اسم از DNS پرسیده میشود (که چنین اسمی ندارد؛ برای همین ping خطای تبدیل اسم میدهد). راهحل: IP نام. (پسوند .test برای آزمایش رزرو شده و در اینترنت واقعی وجود ندارد؛ پس برای نامهای محلی تمرینی امن است.)
۵) فراموشکردن -c در ping
Section titled “۵) فراموشکردن -c در ping”ping بدون -c تا ابد ادامه میدهد (تا Ctrl+C). در اسکریپتها همیشه ping -c 1 (یا -c 3) و بهتر -W 2 (حداکثر انتظار) بگذار تا گیر نکنی.
آدرس IP کارت شبکهی eth0 و آدرس gateway پیشفرض را با دو دستور پیدا کن.
دیدن جواب
ip -br -4 a show eth0ip route | awk '/^default/ {print "gateway:", $3}'eth0@if2471 UP 172.17.0.2/16gateway: 172.17.0.1تمرین اصلی: مسیر اتصال به یک سایت را قدمبهقدم بررسی کن. اسکریپت netcheck.sh را برای wikipedia.org اجرا کن. بعد خودت قدم ۴ و ۵ را با دو دستور مستقیم بزن (dig +short و curl -I) و ببین نتیجه مثل اسکریپت است.
دیدن جواب
bash netcheck.sh wikipedia.orgecho "=== دستی:"dig +short wikipedia.org | head -1curl -sI -m 6 https://wikipedia.org | head -1۱) interface و IP: eth0@if2471 172.17.0.2/16۲) gateway (172.17.0.1): ✓ جواب میدهد۳) اینترنت بدون DNS (1.1.1.1): ✓ در دسترس۴) DNS (wikipedia.org): ✓ wikipedia.org ← 185.15.59.224۵) اتصال HTTPS به wikipedia.org: ✓ پاسخ HTTP 301=== دستی:185.15.59.224HTTP/2 301یک نام محلی بساز: با /etc/hosts اسم myapp.test را به 127.0.0.1 بیند، با python3 -m http.server 8097 یک وبسرور بالا بیاور، و با curl http://myapp.test:8097 به آن وصل شو. بعد همهچیز را پاک کن (سرور و خط hosts).
دیدن جواب
echo "127.0.0.1 myapp.test" | sudo tee -a /etc/hosts > /dev/nullpython3 -m http.server 8097 --bind 127.0.0.1 > /dev/null 2>&1 &sleep 1getent hosts myapp.testcurl -sI http://myapp.test:8097 | head -1kill %1sudo sh -c "grep -v 'myapp.test' /etc/hosts > /tmp/hosts.new; cat /tmp/hosts.new > /etc/hosts; rm /tmp/hosts.new"getent hosts myapp.test || echo "(پاک شد)"127.0.0.1 myapp.testHTTP/1.0 200 OK(پاک شد)آزمونک
Section titled “آزمونک”در 192.168.1.37/24 عدد 24 چه میگوید؟
/24 یعنی ماسک 255.255.255.0؛ همهی 192.168.1.x همشبکهاند.
خط default via 172.17.0.1 dev eth0 در ip route یعنی…
مسیر پیشفرض: همهچیز بیرون از شبکهی محلی را به gateway بده.
ping 1.1.1.1 جواب میدهد ولی ping example.com میگوید Name or service not known. مشکل چیست؟
اتصال IP سالم است؛ فقط تبدیل اسم به IP خراب است.
مرتبهی جستجوی اسم با hosts: files dns در nsswitch.conf یعنی…
برای همین یک خط در /etc/hosts بر DNS غلبه میکند.
برای دیدن اینکه یک برنامه (مثل curl) اسم را به چه آدرسی تبدیل میکند، کدام درستتر است؟
dig و nslookup فقط DNS را میسنجند و /etc/hosts را نادیده میگیرند.
ping به یک سرور 100% packet loss دارد ولی سایتش باز میشود. چرا ممکن است؟
ping فقط ICMP را میسنجد، نه وضعیت سرویس.
جمعبندی
Section titled “جمعبندی”ip a: interface ها و آدرسها (lo= خودِ ماشین،eth0= کارت اصلی)./16،/24و… یعنی چند بیت اول، بخش شبکه است. خصوصی:10/8،172.16/12،192.168/16.ip route: جدول مسیر؛default via Xیعنی gateway.ip route get مقصدمسیر انتخابشده را نشان میدهد.ping -c Nبرای سنجش دسترسی؛100% packet loss(جواب برنگشت) در برابرName or service not known(DNS). فرق ICMP با سرویس را فراموش نکن.- DNS:
/etc/resolv.conf(سرور)،digوnslookup؛dig +short TYPE اسم،dig @سرور اسم؛ جوابها ممکن است از resolver های مختلف فرق کنند. /etc/hostsقبل از DNS خوانده میشود (nsswitch.conf)؛getent hostsهمان را میبیند که برنامهها میبینند.traceroute -nhop ها را نشان میدهد؛* * *همیشه قطع نیست.- عیبیابی قدمبهقدم: IP ← gateway ← اینترنت با IP ← DNS ← اتصال به سرویس.
| دستور | کاری که میکند |
|---|---|
ip -br -4 a | interface ها و IP ها (خلاصه) |
ip route | جدول مسیر و gateway |
ip route get 1.1.1.1 | مسیر یک مقصد |
ping -c 3 -W 2 مقصد | آیا جواب میدهد؟ |
dig +short اسم / dig +short MX اسم | DNS (A یا نوع دیگر) |
dig +short @8.8.8.8 اسم | پرسیدن از یک DNS مشخص |
nslookup اسم | پرسش سادهی DNS |
getent hosts اسم | همان که برنامهها میبینند |
cat /etc/resolv.conf | DNS سیستم |
echo "127.0.0.1 نام" | sudo tee -a /etc/hosts | نام محلی |
traceroute -n -I مقصد | مسیر hop ها (با ICMP) |
hostname / hostname -I | نام و IP ماشین |