المرحلة 07 — يداك على السلك
هنا يلتحم الجذعان تماماً. كل أداةٍ نافذةٌ على طبقةٍ بنيتَها. سنفتحها كلها بعمق، نضيف nc و telnet (لتصير العميل/الخادم بيدك)، نتقن لبنات Bash، ثم نواجه التاسكات السبعة كألغازٍ — لا كواجباتٍ تُسلَّم.
النبذة
توقّف وتأمّل أين صرت: تستطيع أن تشرح، من الإلكترون، كيف يصل GET / HTTP/1.1 إلى خادمٍ عبر العالم ويعود. الآن الأدوات لن تكون «أوامر تُحفَظ» — كل واحدةٍ ستراها كـمنظارٍ على طبقةٍ محدّدة. هذا الإطار وحده يجعلك تتذكّرها دون حفظ.
| الأداة | الطبقة التي تكشفها | السؤال الذي تجيب عليه |
|---|---|---|
ip link / ifconfig | L2 | ما واجهاتي وما عناوين MAC-ها؟ |
ip addr | L2+L3 | ما عناوين IP المربوطة بكل واجهة؟ |
ip route / ip neigh | L3 | كيف أوجّه؟ مَن جيراني (ARP)؟ |
ping / traceroute | L3 (ICMP) | هل الوجهة حيّة؟ ما المسار؟ |
ss / netstat | L4 | أي منافذٍ مفتوحة، ومن يملكها؟ |
nc / telnet | L4→L7 | كن العميل أو الخادم بيدك |
أ. ip مقابل ifconfig — منظار L2/L3
ifconfig من حزمة net-tools القديمة (لم تَعُد مثبّتةً افتراضياً على Ubuntu الحديثة)؛ ip من حزمة iproute2 الحديثة. الأخيرة تتكلّم مع النواة عبر netlink (واجهةٌ حديثة منظَّمة)، بينما ifconfig تقرأ تجريداتٍ أقدم. ولهذا مخرجاتهما تختلف شكلاً — وهذا سبب اختلاف حلول الطلّاب لنفس التاسك.
baship link show # L2: الواجهات + MAC (link/ether) ip addr show # L2+L3: + عناوين IP (inet = IPv4, inet6 = IPv6) ip -4 addr show # IPv4 فقط
سطرٌ نموذجي من ip addr: inet 10.0.2.15/24 brd 10.0.2.255 scope global enp0s3. لاحظ أن كل ما تحتاجه لتاسك «أظهر كل عناوين IPv4» موجود: تصفية أسطر inet، وأخذ الحقل الذي فيه العنوان/CIDR، وقصّ الـ /24. (الأدوات: grep, awk/cut.)
هذه نافذة basics_1 task 1 (1-show_attached_IPs). لاحظ أن المخرَج المتوقّع يتضمّن 127.0.0.1 — أي يشمل الـ loopback (المرحلة 05)، فالحل لا يستثنيه.
ب. ss / netstat — منظار L4
هذه نافذة basics_0 task 4، وأهم منظارٍ تشخيصي. كل عمودٍ فيها مفهومٌ بنيتَه:
bashss -tulpn │││││ ││││└ n: أرقام لا أسماء (لا تحويل 22→ssh) │││└─ p: العملية المالكة (PID/program) — يحتاج صلاحية ││└── l: المستمعة فقط (listening) │└─── u: UDP └──── t: TCP
اقرأ أعمدة netstat -lp بعينٍ مشتقّة:
textProto Local Address Foreign Address State PID/Program tcp *:ssh *:* LISTEN 1240/sshd └─socket(L4)─┘ └خادمٌ ينتظر┘ * = 0.0.0.0 (كل الواجهات، م.05)
Local Address= الـ socket (IP:port).*=0.0.0.0(مكشوف).127.0.0.1= محلّيٌّ فقط.State = LISTEN= خادمٌ ينتظر اتصالاً (تذكّر: TCP له حالات؛ UDP لا «يستمع» بنفس المعنى — لا مصافحة — فلا تظهر لهState).PID/Program= أيّ عمليةٍ تملك الـ socket (يحتاج root — تذكّر منطق الصلاحيات).
خبيئة + لغز: مخرَج هولبرتون المتوقّع يُظهر أسماء خدماتٍ (*:ssh, *:sunrpc) لا أرقاماً، ويُظهر sockets من نوع unix أيضاً، و«only servers» في العنوان. فكّر: أي رايات netstat تنتج هذا بالضبط؟ (هل فيها -n؟ هل فيها -t/-u التي تخفي unix sockets؟) استنتج التركيبة من المخرَج — لا تبحث عنها. هذا نصف المتعة.
netstat يقرأ /proc/net/* (ملفّاتٌ نصّية تُحدَّث ببطء)؛ ss يستعلم النواة مباشرةً عبر netlink (sock_diag) ← أسرع بكثير على آلافٍ من الاتصالات. هولبرتون يطلب netstat تحديداً، لكن في العمل الحقيقي ss هو المعيار.
ج. nc (netcat) و telnet — كن أنت الـ socket
حتى الآن كنت تفحص اتصالات غيرك. هاتان الأداتان تجعلانك تنشئ اتصالاً بيدك — أعظم طريقةٍ لتجسيد طبقة النقل.
bash# خادم: استمع على منفذ (basics_1 task 2) nc -l 98 # بعض الإصدارات: nc -l -p 98 أو nc -lp 98 # عميل: اتصل واكتب nc 127.0.0.1 98 # أو: telnet 127.0.0.1 98
nc -l <port>ينشئ خادمَ TCP يستمع (يحتاج sudo لمنفذٍ <1024 — م.03). ما تكتبه في طرفٍ يظهر في الآخر: لأنك بنيتَ tunnel TCP خاماً بين socketين.nc -u ...= UDP بدل TCP. جرّبه وقارن السلوك (لا مصافحة).telnet host port= عميل TCP خام: يقيم المصافحة الثلاثية (م.03) ثم يعطيك أنبوب بايتاتٍ نصّياً.
bashtelnet example.com 80 # بعد الاتصال اكتب (ثم Enter مرتين): GET / HTTP/1.1 Host: example.com
سيردّ الخادم بـ HTTP خام. لقد صرتَ متصفّحاً. هذا يثبت بصرياً أن طبقة التطبيق (L7) ليست سحراً — مجرّد نصٍّ متّفقٍ عليه فوق TCP الذي بنيتَه. (telnet ممتاز لفحص «هل المنفذ مفتوح وهل الخدمة تتكلّم» — أداة تشخيصٍ لا تُقدَّر.)
د. لبنات Bash (لأن أربع تاسكاتٍ سكربتات)
لن أشرح Bash من الصفر — أنت مبرمج. سأربط كل لبنةٍ بـ«ليش» التاسك:
| اللبنة | ليش نحتاجها في التاسكات |
|---|---|
#!/usr/bin/env bash | السطر الأول الإلزامي. ليش env؟ يبحث عن bash في PATH بدل تثبيت مسارٍ صلب — قابليةٌ للنقل بين الأنظمة. |
| تعليق السطر الثاني | متطلَّب هولبرتون صراحةً: سطرٌ ثانٍ يشرح ما يفعل السكربت. |
$1, $2 ... | المعاملات الموضعية: وسائط السطر (تاسك ping يأخذ IP في $1). |
$# | عدد الوسائط: لفحص «هل مُرّر وسيط؟» (تاسك ping: إن $# -eq 0 اطبع Usage). |
[ -z "$1" ] | اختبار «هل $1 فارغ؟» — بديلٌ شائع لفحص غياب الوسيط. اقتبس "$1" دائماً. |
ping -c 5 | الراية -c = count؛ بلا حصرٍ يَطلب للأبد. التاسك يطلب 5 طلباتٍ بالضبط. |
cut -d: -f2 | قصّ حقلٍ من سطر: -d المحدِّد، -f رقم الحقل. لتفكيك مخرجات ifconfig/ip. |
chmod +x | كل سكربتات هولبرتون يجب أن تكون قابلةً للتنفيذ. |
هولبرتون يطلب اجتياز shellcheck بلا أخطاء. أشهر تحذير ستقابله SC2086: «اقتبس متغيّراتك لتجنّب word splitting». لماذا؟ لو كان $1 = "8.8.8.8 ; rm -rf" فإن ping $1 بلا اقتباسٍ قد ينقسم لكلماتٍ متعدّدة بشكلٍ خطير. الحل: ping "$1". هذا ليس إرضاءً لأداةٍ — إنه أمانٌ حقيقي. تثبيت الأداة: sudo apt-get install shellcheck (هولبرتون يطلب إصدار 0.7.0).
ألغاز المواجهة (Boss Fights) — التاسكات السبعة
اكتب كلاً منها بيدك قبل أن تفتح أي حل. القيود ليست تعجيزاً — كلٌّ منها يفرض استعمال مفهومٍ بنيتَه. لا تفتح 08-solutions-vault.md حتى تكافح كل واحدٍ بجدّية.
basics_0 (الأسئلة الاختيارية: 0,1,2,3)
هذه لستَ بحاجةٍ لحلٍّ مكتوب — اشتققتَها في المراحل 04, 02, 01, 03 على الترتيب. التحدي الحقيقي: لا تكتفِ باختيار الرقم — برهِن لماذا كل خيارٍ خاطئٍ خاطئ. إن عجزتَ عن دحض خيارٍ، عُد للمرحلة المناسبة. (الخريطة الكاملة في coverage-map.md.)
4-TCP_and_UDP_portsسكربتٌ يعرض المنافذ المستمعة فقط، مع PID واسم البرنامج لكل socket. القيود:
- يطابق مخرَج هولبرتون: أسماء خدماتٍ (لا أرقام)، يشمل tcp/udp/unix، «only servers».
- استنتج رايات
netstatمن المخرَج المتوقّع (الجزء «ب» أعلاه يلمّح: هل فيه-n؟). - shellcheck نظيف، السطر الأول الشيبانغ، السطر الثاني تعليق.
5-is_the_host_on_the_networkسكربتٌ يفحص IP يُمرَّر كوسيط. القيود:
- بلا وسيطٍ → يطبع
Usage: 5-is_the_host_on_the_network {IP_ADDRESS}(بالضبط). - مع وسيطٍ →
pingله 5 مرّات بالضبط. - فكّر: كيف تكتشف غياب الوسيط (
$#أم[ -z ])؟ كيف تحدّ ping بـ 5؟ هل تقتبس"$1"؟
0-change_your_home_IP (basics_1)سكربتٌ يجعل localhost → 127.0.0.2 و facebook.com → 8.8.8.8. القيود:
- استبدل تعيين localhost القائم، لا تكدّس (مصيدة المرحلة 06).
- أضِف تعيين facebook.com.
- يحتاج sudo (ملف نظام). فكّر بأنظف أداةٍ للاستبدال داخل ملف (المرحلة 06، س.3).
1-show_attached_IPsسكربتٌ يطبع كل عناوين IPv4 النشطة، عنواناً في سطر (المخرَج يشمل 127.0.0.1). القيود:
- اختر منظارك (
ipأمifconfig؟ أيّهما مضمونٌ على Ubuntu 22.04؟). - صفّ أسطر IPv4 فقط (لا IPv6)، واقصّ العنوان من الـ CIDR/الزوائد. (
grep+awk/cut.)
2-port_listening_on_localhostسكربتٌ يستمع على المنفذ 98 على localhost. القيود:
- استخدم
ncفي وضع الاستماع. - لماذا قد يحتاج sudo؟ (98 < 1024 — م.03.) كيف تتحقّق أنه يعمل؟ (من طرفٍ آخر بـ
telnet localhost 98واكتب نصّاً — يجب أن يظهر عندك.)
الخلاصة وموقعك على الشجرة
- فتحتَ كل منظار:
ip/ifconfig(L2/L3)،ss/netstat(L4)،ping/traceroute(L3/ICMP)،nc/telnet(L4→L7) — وكلٌّ مرتبطٌ بطبقةٍ بنيتَها، لا محفوظ. - أتقنتَ لبنات Bash اللازمة، وفهمتَ
envوالـ shebang و SC2086 و sudo *كحلولٍ لمشاكل* لا كطقوس. - واجهتَ التاسكات السبعة كألغازٍ مشتقّةٍ من المنهج، لا كواجباتٍ غريبة.
اكتملت الشجرة. الجذعان (المكدّس + الأدوات) التحما في كل عقدة. ما عليك الآن إلا أن تكتب الحلول بيدك، ثم — وفقط بعدها — تفتح القبو لتقارن.
← المرجع السريع: reference-cards.md · خريطة التغطية: coverage-map.md ← بعد الكفاح فقط: 08-solutions-vault.md