সরাসরি পর্বে যান
পর্ব ০৬ · ৬২-এর মধ্যে · মডিউল ১

Linux-এ নেটওয়ার্ক দেখা — ip, ping, ss, curl আর /proc/net

Seeing the Network on Linux — ip, ping, ss, curl and /proc/net

Taught in Bangla, this lesson is a hands-on tour of Linux networking commands in a live terminal: ip addr, ip route and ip neigh, finding listening ports with ss -tulpn, testing reachability with ping, traceroute, tracepath and mtr, dig, curl -v and a raw TCP connection with nc, reading /proc/net and /sys/class/net, a C program that finds its own socket, and tcpdump and Wireshark with ethics.

এই পর্বে যা শিখবেন

  • ip addr-এর আউটপুটের প্রতিটি শব্দের মানে — interface, MAC, IPv4/IPv6 ঠিকানা আর state
  • Default gateway, ARP cache আর listening socket খুঁজে বের করা, আর Windows ও macOS-এ একই কাজের কমান্ড
  • ping, traceroute, dig, curl -v, nc দিয়ে “সমস্যাটা কোন স্তরে” তা আলাদা করা
  • /proc/net/tcp-এর একটি লাইন হাতে decode করা — hex ঠিকানা, port আর TCP state
  • Packet capture-এর প্রাথমিক ধারণা আর তার নৈতিক ও আইনি সীমা

১ · কেন এই পর্ব — নেটওয়ার্ককে চোখে দেখা

আগের পাঁচটি পর্বে আমরা নেটওয়ার্কের ধারণা গড়েছি — স্তর, packet, delay. কিন্তু ধারণা যতই পরিষ্কার হোক, নিজের ল্যাপটপে সেগুলো দেখতে না পেলে মনে হয় সবই বইয়ের কথা। এই পর্বটি একটি ল্যাব পর্ব। এখানে শেখা কমান্ডগুলো পুরো কোর্সে বারবার ফিরে আসবে: ARP দেখতে ip neigh, TCP state দেখতে ss, DNS বুঝতে dig, HTTP বুঝতে curl -v.

ধরুন আপনি মহল্লার নতুন ডাকপিয়ন। কাজ শুরুর আগে তিনটি জিনিস জানতে হবে: আপনার নিজের অফিসের ঠিকানা কী, মহল্লার বাইরে চিঠি গেলে কোন বড় ডাকঘরে পাঠাবেন, আর পাশের বাড়িগুলোর নম্বর কোন দরজার সাথে মেলে। নেটওয়ার্কেও ঠিক তাই — ip addr বলে আপনার ঠিকানা, ip route বলে বাইরের চিঠি কোন দরজায় যাবে, ip neigh বলে পাশের যন্ত্রগুলোর “দরজার নম্বর” (MAC). আর ss হলো অফিসের রিসেপশনের খাতা — কোন কাউন্টারে (port) কে বসে আছে আর কার সাথে কথা চলছে।

এই পর্বের কমান্ডগুলো চালাতে হলে একটি Linux shell লাগবে — নিজের Linux, Windows-এর WSL, বা কোনো ক্লাউড VM. Terminal খোলা, cd, ls, pipe (|), grep আর man যদি নতুন হয়, আগে অপারেটিং সিস্টেম কোর্সের Linux terminal পর্বটি দেখে নিন; এখানে সেগুলো আবার শেখানো হবে না।

পুরোনো টুল বনাম আধুনিক টুল

অনলাইনে পুরোনো টিউটোরিয়ালে (আর অনেক সময় AI-এর উত্তরেও) দেখবেন ifconfig, netstat, route, arp. এগুলো net-tools নামের একটি পুরোনো প্যাকেজের অংশ। বহু বছর ধরে এর উন্নয়ন প্রায় থেমে ছিল, আর আধুনিক Linux-এর অনেক সুবিধা (একটি interface-এ অনেক ঠিকানা, একাধিক routing table, network namespace) এটি ঠিকমতো দেখাতে পারে না। এর জায়গা নিয়েছে iproute2 — যার প্রধান কমান্ড ip আর ss. Ubuntu, Debian, Fedora-র মতো বেশিরভাগ আধুনিক distribution-এ iproute2 আগে থেকেই থাকে, আর ছোট (minimal) ইনস্টলেশনে net-tools প্রায়ই থাকে না — তাই ifconfig: command not found দেখে অবাক হবেন না।

কাজLinux (আধুনিক)Linux (পুরোনো টুল, মূলত net-tools)WindowsmacOS
Interface আর ঠিকানাip addr, ip -br addrifconfigipconfig /all, Get-NetIPAddressifconfig
Routing tableip routeroute -n, netstat -rnroute print, Get-NetRoutenetstat -rn
ARP / neighbourip neigharp -narp -a, Get-NetNeighborarp -a
Socket আর portss -tulpnnetstat -tulpnnetstat -ano, Get-NetTCPConnectionnetstat -an, lsof -i -P
পৌঁছানো যায় কি নাpingpingping, Test-NetConnectionping
পথের routertraceroute, tracepath, mtrtraceroutetracert, pathpingtraceroute
DNSdig, host, resolvectlnslookupnslookup, Resolve-DnsNamedig, nslookup
HTTPcurl -vwgetcurl.exe, Invoke-WebRequestcurl
Packet capturetcpdump, Wireshark—Wireshark, pktmontcpdump, Wireshark

macOS-এর ifconfig আর Linux-এর ifconfig এক নয়। macOS এসেছে BSD পরিবার থেকে; সেখানে ifconfig আর netstat এখনো প্রধান টুল এবং নিয়মিত হালনাগাদ হয়। ip আর ss macOS-এ নেই (Linux kernel-এর netlink interface-এর ওপর নির্ভর করে)। Windows-এর ipconfig-এর নাম কাছাকাছি হলেও এটি সম্পূর্ণ আলাদা প্রোগ্রাম। তাই কোনো কমান্ড দেখলে আগে জিজ্ঞেস করুন: “এটা কোন OS-এর?”

২ · আমার ঠিকানা কী — ip addr আর interface

নেটওয়ার্কের সাথে কম্পিউটারের প্রতিটি সংযোগ-বিন্দুকে বলে network interface. ল্যাপটপে সাধারণত তিনটি থাকে: Wi-Fi কার্ড, Ethernet পোর্ট আর একটি কাল্পনিক interface — loopback (lo), যেটি দিয়ে কম্পিউটার নিজের সাথেই কথা বলে। প্রতিটি interface-এর থাকতে পারে একটি হার্ডওয়্যার ঠিকানা (MAC address), এক বা একাধিক IP address, আর একটি MTU — একবারে সবচেয়ে বড় কত বাইটের packet পাঠানো যায়।

নিচে ঢাকার একটি বাসার Wi-Fi-তে যুক্ত সাধারণ Ubuntu ল্যাপটপের ip addr আউটপুট। এটি একটি উদাহরণ — আপনার যন্ত্রের নাম, MAC আর ঠিকানা আলাদা হবে। “পরে” চেপে লাইন ধরে ধরে পড়ুন:

11: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN2    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:003    inet 127.0.0.1/8 scope host lo4    inet6 ::1/128 scope host52: enp3s0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 state DOWN6    link/ether 8c:16:45:3a:7e:21 brd ff:ff:ff:ff:ff:ff73: wlp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP8    link/ether 4c:d5:77:1b:9e:42 brd ff:ff:ff:ff:ff:ff9    inet 192.168.0.105/24 brd 192.168.0.255 scope global dynamic wlp2s010       valid_lft 85980sec preferred_lft 85980sec11    inet6 fe80::9a3c:2f1e:7b44:c1d0/64 scope link
এই লাইন থেকে যা জানলাম
interface
ক্ষেত্র
মানে
  1. প্রথম interface — lo. শুরুর 1: হলো kernel-এর দেওয়া ক্রমিক নম্বর। কোণবন্ধনীর ভেতরের শব্দগুলো flag: LOOPBACK (নিজের ভেতরেই ঘোরে), UP (চালু)। mtu 65536 — loopback-এ কোনো তার নেই, তাই বিশাল packet-ও চলে। state UNKNOWN দেখে ভয় পাবেন না; loopback-এর জন্য এটিই স্বাভাবিক, কারণ এর কোনো “তার লাগানো আছে কি না” অবস্থা নেই।
  2. Loopback-এর ঠিকানা। inet মানে IPv4 ঠিকানা: 127.0.0.1/8. পুরো 127.0.0.0/8 ব্লকটিই loopback-এর জন্য সংরক্ষিত। scope host মানে ঠিকানাটি শুধু এই যন্ত্রের ভেতরে অর্থবহ — বাইরের কেউ এতে পৌঁছাতে পারে না। inet6 ::1/128 হলো IPv6-এর loopback.
  3. Ethernet পোর্ট — তার নেই। enp3s0 নামটি systemd-এর “predictable” নামকরণ: en = Ethernet, p3s0 = PCI bus ৩, slot ০. Flag-এ UP আছে (প্রশাসনিকভাবে চালু), কিন্তু NO-CARRIER আর state DOWN — অর্থাৎ পোর্টে তার লাগানো নেই, বা অন্য প্রান্ত বন্ধ। ঠিকানা নেই, কারণ সংযোগই নেই।
  4. Wi-Fi — আসল সংযোগ। wl = wireless LAN. এখানে UP আর LOWER_UP দুটোই আছে: প্রথমটি বলে “আমরা চালু করেছি”, দ্বিতীয়টি বলে “physical স্তরে সংযোগ সত্যিই আছে” (Wi-Fi-এর ক্ষেত্রে router-এর সাথে যুক্ত)। BROADCAST,MULTICAST মানে এই interface সবাইকে বা একটি দলকে একসাথে বার্তা পাঠাতে পারে। mtu 1500 — Ethernet আর Wi-Fi-এর প্রচলিত মান।
  5. MAC ঠিকানা। link/ether 4c:d5:77:1b:9e:42 — ৬ বাইটের data link স্তরের ঠিকানা, যা দিয়ে একই LAN-এর যন্ত্ররা একে অন্যকে চেনে। brd ff:ff:ff:ff:ff:ff হলো broadcast ঠিকানা: এই MAC-এ পাঠানো frame LAN-এর সবাই পায়। MAC নিয়ে বিস্তারিত পর্ব ১২-তে।
  6. IPv4 ঠিকানা। 192.168.0.105/24 — /24 মানে প্রথম ২৪ বিট নেটওয়ার্কের অংশ (mask 255.255.255.0), তাই নেটওয়ার্ক 192.168.0.0 আর broadcast 192.168.0.255 (লাইনেই brd লেখা আছে)। 192.168.x.x একটি private ঠিকানা — ইন্টারনেটে সরাসরি দেখা যায় না, router NAT করে (পর্ব ১৯)। scope global মানে এটি দিয়ে বাইরে যাওয়া যায়; dynamic মানে ঠিকানাটি DHCP থেকে পাওয়া (পর্ব ১৮)।
  7. Lease-এর মেয়াদ। valid_lft 85980sec — DHCP যে ঠিকানাটি “ভাড়া” দিয়েছে, তার মেয়াদ আর ৮৫,৯৮০ সেকেন্ড, অর্থাৎ প্রায় ২৩ ঘণ্টা ৫৩ মিনিট (৮৫,৯৮০ ÷ ৩,৬০০ ≈ ২৩.৮৮)। মেয়াদ ফুরানোর আগেই যন্ত্রটি নবায়নের অনুরোধ পাঠাবে। Loopback-এ লেখা থাকে forever.
  8. IPv6 link-local ঠিকানা। fe80:: দিয়ে শুরু ঠিকানা প্রতিটি IPv6-চালু interface নিজে থেকেই বানায়; scope link মানে এটি শুধু একই LAN-এ কাজ করে, router পার হয় না। বাসার ISP IPv6 দিলে এর পাশে একটি scope global IPv6 ঠিকানাও দেখতেন। IPv6-এর পুরো গল্প পর্ব ২১-এ।

প্রতিদিনের কাজে পুরো আউটপুট লাগে না। -br (brief) দিলে প্রতি interface এক লাইনে আসে — সবচেয়ে বেশি ব্যবহৃত রূপ:

$ ip -br addr
lo               UNKNOWN        127.0.0.1/8 ::1/128
enp3s0           DOWN
wlp2s0           UP             192.168.0.105/24 fe80::9a3c:2f1e:7b44:c1d0/64

$ ip -br link                  # শুধু link স্তর: নাম, state, MAC
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
enp3s0           DOWN           8c:16:45:3a:7e:21 <NO-CARRIER,BROADCAST,MULTICAST,UP>
wlp2s0           UP             4c:d5:77:1b:9e:42 <BROADCAST,MULTICAST,UP,LOWER_UP>

$ ip -4 addr show dev wlp2s0   # শুধু একটি interface-এর IPv4

ip-এর ব্যাকরণ সহজ: ip [বিকল্প] বস্তু কাজ. বস্তু হতে পারে addr, link, route, neigh; কাজ না দিলে ধরে নেয় show. সংক্ষেপও চলে — ip a, ip r, ip n. দেখার কমান্ডে root লাগে না; কিন্তু বদলানোর কমান্ডে (যেমন ip addr add, ip link set … down) sudo লাগে, আর এগুলো ভুল করে চালালে দূরের সার্ভারের সাথে আপনার সংযোগই কেটে যেতে পারে — তাই সেগুলো এই পর্বে চালাবেন না।

Windows-এ ipconfig /all একসাথে ঠিকানা, MAC (“Physical Address”), DHCP lease আর DNS server দেখায়। PowerShell-এ একই তথ্য বস্তু (object) হিসেবে পাওয়া যায়, তাই ছেঁকে নেওয়া সহজ। নিচের কমান্ডগুলো Windows-এর — এই পাতায় চলবে না:

PS> ipconfig /all
PS> Get-NetIPAddress -AddressFamily IPv4 | Format-Table InterfaceAlias, IPAddress, PrefixLength
PS> Get-NetAdapter | Format-Table Name, Status, MacAddress, LinkSpeed
PS> netsh interface ipv4 show config

macOS-এ Wi-Fi সাধারণত en0. ifconfig-এ MAC লেখা থাকে ether শব্দের পরে, আর mask লেখা হয় hex-এ (netmask 0xffffff00 = /24). নিচের কমান্ডগুলো macOS-এর:

$ ifconfig en0
$ ipconfig getifaddr en0        # শুধু IPv4 ঠিকানা
$ networksetup -getinfo Wi-Fi

৩ · বাইরে যাওয়ার দরজা আর পাশের বাড়ি — ip route আর ip neigh

ঠিকানা জানা হলো। এবার প্রশ্ন: একটি packet কোথায় পাঠাবেন? Kernel এই সিদ্ধান্ত নেয় routing table দেখে — একটি তালিকা, যেখানে লেখা থাকে “এই গন্তব্যের জন্য এই দরজা”। দেখার কমান্ড ip route:

$ ip route
default via 192.168.0.1 dev wlp2s0 proto dhcp src 192.168.0.105 metric 600
192.168.0.0/24 dev wlp2s0 proto kernel scope link src 192.168.0.105 metric 600

$ ip route get 192.0.2.10        # এই ঠিকানায় যেতে kernel কোন পথ নেবে?
192.0.2.10 via 192.168.0.1 dev wlp2s0 src 192.168.0.105 uid 1000
    cache

দ্বিতীয় লাইনটি আগে পড়ুন: 192.168.0.0/24-এর যেকোনো ঠিকানা সরাসরি wlp2s0 দিয়ে পাওয়া যায় (scope link) — এরা একই LAN-এর প্রতিবেশী, মাঝে কোনো router লাগে না। প্রথম লাইনটি হলো default route: বাকি সব গন্তব্যের packet যাবে 192.168.0.1-এর কাছে। এই 192.168.0.1-ই আপনার default gateway — বাসার Wi-Fi router. proto dhcp বলছে এই নিয়মটি DHCP থেকে এসেছে; metric 600 হলো অগ্রাধিকার (একই গন্তব্যের একাধিক পথ থাকলে কম metric জেতে — Wi-Fi আর তার দুটোই থাকলে সাধারণত তারের পথের metric কম রাখা হয়)।

মহল্লার ডাকঘরের নিয়মটা এরকম: “চিঠি যদি এই মহল্লারই কোনো বাড়ির হয়, নিজেই গিয়ে দিয়ে আসুন। অন্য যেকোনো জায়গার হলে জেলা ডাকঘরে পাঠিয়ে দিন — বাকিটা তারা জানে।” প্রথম অংশটি 192.168.0.0/24 … scope link, দ্বিতীয়টি default via 192.168.0.1. কোন নিয়ম কখন খাটবে — সবচেয়ে নির্দিষ্ট (লম্বা prefix) নিয়মটি আগে — সেটি পর্ব ২২-এর longest prefix match.

পাশের বাড়ির দরজার নম্বর — ip neigh

Gateway-এর IP জানা গেল, কিন্তু Wi-Fi-তে frame পাঠাতে লাগে তার MAC ঠিকানা। IP থেকে MAC বের করার কাজ করে ARP (IPv6-এ এর বদলে Neighbor Discovery). একবার জানা MAC kernel কিছুক্ষণ মনে রাখে — এই স্মৃতির নাম ARP cache বা neighbour table:

$ ip neigh
192.168.0.1 dev wlp2s0 lladdr 60:a4:b7:5e:21:0c REACHABLE
192.168.0.110 dev wlp2s0 lladdr 3a:f1:0c:88:42:9d STALE
fe80::62a4:b7ff:fe5e:210c dev wlp2s0 lladdr 60:a4:b7:5e:21:0c router STALE

প্রথম লাইন: router-এর MAC জানা আছে, আর সম্প্রতি নিশ্চিত হওয়া গেছে যে সে সাড়া দেয় (REACHABLE). দ্বিতীয়টি বাসার অন্য একটি যন্ত্র — হয়তো কারও ফোন; STALE মানে তথ্যটি একটু পুরোনো, পরের বার ব্যবহারের আগে kernel আবার যাচাই করবে। খেয়াল করুন, ফোনের MAC-এর প্রথম বাইট 3a — এর দ্বিতীয় সর্বনিম্ন বিটটি ১, যার মানে এটি “locally administered”, অর্থাৎ কারখানার আসল MAC নয়। আধুনিক Android আর iPhone গোপনীয়তার জন্য প্রতিটি Wi-Fi নেটওয়ার্কে আলাদা এলোমেলো MAC ব্যবহার করে। তৃতীয় লাইনে একই router-কে IPv6-এর চোখে দেখা যাচ্ছে (router শব্দটি লক্ষ করুন)। ARP-এর request-reply কীভাবে চলে, তা ধাপে ধাপে পর্ব ১৮-তে দেখবেন।

PS> route print -4
PS> Get-NetRoute -DestinationPrefix 0.0.0.0/0      # শুধু default route
PS> arp -a
PS> Get-NetNeighbor -AddressFamily IPv4

mac$ netstat -rn -f inet
mac$ route -n get default
mac$ arp -a

৪ · কে কোন port-এ শুনছে — ss -tulpn

একটি যন্ত্রে একসাথে অনেক নেটওয়ার্ক প্রোগ্রাম চলে: ওয়েব সার্ভার, ডেটাবেস, SSH, স্থানীয় DNS. প্রত্যেকে একটি বা একাধিক socket খোলে, আর socket চেনা যায় একটি IP ঠিকানা আর একটি port নম্বর দিয়ে। Port হলো অফিসের কাউন্টার নম্বরের মতো — একই ভবন (IP), কিন্তু ৮০ নম্বর কাউন্টারে ওয়েব, ২২ নম্বরে SSH. Port আর socket-এর তত্ত্ব পর্ব ২৭-এ; এখানে শুধু দেখতে শিখি।

ss মানে socket statistics. সবচেয়ে প্রচলিত রূপ ss -tulpn, যার প্রতিটি অক্ষর একটি বিকল্প: -t TCP, -u UDP, -l শুধু যারা শুনছে (listening), -p কোন process, -n নাম না বানিয়ে সংখ্যা দেখানো (:80, :http নয়)। অন্যের process দেখতে sudo লাগে; না দিলে শুধু নিজের process-এর নাম আসে, বাকিদের ঘর ফাঁকা থাকে।

নিচে একটি ছোট Ubuntu সার্ভারের উদাহরণ — এতে nginx ওয়েব সার্ভার, একটি Node.js অ্যাপ, PostgreSQL আর SSH চলছে। ধাপে ধাপে দেখুন আউটপুটটি সার্ভার সম্পর্কে কী কী বলে দেয়:

1Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process2udp   UNCONN 0      0      127.0.0.53%lo:53        0.0.0.0:*     users:(("systemd-resolve",pid=612,fd=13))3tcp   LISTEN 0      4096   127.0.0.53%lo:53        0.0.0.0:*     users:(("systemd-resolve",pid=612,fd=14))4tcp   LISTEN 0      128          0.0.0.0:22         0.0.0.0:*     users:(("sshd",pid=901,fd=3))5tcp   LISTEN 0      511          0.0.0.0:80         0.0.0.0:*     users:(("nginx",pid=1204,fd=6),("nginx",pid=1203,fd=6))6tcp   LISTEN 0      511             [::]:80            [::]:*     users:(("nginx",pid=1204,fd=7),("nginx",pid=1203,fd=7))7tcp   LISTEN 0      200        127.0.0.1:5432       0.0.0.0:*     users:(("postgres",pid=1088,fd=7))8tcp   LISTEN 0      511        127.0.0.1:3000       0.0.0.0:*     users:(("node",pid=2210,fd=19))
সার্ভার সম্পর্কে যা জানলাম
সেবা
কারা পৌঁছাতে পারে
সতর্কতা
  1. কলামগুলো। Netid — protocol (tcp/udp). State — socket-এর অবস্থা। Recv-Q আর Send-Q — দুটি সারির দৈর্ঘ্য; listening socket-এর ক্ষেত্রে এদের মানে বিশেষ: Recv-Q = এই মুহূর্তে কতগুলো সম্পূর্ণ সংযোগ accept()-এর অপেক্ষায় আছে, Send-Q = সেই সারির সর্বোচ্চ দৈর্ঘ্য (backlog). Local Address:Port — কোন ঠিকানা আর port-এ শুনছে। Peer — অন্য প্রান্ত; শোনা socket-এর কোনো নির্দিষ্ট peer নেই, তাই *. Process — কোন প্রোগ্রাম, তার PID আর file descriptor নম্বর।
  2. স্থানীয় DNS. Ubuntu-তে systemd-resolved একটি ছোট DNS “stub” চালায় 127.0.0.53-এ, শুধু lo-তে (%lo). UDP-তে সংযোগের ধারণা নেই, তাই state LISTEN নয়, UNCONN (unconnected). একই port-এ TCP-ও খোলা — বড় DNS উত্তরের জন্য। ঠিকানাটি 127-ব্লকের, তাই বাইরের কেউ এটি দেখতে পায় না।
  3. SSH সবার জন্য খোলা। 0.0.0.0:22 মানে “যন্ত্রের সব IPv4 ঠিকানায় শুনছি” — Wi-Fi, Ethernet, যেটি দিয়েই আসুক। Send-Q 128 হলো sshd-এর চাওয়া backlog. সার্ভার পরিচালকের প্রশ্ন হওয়া উচিত: পাসওয়ার্ড লগইন বন্ধ করে key-ভিত্তিক লগইন রাখা হয়েছে কি? (নিরাপত্তার কাঠামো মডিউল ৮-এ।)
  4. ওয়েব সার্ভার — দুটি socket. nginx শুনছে 0.0.0.0:80 (সব IPv4) আর [::]:80 (সব IPv6). একই socket-এর পাশে দুটি PID কেন? nginx-এর একটি master process socket খুলে worker process তৈরি করে; worker উত্তরাধিকারসূত্রে একই socket পায়। Recv-Q 0 — কেউ অপেক্ষায় নেই, সার্ভার স্বাচ্ছন্দ্যে আছে। আর একটি জিনিস চোখে পড়ার মতো: ৪৪৩ port কোথাও নেই — অর্থাৎ HTTPS চালু হয়নি।
  5. ডেটাবেস শুধু ভেতরে। PostgreSQL শুনছে 127.0.0.1:5432-এ — শুধু loopback. বাইরের কোনো যন্ত্র সরাসরি এতে সংযোগ করতে পারবে না, firewall থাকুক বা না থাকুক। ডেটাবেসের জন্য এটিই নিরাপদ অভ্যাস; ভুল করে 0.0.0.0-তে খুলে রাখা ডেটাবেস ইন্টারনেটে ডেটা ফাঁসের একটি পরিচিত কারণ।
  6. অ্যাপ সার্ভার nginx-এর পেছনে। Node.js অ্যাপ শুনছে 127.0.0.1:3000-এ। তাহলে বাইরের ব্যবহারকারী এর কাছে পৌঁছায় কীভাবে? nginx ৮০ port-এ অনুরোধ নিয়ে ভেতরে ৩০০০-এ পাঠিয়ে দেয় — একে বলে reverse proxy (পর্ব ৩৮)। অর্থাৎ ব্যবহারকারী শুধু nginx দেখে।
  7. সারসংক্ষেপ। মাত্র ৮ লাইন থেকে জানা গেল: বাইরে থেকে শুধু ২২ আর ৮০ port খোলা, ডেটাবেস আর অ্যাপ লুকানো, HTTPS নেই। তবে মনে রাখুন — ss দেখায় কে শুনছে; firewall (পর্ব ৪৯) সেই দরজা বাইরে থেকে বন্ধ রাখতে পারে। “বাইরে থেকে আসলে কী খোলা” নিশ্চিত হতে firewall নিয়মও দেখতে হয়।

শুধু শোনা socket নয়, চলমান সংযোগও দেখা যায়। কয়েকটি কাজের রূপ:

$ ss -tn                          # সব চলমান TCP সংযোগ (ESTAB ইত্যাদি)
$ ss -tn state established '( dport = :443 )'   # শুধু HTTPS সংযোগগুলো
$ sudo ss -ltnp 'sport = :8080'   # 8080 port-এ কে শুনছে?
$ ss -s                           # মোট হিসাব: কতগুলো TCP, কতগুলো TIME_WAIT
$ ss -ti                          # প্রতিটি সংযোগের ভেতরের তথ্য: rtt, cwnd, retrans

শেষ কমান্ডটি পর্ব ৩০–৩২-এ খুব কাজে লাগবে — সেখানে TCP-র RTT অনুমান আর congestion window (cwnd) আসল সংযোগে দেখবেন। পুরোনো সমতুল্য netstat -tulpn-এর আউটপুট দেখতে প্রায় একই, কিন্তু অনেক socket থাকলে ধীর (কারণ অংশ ৭-এ)।

PS> netstat -ano | findstr LISTENING
PS> Get-NetTCPConnection -State Listen | Sort-Object LocalPort | Format-Table LocalAddress, LocalPort, OwningProcess
PS> Get-Process -Id 1204          # PID থেকে প্রোগ্রামের নাম

mac$ sudo lsof -nP -iTCP -sTCP:LISTEN
mac$ netstat -an -p tcp | grep LISTEN

৫ · পৌঁছানো যায় তো? — ping, traceroute, tracepath আর mtr

ping সবচেয়ে পুরোনো আর সবচেয়ে পরিচিত নেটওয়ার্ক টুল। এটি ICMP protocol-এর “Echo Request” বার্তা পাঠায়, আর গন্তব্য বেঁচে থাকলে ফেরত দেয় “Echo Reply”. ICMP-এর কোনো port নেই — তাই “ping কোন port ব্যবহার করে?” প্রশ্নটিই ভুল। একটি উদাহরণ:

$ ping -c 4 example.com
PING example.com (192.0.2.10) 56(84) bytes of data.
64 bytes from 192.0.2.10: icmp_seq=1 ttl=56 time=38.2 ms
64 bytes from 192.0.2.10: icmp_seq=2 ttl=56 time=37.9 ms
64 bytes from 192.0.2.10: icmp_seq=3 ttl=56 time=39.8 ms
64 bytes from 192.0.2.10: icmp_seq=4 ttl=56 time=38.5 ms

--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 37.900/38.600/39.800/0.725 ms

লাইন ধরে পড়ি। 56(84) bytes: ৫৬ বাইট ডেটা, তার সাথে ৮ বাইট ICMP header = ৬৪, তার সাথে ২০ বাইট IP header = ৮৪. প্রতিটি উত্তরে তিনটি জিনিস:

  • icmp_seq — ক্রমিক নম্বর। কোনো নম্বর বাদ গেলে সেই packet হারিয়েছে; ক্রম উল্টে এলে পথে reorder হয়েছে।
  • time — RTT (round-trip time): পাঠানো থেকে উত্তর আসা পর্যন্ত সময়। পর্ব ৫-এর propagation, transmission, queueing আর processing delay — সব যাওয়া-আসায় মিলে এই সংখ্যা।
  • ttl — উত্তর-packet-এর TTL (time to live)-এর বাকি মান। প্রতিটি router TTL ১ করে কমায়; ০ হলে packet ফেলে দেয়। এটি ঘুরপাক খাওয়া packet-কে চিরকাল বাঁচতে দেয় না।

শেষ লাইনের mdev হলো RTT কতটা ওঠানামা করছে তার মাপ (প্রায় standard deviation). হিসাবটা মিলিয়ে দেখুন: চারটি RTT-র যোগফল ১৫৪.৪, গড় ৩৮.৬; গড় থেকে বিচ্যুতি −০.৪, −০.৭, +১.২, −০.১; বর্গের গড় (০.১৬ + ০.৪৯ + ১.৪৪ + ০.০১) ÷ ৪ = ০.৫২৫; বর্গমূল ≈ ০.৭২৫. ওঠানামা (jitter) বেশি হলে ভিডিও কল আর অনলাইন গেম কষ্ট পায়। আর 0% packet loss — packet loss শূন্য। বাসার Wi-Fi-তে কয়েক শতাংশ loss মানে প্রায়ই দুর্বল সংকেত বা ব্যস্ত চ্যানেল।

TTL থেকে hop গোনা

বিভিন্ন OS প্রচলিতভাবে ভিন্ন TTL দিয়ে শুরু করে: Linux আর macOS সাধারণত ৬৪, Windows ১২৮, অনেক router ২৫৫. উত্তর এসেছে ttl=56 নিয়ে, তাই সবচেয়ে সম্ভাব্য ব্যাখ্যা: সার্ভার ৬৪ দিয়ে শুরু করেছিল, আর ফেরার পথে ৬৪ − ৫৬ = ৮টি router পার হয়েছে। এটি একটি অনুমান — শুরুর মান বদলানো যায়, আর যাওয়া-আসার পথ এক না-ও হতে পারে।

ping-এ উত্তর নেই মানেই সার্ভার বন্ধ নয়। অনেক firewall আর ক্লাউড সার্ভার ICMP Echo ইচ্ছা করে আটকে রাখে, অথচ ওয়েবসাইট দিব্যি চলে। উল্টোটাও সত্য: ping চললেই ওয়েব সার্ভার চলছে, এমন নয়। Application চলছে কি না জানতে সেই application-এর protocol-এই পরীক্ষা করুন — যেমন curl দিয়ে (অংশ ৬)।

traceroute — TTL-এর চতুর ব্যবহার

TTL ০ হলে router packet ফেলে দেয়, কিন্তু চুপচাপ নয় — প্রেরককে একটি ICMP “Time Exceeded” বার্তা পাঠায়, আর সেই বার্তার উৎস-ঠিকানা হলো router-এর নিজের ঠিকানা। traceroute এই নিয়মটিকেই কাজে লাগায়। নিচের ডায়াগ্রামে ধাপে ধাপে দেখুন:

  1. ল্যাপটপ192.168.0.105probe পাঠায়
  2. hop ১ — বাসার router192.168.0.1TTL 1→0
  3. hop ২ — ISP100.64.12.1TTL 2→1→0
  4. hop ৩ — upstream203.0.113.17TTL 3→…→0
  5. গন্তব্য192.0.2.10পৌঁছে গেছে
  1. TTL = ১. traceroute প্রথম probe পাঠায় TTL ১ দিয়ে। বাসার router TTL কমিয়ে ০ করে, packet ফেলে দেয়, আর ফেরত পাঠায় ICMP Time Exceeded. উৎস-ঠিকানা 192.168.0.1 — পাওয়া গেল প্রথম hop. প্রতিটি TTL-এ traceroute সাধারণত ৩টি probe পাঠায়, তাই তিনটি সময় দেখা যায়। _gateway নামটি systemd-resolved-এর দেওয়া, gateway-এর জন্য।
  2. TTL = ২. এবার বাসার router TTL ২ থেকে ১ করে পাঠিয়ে দেয়; পরের router (ISP-এর) ১ থেকে ০ করে, আর সে-ই Time Exceeded পাঠায়। দ্বিতীয় hop 100.64.12.1. খেয়াল করুন, ঠিকানাটি 100.64.0.0/10 ব্লকের — এটি carrier-grade NAT-এর জন্য সংরক্ষিত; অনেক ISP গ্রাহককে এর ভেতরে রাখে (পর্ব ১৯)।
  3. TTL = ৩. একইভাবে তৃতীয় router ধরা পড়ে — এখানে ISP-এর upstream সংযোগ। প্রতি ধাপে TTL এক বাড়িয়ে traceroute পথের প্রতিটি router-কে একবার করে “ধরা পড়তে” বাধ্য করে। সময়গুলোও ধাপে ধাপে বাড়ছে, কারণ probe আরও দূরে যাচ্ছে।
  4. TTL = ৪ — গন্তব্যে পৌঁছানো। এবার packet সার্ভারে পৌঁছায়, TTL ফুরানোর আগেই। Linux-এর traceroute ডিফল্টভাবে UDP probe পাঠায় অব্যবহৃত উঁচু port-এ (৩৩৪৩৪ থেকে শুরু), তাই সার্ভার উত্তর দেয় ICMP “Port Unreachable” — traceroute বোঝে গন্তব্যে পৌঁছানো গেছে, থামে। Windows-এর tracert UDP-র বদলে ICMP Echo পাঠায়, শেষে পায় Echo Reply.
  5. তারকা চিহ্ন * * *. ধরুন hop ৩-এর router উত্তর দেওয়া বন্ধ রেখেছে — তখন আউটপুট এমন দেখাত। বাস্তবে প্রায়ই কোনো hop-এ তিনটি তারকা দেখবেন: নির্দিষ্ট সময়ে কোনো উত্তর আসেনি। কারণ হতে পারে — router ICMP পাঠায় না, বা পাঠানোর হার সীমিত রাখে, বা পথে firewall আটকায়। পরের hop-গুলো ঠিকমতো এলে মানে packet সেই router পার হচ্ছে ঠিকই; শুধু সে নিজের পরিচয় দিচ্ছে না। তারকা মানেই সমস্যা নয়। TTL আর ICMP-র বার্তার পুরো বিবরণ পর্ব ২০-এ।

বাস্তবের একটি দীর্ঘ পথ দেখতে এরকম হতে পারে (উদাহরণ; ঠিকানাগুলো documentation range-এর, তাই আসল কোনো প্রতিষ্ঠানের নয়)। খেয়াল করুন — ping-এ ttl=56 বলেছিল ৮টি router, আর এখানে ৮টি hop-এর পরে ৯ নম্বরে গন্তব্য:

$ traceroute example.com
traceroute to example.com (192.0.2.10), 30 hops max, 60 byte packets
 1  _gateway (192.168.0.1)  1.912 ms  1.874 ms  2.035 ms
 2  100.64.12.1 (100.64.12.1)  4.210 ms  4.388 ms  4.157 ms
 3  10.20.0.5 (10.20.0.5)  5.902 ms  6.114 ms  5.877 ms
 4  203.0.113.17 (203.0.113.17)  7.341 ms  7.120 ms  7.509 ms
 5  * * *
 6  198.51.100.66 (198.51.100.66)  34.880 ms  35.102 ms  34.917 ms
 7  198.51.100.129 (198.51.100.129)  36.554 ms  36.019 ms  36.871 ms
 8  203.0.113.201 (203.0.113.201)  37.640 ms  37.488 ms  37.912 ms
 9  192.0.2.10 (192.0.2.10)  38.105 ms  37.996 ms  38.240 ms

৪ থেকে ৬ নম্বর hop-এ সময় ~৭ ms থেকে ~৩৫ ms-এ লাফ দিয়েছে। এ ধরনের বড় লাফ সাধারণত বোঝায় পথটি এখানে একটি দীর্ঘ সংযোগ পার হয়েছে — বাংলাদেশ থেকে বিদেশের সার্ভারে যেতে traffic সাধারণত সাবমেরিন কেবল বা প্রতিবেশী দেশের মধ্য দিয়ে যাওয়া স্থল-সংযোগ ব্যবহার করে। তবে এটি অনুমান: মাঝের router-এর নিজের উত্তর দেওয়ার গতিও সংখ্যাটিকে প্রভাবিত করে।

tracepath

iputils প্যাকেজের অংশ, root ছাড়াই চলে। পথের সাথে সাথে path MTU — পথের সবচেয়ে ছোট MTU — বের করার চেষ্টা করে।

tracepath -n example.com

mtr

traceroute আর ping-এর মিশ্রণ: পথের প্রতিটি hop-এ বারবার probe পাঠিয়ে loss % আর গড় RTT-এর জীবন্ত টেবিল দেখায়। বিরতিহীন সমস্যা খুঁজতে চমৎকার।

mtr -rwc 50 example.com

Windows

tracert হলো traceroute-এর সমতুল্য; pathping কিছুটা mtr-এর মতো, প্রতিটি hop-এর loss হিসাব করে। Test-NetConnection -TraceRoute-ও আছে।

tracert example.com

৬ · নাম, ওয়েব আর একটি কাঁচা TCP সংযোগ — dig, curl -v আর nc

dig — নাম থেকে ঠিকানা

মানুষ মনে রাখে নাম (example.com), যন্ত্রের লাগে ঠিকানা। নাম থেকে ঠিকানা বের করার ব্যবস্থাই DNS. এর সবচেয়ে বিস্তারিত টুল dig:

$ dig example.com A

; <<>> DiG 9.18.28 <<>> example.com A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41873
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;example.com.                   IN      A

;; ANSWER SECTION:
example.com.            3125    IN      A       192.0.2.10

;; Query time: 24 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; WHEN: Mon Oct 26 21:14:03 +06 2026
;; MSG SIZE  rcvd: 56

গুরুত্বপূর্ণ অংশ চারটি। status: NOERROR — প্রশ্নের উত্তর পাওয়া গেছে (নাম না থাকলে আসত NXDOMAIN). ANSWER SECTION-এ আসল উত্তর: example.com-এর A (IPv4) রেকর্ড 192.0.2.10, আর 3125 হলো সেকেন্ডে TTL — এতক্ষণ উত্তরটি cache-এ রাখা যাবে (এই TTL DNS-এর, IP header-এর TTL নয় — নাম এক, জিনিস আলাদা)। SERVER: 127.0.0.53 — প্রশ্নটি গেছে অংশ ৪-এ দেখা স্থানীয় DNS stub-এর কাছে। Query time: 24 msec — উত্তর পেতে কত সময় লাগল; আবার চালালে cache থেকে প্রায় ০ ms আসতে পারে।

$ dig +short example.com
192.0.2.10
$ host example.com
example.com has address 192.0.2.10
$ nslookup example.com
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
Name:   example.com
Address: 192.0.2.10

nslookup Windows-এও আছে; PowerShell-এ আধুনিক বিকল্প Resolve-DnsName example.com. DNS-এর ভেতরের যাত্রা — root, TLD, authoritative server, recursive resolver আর caching — পর্ব ৩৫-এর বিষয়।

curl -v — একটি HTTP কথোপকথন

curl URL দিয়ে কিছু আনার টুল। -v (verbose) দিলে এটি পুরো কথোপকথন দেখায়: * চিহ্নের লাইন curl-এর নিজের মন্তব্য, > চিহ্নের লাইন যা পাঠানো হলো, < চিহ্নের লাইন যা ফিরে এলো।

$ curl -v http://example.com/
*   Trying 192.0.2.10:80...
* Connected to example.com (192.0.2.10) port 80
> GET / HTTP/1.1
> Host: example.com
> User-Agent: curl/8.5.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 1256
< Cache-Control: max-age=3600
<
<!doctype html>
… (পাতার HTML) …
* Connection #0 to host example.com left intact

এক নজরে পুরো স্তরের গল্প: আগে DNS (192.0.2.10 পাওয়া), তারপর TCP সংযোগ port ৮০-তে (Connected), তারপর HTTP অনুরোধ — একটি GET লাইন আর কয়েকটি header, শেষে একটি ফাঁকা লাইন। সার্ভার জবাব দিল 200 OK, কিছু header আর পাতার বিষয়বস্তু। HTTPS URL দিলে Connected-এর পরে TLS handshake-এর লাইনও দেখবেন (পর্ব ৪৮)। HTTP-র প্রতিটি অংশ পর্ব ৩৬-এ বিস্তারিত।

স্তর ধরে সমস্যা আলাদা করা

ব্রাউজারে “সাইট খুলছে না” — কোন স্তরে আটকেছে? ip -br addr (ঠিকানা আছে?) → ip route (gateway আছে?) → ping 192.168.0.1 (LAN চলছে?) → নাম ছাড়া একটি বাইরের IP-তে ping (ইন্টারনেট চলছে?) → dig (DNS চলছে?) → curl -v (সার্ভার আর application চলছে?)। নিচ থেকে ওপরে — পর্ব ৩-এর স্তরগুলোর ক্রমে। পুরো পদ্ধতিগত তদন্ত পর্ব ৫৫-এ।

nc — নিজের যন্ত্রে একটি কাঁচা TCP সংযোগ

netcat (nc) হলো নেটওয়ার্কের “সুইস ছুরি”: এটি যেকোনো TCP বা UDP সংযোগ খুলে আপনার কীবোর্ড থেকে বাইট পাঠায় আর যা আসে তা দেখায়। নিজের ল্যাপটপে দুটি terminal খুলে চেষ্টা করুন — সবকিছু 127.0.0.1-এ, তাই বাইরের কেউ জড়িত নয়:

# terminal ১: 9000 port-এ শোনা শুরু (OpenBSD-ধাঁচের nc; Ubuntu-র ডিফল্ট)
$ nc -l 127.0.0.1 9000

# terminal ২: সংযোগ, তারপর একটি লাইন লিখে Enter
$ nc -v 127.0.0.1 9000
Connection to 127.0.0.1 9000 port [tcp/*] succeeded!
hello
# → terminal ১-এ "hello" ভেসে উঠবে; Ctrl+C দিয়ে বন্ধ

# শুধু port খোলা কি না যাচাই (নিজের যন্ত্রে):
$ nc -zv 127.0.0.1 22
Connection to 127.0.0.1 22 port [tcp/ssh] succeeded!

সংযোগ চলার সময় তৃতীয় একটি terminal-এ ss -tn '( sport = :9000 or dport = :9000 )' দিলে দুটি ESTAB লাইন দেখবেন — সংযোগের দুই প্রান্ত। nc-এর কয়েকটি “জাত” আছে (OpenBSD nc, পুরোনো traditional nc, Nmap প্রকল্পের ncat), আর এদের বিকল্প একটু আলাদা: traditional nc-তে শোনার কমান্ড nc -l -p 9000. তাই man nc দেখে নিন। Windows-এ এর কাজ অনেকটা করে Test-NetConnection 127.0.0.1 -Port 9000.

৭ · Kernel-এর কাঁচা হিসাব — /proc/net আর /sys/class/net

এতক্ষণের সব টুল তথ্য পায় kernel থেকে। Linux সেই তথ্যের একটি অংশ ফাইলের আকারে খুলে রাখে — /proc আর /sys ফাইল সিস্টেমে। এগুলো ডিস্কের আসল ফাইল নয়: পড়ার মুহূর্তে kernel লেখাটি বানিয়ে দেয়। কয়েকটি কাজের ফাইল:

ফাইলযা আছেকোন টুলের সমতুল্য
/sys/class/net/প্রতিটি interface-এর একটি ফোল্ডার: address (MAC), operstate, mtu, statistics/rx_bytesip link
/proc/net/devপ্রতিটি interface-এ মোট কত বাইট ও packet এলো-গেল, কত error আর dropip -s link
/proc/net/routeIPv4 routing table, hex-এip route
/proc/net/arpARP cacheip neigh
/proc/net/tcp, tcp6প্রতিটি TCP socket: ঠিকানা, port, state, uid, inodess -tan
/proc/net/udp, udp6প্রতিটি UDP socketss -uan
/proc/net/snmpprotocol-ভিত্তিক মোট হিসাব — যেমন TCP-র মোট retransmitnstat, netstat -s

একটি গুরুত্বপূর্ণ সূক্ষ্মতা: /proc/net আসলে /proc/self/net-এর একটি link — অর্থাৎ আপনি যে network namespace-এ আছেন, শুধু সেটিরই তথ্য। Docker বা অন্য container-এর ভেতরে /proc/net/tcp পড়লে host-এর socket দেখবেন না (অপারেটিং সিস্টেম কোর্সের container পর্বে namespace বিস্তারিত)।

এই পাতার কোড চলে একটি rootless container-এ — বাইরের সার্ভারের সাথে কাজ করার জন্য এটি বানানো নয়, আর ip বা ss থাকবে কি না নিশ্চিত নয়। তাই নিচের স্ক্রিপ্ট প্রতিটি টুল আগে command -v দিয়ে খুঁজে নেয়, আর না পেলে সরাসরি kernel-এর ফাইল পড়ে। “চালান” চাপুন — এটি সেই container-এর নেটওয়ার্কের এক নজরের ছবি:

hex2ip() { local h=$1; printf '%d.%d.%d.%d' "0x${h:6:2}" "0x${h:4:2}" "0x${h:2:2}" "0x${h:0:2}"; }
echo "== 1. interfaces (/sys/class/net) =="
for d in /sys/class/net/*; do
  echo "  ${d##*/}  state=$(cat "$d/operstate")  mac=$(cat "$d/address")  mtu=$(cat "$d/mtu")"
done
echo "== 2. IPv4 addresses =="
if command -v ip >/dev/null; then ip -br -4 addr
else echo "  (ip নেই; /proc/net/fib_trie থেকে)"
  awk '/32 host/ {print "  " p} {p = $2}' /proc/net/fib_trie 2>/dev/null | sort -u
fi
echo "== 3. default route (/proc/net/route) =="
found=no
while read -r ifc dst gw flags _; do
  if [ "$dst" = 00000000 ]; then echo "  default via $(hex2ip "$gw") dev $ifc flags=$flags"; found=yes; fi
done < <(tail -n +2 /proc/net/route)
if [ "$found" = no ]; then echo "  (default route নেই)"; fi
echo "== 4. counters (/proc/net/dev) =="
tail -n +3 /proc/net/dev | while read -r line; do
  set -- ${line/:/ }
  echo "  $1  rx_bytes=$2 rx_packets=$3  tx_bytes=${10} tx_packets=${11}"
done
echo "== 5. TCP LISTEN sockets (/proc/net/tcp, st=0A) =="
n=0
while read -r sl loc rem st _; do
  if [ "$st" = 0A ]; then echo "  $(hex2ip "${loc%:*}"):$((16#${loc#*:}))"; n=$((n + 1)); fi
done < <(tail -n +2 /proc/net/tcp)
echo "  total LISTEN: $n"
echo "== 6. which tools exist here? =="
for t in ip ss ping traceroute dig curl nc tcpdump; do
  command -v "$t" >/dev/null && echo "  $t: আছে" || echo "  $t: নেই"
done

আসল রানের আউটপুট:

== 1. interfaces (/sys/class/net) ==
  lo  state=unknown  mac=00:00:00:00:00:00  mtu=65536
  tap0  state=unknown  mac=8a:6e:8f:9e:5c:c6  mtu=65520
== 2. IPv4 addresses ==
lo               UNKNOWN        127.0.0.1/8
tap0             UNKNOWN        10.0.2.100/24
== 3. default route (/proc/net/route) ==
  default via 10.0.2.2 dev tap0 flags=0003
== 4. counters (/proc/net/dev) ==
  lo  rx_bytes=0 rx_packets=0  tx_bytes=0 tx_packets=0
  tap0  rx_bytes=110 rx_packets=1  tx_bytes=250 tx_packets=3
== 5. TCP LISTEN sockets (/proc/net/tcp, st=0A) ==
  total LISTEN: 0
== 6. which tools exist here? ==
  ip: আছে
  ss: আছে
  ping: নেই
  traceroute: নেই
  dig: নেই
  curl: নেই
  nc: নেই
  tcpdump: নেই

অংশ ধরে পড়ুন। ১ — interface: মাত্র দুটি। lo আমাদের চেনা loopback. দ্বিতীয়টি tap0 — কোনো আসল কার্ড নয়, একটি কাল্পনিক (virtual) interface, যার মাধ্যমে rootless container বাইরের সাথে যুক্ত হয়; host-এর আসল Wi-Fi বা Ethernet এখান থেকে অদৃশ্য। এর MAC প্রতিটি রানে নতুন করে বানানো হয় (আরেকটি রানে এসেছিল ea:e9:…), আর দুবারই প্রথম বাইটের (8a, ea) দ্বিতীয় সর্বনিম্ন বিট ১ — অর্থাৎ locally administered, সফটওয়্যারের বানানো ঠিকানা। দুটির state-ই unknown: loopback আর এ ধরনের virtual interface-এর “তার লাগানো আছে কি না” বলার কিছু নেই। MTU ৬৫৫২০ — সাধারণ ১৫০০-এর চেয়ে অনেক বড়, কারণ এই packet আসলে কোনো তারে যায় না, host-এর একটি প্রোগ্রাম তা হাতে নিয়ে বাইরে পাঠায়।

২ — ঠিকানা: এই container-এ ip আছে, তাই fallback লাগেনি; tap0-এর ঠিকানা 10.0.2.100/24 — একটি private ঠিকানা। ৩ — default route: /proc/net/route-এর hex 0202000A উল্টে পড়ে পাওয়া গেল 10.0.2.2, আর flags=0003 = U + G. Rootless নেটওয়ার্কিংয়ের প্রচলিত ব্যবস্থায় (যেমন slirp4netns) container পায় 10.0.2.100, আর 10.0.2.2-এ থাকে একটি কাল্পনিক gateway — বাসার router-এর জায়গায় host-এর একটি প্রোগ্রাম। ৪ — counter: loopback-এ কিছুই যায়নি; tap0-এ কয়েকটি packet — container চালুর সময়ের স্বয়ংক্রিয় কিছু বার্তা। এই সংখ্যাগুলো রানভেদে বদলাতে পারে।

৫ — শোনা socket: শূন্য। এই container-এ কোনো সার্ভার চলছে না — পরের অংশের C প্রোগ্রাম নিজেই একটি বানিয়ে দেখাবে। ৬ — টুল: ip আর ss আছে, কিন্তু ping, traceroute, dig, curl, nc, tcpdump নেই। (নাম থেকে ঠিকানা বের করা অবশ্য এখানেও কাজ করে — glibc-এর getent hosts example.com কোনো আলাদা টুল ছাড়াই সেটি করে; তবে এই পাতার কোড ইচ্ছা করেই বাইরের কোনো সার্ভারে সংযোগ করে না।) এজন্যই অংশ ২–৬-এর ওই টুলগুলোর আউটপুট এই পাতায় চালানো নয়, একটি সাধারণ ল্যাপটপের উদাহরণ হিসেবে দেখানো হয়েছে। নিজের Linux-এ স্ক্রিপ্টটি চালালে দেখবেন Wi-Fi interface, 192.168.x.x ঠিকানা, router-এর gateway আর কয়েকটি LISTEN socket (যেমন 127.0.0.53:53).

/proc/net/tcp-এর একটি লাইন নিজের হাতে পড়া

স্ক্রিপ্টের অংশ ৩ আর ৫-এ আমরা hex থেকে ঠিকানা বানালাম। নিয়মটি একবার হাতে করে দেখা দরকার, কারণ কোনো টুল না থাকলে (ছোট container, ভাঙা সার্ভার, পরীক্ষার খাতা) এটুকুই আপনার ভরসা। নিচে একটি ল্যাপটপের /proc/net/tcp থেকে নেওয়া একটি লাইন — প্রতিটি টুকরো আলাদা করে পড়ুন:

3: 6900A8C0:D5C2 227100CB:01BB 01 00000000:00000000 02:000A3F2C 00000000 1000 0 98213
এ পর্যন্ত যা বের হলো
local
remote
state
owner
  1. ক্রমিক নম্বর। প্রথম ঘর sl — শুধু তালিকার সারি নম্বর, এর কোনো নেটওয়ার্ক-অর্থ নেই। ফাইলের প্রথম লাইনে কলামের নামগুলো থাকে: local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode.
  2. Local ঠিকানা — বাইট উল্টে পড়া। 6900A8C0 হলো ৪ বাইট: 69 00 A8 C0. Kernel ঠিকানাটি network byte order-এ (বড় প্রান্ত আগে) রাখে, কিন্তু ফাইলে লেখার সময় সেটিকে একটি পূর্ণসংখ্যা হিসেবে hex-এ ছাপে — আর x86 যন্ত্র little-endian, তাই বাইটগুলো উল্টো দেখায়। উল্টে নিলে C0 A8 00 69 = ১৯২.১৬৮.০.১০৫ — অংশ ২-এর সেই Wi-Fi ঠিকানা।
  3. Local port — সোজা পড়া। Port কিন্তু উল্টাতে হয় না: kernel port-কে আগে host order-এ বদলে তারপর ছাপে। D5C2 = ১৩×৪০৯৬ + ৫×২৫৬ + ১২×১৬ + ২ = ৫৪,৭২২. এত বড় সংখ্যা দেখে বোঝা যায় এটি একটি ephemeral port — সংযোগ শুরু করার সময় kernel যে অস্থায়ী port বেছে দেয় (Linux-এ ডিফল্ট পরিসর ৩২৭৬৮–৬০৯৯৯)। অর্থাৎ এই যন্ত্রটি client.
  4. Remote ঠিকানা। একই নিয়ম: 227100CB → 22 71 00 CB → উল্টে CB 00 71 22 = ২০৩.০.১১৩.৩৪.
  5. Remote port. 01BB = ২৫৬ + ১৭৬ + ১১ = ৪৪৩ — HTTPS-এর পরিচিত port. অর্থাৎ ল্যাপটপের কোনো প্রোগ্রাম (সম্ভবত ব্রাউজার) একটি ওয়েব সার্ভারের সাথে নিরাপদ সংযোগে আছে।
  6. State. st ঘরের 01 মানে ESTABLISHED — সংযোগ পুরোপুরি চালু, ডেটা যাওয়া-আসা করতে পারে। পুরো তালিকা: ০১ ESTABLISHED, ০২ SYN_SENT, ০৩ SYN_RECV, ০৪ FIN_WAIT1, ০৫ FIN_WAIT2, ০৬ TIME_WAIT, ০৭ CLOSE, ০৮ CLOSE_WAIT, ০৯ LAST_ACK, ০A LISTEN, ০B CLOSING (আর ০C NEW_SYN_RECV, kernel-এর ভেতরের একটি অবস্থা)। এই state-গুলোর মানে পর্ব ২৯-এ ধাপে ধাপে।
  7. সারি আর timer. tx_queue:rx_queue = ০:০ — পাঠানোর বা পড়ার জন্য কোনো বাইট জমে নেই। tr = ০২ মানে keepalive timer চালু; tm->when = 0x000A3F2C = ৬,৭১,৫৩২ — এই ফাইলে সময় ছাপা হয় সেকেন্ডের ১০০ ভাগের ১ ভাগ এককে, তাই প্রায় ৬,৭১৫ সেকেন্ড পরে keepalive probe যাবে (Linux-এর ডিফল্ট keepalive সময় ৭,২০০ সেকেন্ড)। retrnsmt = ০ — কোনো retransmission বাকি নেই।
  8. মালিক। uid 1000 — Ubuntu-তে প্রথম সাধারণ ব্যবহারকারীর id. inode 98213 হলো socket-এর পরিচয় নম্বর: কোনো process-এর /proc/<PID>/fd/-তে socket:[98213] লিংক খুঁজে পেলে বোঝা যায় socket-টি কার। ss -p ঠিক এই কাজটিই করে — সব process-এর fd ঘুরে inode মেলায়।

একই নিয়ম /proc/net/route-এ খাটে। সেখানে Destination 00000000 মানে 0.0.0.0 — default route; Gateway 0100A8C0 উল্টে C0 A8 00 01 = ১৯২.১৬৮.০.১; Mask 00FFFFFF উল্টে FF FF FF 00 = ২৫৫.২৫৫.২৫৫.০; আর Flags 0003 = U (চালু) + G (gateway দিয়ে)। এবার একটি ছোট JavaScript decoder দিয়ে পুরো একটি নমুনা ফাইল পড়ি (নমুনাটি একটি ল্যাপটপের মতো করে বানানো; বাইরের ঠিকানাগুলো documentation range-এর):

// Decode /proc/net/tcp lines by hand: hex IP:port and the state code
const STATES = { "01": "ESTABLISHED", "02": "SYN_SENT", "03": "SYN_RECV", "04": "FIN_WAIT1",
  "05": "FIN_WAIT2", "06": "TIME_WAIT", "07": "CLOSE", "08": "CLOSE_WAIT", "09": "LAST_ACK",
  "0A": "LISTEN", "0B": "CLOSING", "0C": "NEW_SYN_RECV" };
const sample = `  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 3500007F:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000   991        0 18342 1
   1: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 21057 1
   2: 0100007F:0CEA 00000000:0000 0A 00000000:00000000 00:00000000 00000000   113        0 23911 1
   3: 6900A8C0:D5C2 227100CB:01BB 01 00000000:00000000 02:000A3F2C 00000000  1000        0 98213 2
   4: 6900A8C0:B0F4 0F6433C6:01BB 06 00000000:00000000 03:00001523 00000000     0        0 0 3
   5: 6900A8C0:9C40 4A0200C0:0050 02 00000000:00000000 01:00000064 00000002  1000        0 99120 1`;

function ip(hex) {          // "6900A8C0" -> bytes 69 00 A8 C0 -> reverse -> 192.168.0.105
  return hex.match(/../g).map(x => parseInt(x, 16)).reverse().join(".");
}
function endpoint(s) {      // "6900A8C0:D5C2" -> "192.168.0.105:54722"
  const [h, p] = s.split(":");
  return ip(h) + ":" + parseInt(p, 16);
}

console.log("local".padEnd(21) + "remote".padEnd(21) + "st  state        uid");
for (const line of sample.split("\n").slice(1)) {
  const f = line.trim().split(/\s+/);   // f[1]=local f[2]=remote f[3]=st f[7]=uid
  console.log(endpoint(f[1]).padEnd(21) + endpoint(f[2]).padEnd(21) +
              f[3] + "  " + STATES[f[3]].padEnd(13) + f[7]);
}
console.log("check: 0x01BB = " + 0x01BB + ", 0x0CEA = " + 0x0CEA + ", 0x0016 = " + 0x16);

আসল রানের আউটপুট:

local                remote               st  state        uid
127.0.0.53:53        0.0.0.0:0            0A  LISTEN       991
0.0.0.0:22           0.0.0.0:0            0A  LISTEN       0
127.0.0.1:3306       0.0.0.0:0            0A  LISTEN       113
192.168.0.105:54722  203.0.113.34:443     01  ESTABLISHED  1000
192.168.0.105:45300  198.51.100.15:443    06  TIME_WAIT    0
192.168.0.105:40000  192.0.2.74:80        02  SYN_SENT     1000
check: 0x01BB = 443, 0x0CEA = 3306, 0x0016 = 22

ছয়টি লাইন, তিন রকম গল্প। প্রথম তিনটি LISTEN (state 0A), remote 0.0.0.0:0 — শোনা socket-এর কোনো নির্দিষ্ট অন্য প্রান্ত নেই। 127.0.0.53:53 হলো অংশ ৪-এর স্থানীয় DNS stub (uid ৯৯১ — systemd-resolve নামের একটি সিস্টেম ব্যবহারকারী; নম্বরটি যন্ত্রভেদে আলাদা হয়)। 0.0.0.0:22 — root (uid ০)-এর চালানো SSH সার্ভার, সব ঠিকানায় খোলা। 127.0.0.1:3306 — MySQL-এর প্রচলিত port, শুধু loopback-এ, তাই নিরাপদ।

চতুর্থ লাইনটি সেই ESTABLISHED HTTPS সংযোগ, যেটি আমরা স্টেপারে হাতে decode করেছিলাম — কোড আর হাত একই উত্তর দিল। পঞ্চম লাইন TIME_WAIT: সংযোগটি শেষ হয়ে গেছে, কিন্তু kernel কিছুক্ষণ এর স্মৃতি রেখে দিচ্ছে, যাতে দেরিতে আসা পুরোনো packet নতুন কোনো সংযোগে মিশে না যায়। খেয়াল করুন, এর uid ০ আর মূল নমুনায় inode ০ — TIME_WAIT অবস্থায় socket আর কোনো প্রোগ্রামের নয়, শুধু kernel-এর। ষষ্ঠ লাইন SYN_SENT: 192.0.2.74:80-এ সংযোগের চেষ্টা চলছে, এখনো উত্তর আসেনি; মূল নমুনায় retrnsmt ঘরে ২ — SYN দুবার আবার পাঠানো হয়েছে, অর্থাৎ অন্য প্রান্ত সাড়া দিচ্ছে না। এক ফাইলেই সক্রিয়, শেষ হওয়া আর ঝুলে থাকা সংযোগ — ঠিক এভাবেই ss আপনাকে তালিকা দেখায়।

আরও গভীরে: আধুনিক ip আর ss আসলে /proc পড়ে না। তারা kernel-এর সাথে কথা বলে netlink socket দিয়ে — ip ব্যবহার করে rtnetlink, আর ss ব্যবহার করে sock_diag (inet_diag). /proc/net/tcp প্রতিবার পড়ার সময় kernel-কে সব socket ঘুরে লেখা বানাতে হয়; লক্ষাধিক সংযোগের সার্ভারে এটি ধীর, আর পড়ার মাঝে socket-এর তালিকা বদলে যেতে পারে। inet_diag-এ ছাঁকনি kernel-এর ভেতরেই চলে, ফল আসে বাইনারি আকারে — এজন্যই বড় সার্ভারে ss পুরোনো netstat-এর চেয়ে অনেক দ্রুত। পুরোনো ifconfig চলে ioctl দিয়ে, যা একটি interface-এ একাধিক ঠিকানা স্বাভাবিকভাবে দেখাতে পারে না (তাই পুরোনো দিনের eth0:1 ধাঁচের “alias”). আরও আধুনিক পর্যবেক্ষণের জন্য আজ eBPF-ভিত্তিক টুলও ব্যবহৃত হয়, যা kernel-এর ভেতরের ঘটনা সরাসরি ধরে।

৮ · নিজের socket নিজে খুঁজে দেখা — একটি C পরীক্ষা

এবার তত্ত্বটি নিজের চোখে যাচাই করি। নিচের C প্রোগ্রাম 127.0.0.1-এ একটি TCP listener খোলে। Port নম্বর হিসেবে দেয় 0 — এর মানে “kernel নিজেই একটি খালি port বেছে দিক”। কোন port পাওয়া গেল, তা জানা যায় getsockname() দিয়ে। তারপর একটি child process সেই port-এ সংযোগ করে, আর parent সংযোগ চলাকালীন /proc/net/tcp পড়ে তিনটি socket খুঁজে বের করে: listener, সার্ভারের প্রান্ত আর client-এর প্রান্ত। Port নম্বর প্রতিবার আলাদা হবে, তাই প্রোগ্রাম আসল নম্বর না ছেপে শুধু সম্পর্ক ছাপে — P = সার্ভারের port, C = client-এর port. Socket কোডের প্রতিটি লাইন পর্ব ৪১-এ বিস্তারিত শিখবেন; এখানে শুধু দেখুন kernel-এর খাতায় কী লেখা হয়।

#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/wait.h>
static const char *NAME[] = {"(gone)", "ESTABLISHED", "SYN_SENT", "SYN_RECV", "FIN_WAIT1",
    "FIN_WAIT2", "TIME_WAIT", "CLOSE", "CLOSE_WAIT", "LAST_ACK", "LISTEN", "CLOSING"};
static void show(const char *when, unsigned P, unsigned C) {   /* P = server port, C = client port */
    unsigned la, lp, ra, rp, st, lis = 0, srv = 0, cli = 0, hex = 0; char line[256];
    FILE *f = fopen("/proc/net/tcp", "r");
    while (fgets(line, sizeof line, f))
        if (sscanf(line, " %*u: %X:%X %X:%X %X", &la, &lp, &ra, &rp, &st) == 5 && st < 12) {
            if (lp == P && rp == 0) { lis = st; hex = la; }
            if (lp == P && rp == C) srv = st; else if (lp == C && rp == P) cli = st;
        }
    fclose(f);
    printf("%s\n  listener    local=P           st=%02X %s (local addr hex %08X)\n"
           "  server end  local=P remote=C  st=%02X %s\n  client end  local=C remote=P  st=%02X %s\n",
           when, lis, NAME[lis], hex, srv, NAME[srv], cli, NAME[cli]);
}
int main(void) {
    struct sockaddr_in a = {0}, peer; socklen_t len = sizeof a; char b;
    a.sin_family = AF_INET; a.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    int ls = socket(AF_INET, SOCK_STREAM, 0);   /* port 0 in a: the kernel picks one */
    bind(ls, (struct sockaddr *)&a, sizeof a); listen(ls, 1); getsockname(ls, (struct sockaddr *)&a, &len);
    fflush(stdout); if (fork() == 0) {          /* child = the client; it waits for EOF */
        int c = socket(AF_INET, SOCK_STREAM, 0); connect(c, (struct sockaddr *)&a, sizeof a);
        while (read(c, &b, 1) > 0) {} close(c); _exit(0); }
    len = sizeof peer; int conn = accept(ls, (struct sockaddr *)&peer, &len);
    unsigned P = ntohs(a.sin_port), C = ntohs(peer.sin_port);
    printf("P = port from getsockname, C = client's port; P != C: %s\n", P != C ? "yes" : "no");
    show("while connected:", P, C);
    close(conn); wait(NULL); usleep(200000);                     /* the server closes first */
    show("after the server closed first:", P, C); return 0;
}

আসল রানের আউটপুট:

P = port from getsockname, C = client's port; P != C: yes
while connected:
  listener    local=P           st=0A LISTEN (local addr hex 0100007F)
  server end  local=P remote=C  st=01 ESTABLISHED
  client end  local=C remote=P  st=01 ESTABLISHED
after the server closed first:
  listener    local=P           st=0A LISTEN (local addr hex 0100007F)
  server end  local=P remote=C  st=06 TIME_WAIT
  client end  local=C remote=P  st=00 (gone)

প্রথম লাইন: kernel একটি port দিয়েছে (P), আর client-এর port (C) তার থেকে আলাদা — client-এর port-ও kernel বেছে দিয়েছে, কারণ child কখনো bind() করেনি; এটি একটি ephemeral port. আসল নম্বর প্রতিবার বদলায়, তাই প্রোগ্রাম শুধু সম্পর্ক ছাপে।

সংযোগ চলার সময় /proc/net/tcp-এ তিনটি আলাদা socket পাওয়া গেল। Listener: state 0A = LISTEN, আর তার local ঠিকানার কাঁচা hex 0100007F — উল্টে 7F 00 00 01 = ১২৭.০.০.১, স্টেপারের সেই নিয়ম। মজার ব্যাপার হলো, accept() listener-কে বদলায় না — সে আগের মতোই শুনছে; সংযোগের জন্য kernel একটি নতুন socket বানিয়েছে (server end: local P, remote C). আর client end তার আয়না: local C, remote P. দুই প্রান্তই 01 = ESTABLISHED. একটি TCP সংযোগ মানেই দুটি socket, প্রতিটি প্রান্তে একটি — আর loopback-এ দুটিই একই যন্ত্রে, তাই একই ফাইলে দেখা যায়।

সার্ভার আগে বন্ধ করার পরে: server end এখন 06 = TIME_WAIT, আর client end তালিকা থেকে উধাও (00 (gone)). এটি TCP-র একটি মৌলিক নিয়ম: যে প্রান্ত প্রথমে বন্ধ করে (active close), সে-ই TIME_WAIT-এ কিছুক্ষণ অপেক্ষা করে — Linux-এ ৬০ সেকেন্ড। অন্য প্রান্ত শেষ ACK পেয়েই পুরোপুরি মুছে যায়। ব্যস্ত ওয়েব সার্ভারে হাজার হাজার TIME_WAIT দেখা যায় ঠিক এই কারণে; কেন এই অপেক্ষা দরকার আর state-গুলোর পুরো যাত্রা, তা পর্ব ২৯-এ।

৯ · Packet নিজের চোখে — tcpdump, Wireshark আর নৈতিকতা

এতক্ষণ আমরা দেখেছি kernel-এর হিসাব। কিন্তু তারে আসলে কোন বাইট যাচ্ছে? সেটি দেখার কাজের নাম packet capture. Command line-এ এর প্রধান টুল tcpdump, আর গ্রাফিক্যাল টুল Wireshark — যেটি প্রতিটি packet-কে স্তর ধরে ধরে খুলে দেখায় (Ethernet → IP → TCP → HTTP), ঠিক পর্ব ৩-এর encapsulation-এর ছবির মতো।

অংশ ৬-এর nc পরীক্ষাটি চলার সময় নিজের ল্যাপটপে loopback interface-এ capture করলে এরকম দেখাবে (উদাহরণ; capture করতে root বা বিশেষ অনুমতি লাগে):

$ sudo tcpdump -i lo -n 'tcp port 9000'
listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
21:20:01.112233 IP 127.0.0.1.48212 > 127.0.0.1.9000: Flags [S], seq 3049185517, win 65495, options [mss 65495,sackOK,TS val 1912345 ecr 0,nop,wscale 7], length 0
21:20:01.112250 IP 127.0.0.1.9000 > 127.0.0.1.48212: Flags [S.], seq 1772004321, ack 3049185518, win 65483, options [mss 65495,sackOK,TS val 1912345 ecr 1912345,nop,wscale 7], length 0
21:20:01.112262 IP 127.0.0.1.48212 > 127.0.0.1.9000: Flags [.], ack 1, win 512, options [nop,nop,TS val 1912345 ecr 1912345], length 0
21:20:04.530101 IP 127.0.0.1.48212 > 127.0.0.1.9000: Flags [P.], seq 1:7, ack 1, win 512, options [nop,nop,TS val 1915763 ecr 1912345], length 6
21:20:04.530118 IP 127.0.0.1.9000 > 127.0.0.1.48212: Flags [.], ack 7, win 512, options [nop,nop,TS val 1915763 ecr 1915763], length 0

প্রথম তিনটি লাইন TCP-র বিখ্যাত three-way handshake: [S] (SYN), [S.] (SYN + ACK), [.] (ACK). দ্বিতীয় লাইনের ack 3049185518 = প্রথম লাইনের seq + ১. তারপর tcpdump সুবিধার জন্য seq নম্বর আপেক্ষিক করে দেখায় (ack 1). চতুর্থ লাইনে hello আর newline — মোট ৬ বাইট (seq 1:7, length 6), [P.] মানে PUSH + ACK; পঞ্চম লাইনে প্রাপক জানাল “৭ পর্যন্ত পেয়েছি”। mss 65495 = একটি IPv4 packet-এর সর্বোচ্চ আকার ৬৫,৫৩৫ বাইট (header-এর ১৬-বিট দৈর্ঘ্যের ঘর) থেকে IP আর TCP header-এর ৪০ বাইট বাদ — loopback-এর MTU ৬৫,৫৩৬ এর চেয়েও বড়, তাই সীমাটা আসে IPv4 থেকে। এই সংখ্যাগুলোর প্রতিটির মানে পর্ব ২৯–৩১-এ খুলে দেখবেন; এখন শুধু মনে রাখুন — packet capture হলো নেটওয়ার্কের “সত্যের উৎস”, টুলের ব্যাখ্যা নয়, তারে যা গেছে তাই।

Wireshark-এ দুই রকম filter আছে, যা নতুনরা প্রায়ই গুলিয়ে ফেলেন: capture filter (tcpdump-এর মতো BPF ভাষা, যেমন tcp port 9000) ঠিক করে কোন packet আদৌ ধরা হবে; display filter (Wireshark-এর নিজের ভাষা, যেমন tcp.port == 9000) শুধু ধরা packet-এর মধ্যে কোনটি দেখাবে। Windows-এ Wireshark চলে Npcap driver দিয়ে; Windows-এর নিজস্ব pktmon-ও আছে। বিস্তারিত তদন্তের কৌশল পর্ব ৫৫-এ।

নৈতিকতা আর আইন — এই অংশটি বাদ দেবেন না। Packet capture শুধু নিজের যন্ত্রে, নিজের বাসার নেটওয়ার্কে, অথবা যে নেটওয়ার্কের দায়িত্বশীল ব্যক্তির কাছ থেকে লিখিত অনুমতি পেয়েছেন সেখানে করুন। ক্যাফে, বিশ্ববিদ্যালয়, অফিস বা প্রতিবেশীর Wi-Fi-তে অন্যের traffic ধরা অন্যের ব্যক্তিগত যোগাযোগে আড়ি পাতা — এটি অনৈতিক, আর বাংলাদেশসহ বহু দেশের আইনে অপরাধ হিসেবে গণ্য হতে পারে। এই কোর্সে capture শেখানো হচ্ছে প্রতিরক্ষা আর সমস্যা খোঁজার জন্য: নিজের অ্যাপ ঠিকমতো এনক্রিপ্ট করছে কি না, সংযোগ কোথায় আটকাচ্ছে, কোন যন্ত্র অস্বাভাবিক traffic পাঠাচ্ছে। Capture ফাইলে (.pcap) পাসওয়ার্ড, cookie আর ব্যক্তিগত তথ্য থাকতে পারে — তাই এগুলো অনলাইনে কারও সাথে ভাগ করার আগে ভাবুন, আর কাজ শেষে মুছে ফেলুন।

ভালো খবর হলো, আজকের ওয়েবের বেশিরভাগ traffic HTTPS-এ এনক্রিপ্ট করা, তাই কেউ capture করলেও বিষয়বস্তু পড়তে পারে না। তবু কিছু তথ্য খোলা থাকে — কোন ঠিকানায় কখন কত বাইট গেল, আর অনেক সময় কোন ডোমেইনে সংযোগ হচ্ছে (DNS প্রশ্ন আর TLS-এর SNI থেকে)। এজন্যই নিজের অ্যাপে HTTPS বাধ্যতামূলক রাখা আর সংবেদনশীল কাজে public Wi-Fi এড়িয়ে চলা ভালো অভ্যাস। এই প্রতিরক্ষার কাঠামো মডিউল ৮-এ।

১০ · AI-এর যুগে নেটওয়ার্ক কমান্ড — কপি করার আগে

“আমার ইন্টারনেট ধীর, কী কমান্ড দেব?” — এ প্রশ্নে AI মুহূর্তে এক গাদা কমান্ড দেবে। কিছু হবে চমৎকার, কিছু পুরোনো, আর কিছু বিপজ্জনক। নেটওয়ার্ক কমান্ডের ক্ষেত্রে ভুলের দাম বেশি: একটি ভুল ip route বা firewall কমান্ড দূরের সার্ভার থেকে আপনাকে চিরতরে বের করে দিতে পারে, আর “সব খুলে দিন” ধাঁচের পরামর্শ সার্ভারকে আক্রমণের জন্য উন্মুক্ত করে।

AI-এর সাধারণ ভুলকীভাবে ধরবেন
ifconfig, netstat, route দিয়ে উত্তর — আপনার যন্ত্রে নেই বা অসম্পূর্ণ তথ্য দেয়ip/ss-এর সমতুল্য চান; অংশ ১-এর টেবিল মিলিয়ে নিন
Windows, macOS আর Linux-এর কমান্ড মিশিয়ে ফেলা (যেমন Linux-এ ipconfig, macOS-এ ss)প্রশ্নেই OS আর version বলুন; command -v আর man দিয়ে যাচাই করুন
কাল্পনিক flag বা বিকল্পman ip-route, ss --help দেখুন; আগে নিরীহ “দেখার” রূপে চালান
Subnet বা hex-এর ভুল হিসাব (যেমন /proc/net-এর বাইট না উল্টে পড়া)নিজে হাতে বা ছোট স্ক্রিপ্টে আবার হিসাব করুন
“firewall বন্ধ করুন”, “0.0.0.0-তে খুলে দিন”, “chmod 777” ধাঁচের অনিরাপদ সমাধানশুধু দরকারি port, শুধু দরকারি ঠিকানায়; 127.0.0.1 যথেষ্ট কি না আগে ভাবুন
বানানো RFC নম্বর বা ভুল সালrfc-editor.org-এ নম্বরটি খুলে শিরোনাম মিলিয়ে দেখুন
অন্যের নেটওয়ার্ক “scan” করার পরামর্শশুধু নিজের যন্ত্র বা লিখিত অনুমতির নেটওয়ার্ক; প্রশ্নেই এই সীমা বলে দিন

সমস্যার বিবরণ দিয়ে AI-কে এভাবে প্রশ্ন করলে উত্তর অনেক নির্ভরযোগ্য হয় — OS, কী দেখছেন, কোন কমান্ডের আউটপুট, আর কী চান না:

আমি Ubuntu 24.04 ল্যাপটপে বাসার Wi-Fi ব্যবহার করি। ব্রাউজারে কিছু সাইট খুলছে না, কিছু খুলছে। নিচে আমার ip -br addr, ip route আর dig example.com-এর আউটপুট দিলাম: [এখানে আউটপুট পেস্ট করুন — দরকার হলে নিজের public IP মুছে দিন] ১. শুধু ip, ss, ping, dig, curl-এর মতো দেখার কমান্ড দাও — কিছু বদলানোর (sudo, firewall, route add) কমান্ড আগে দিও না। ২. প্রতিটি কমান্ড কোন স্তর পরীক্ষা করছে (link, IP, DNS, application) আর ঠিক থাকলে কী আউটপুট দেখার কথা, বলো। ৩. ifconfig বা netstat-এর মতো পুরোনো কমান্ড দিও না। ৪. কোনো RFC বা নিয়মের কথা বললে তার নম্বর দাও, যাতে আমি নিজে মিলিয়ে নিতে পারি।

AI-এর দেওয়া নেটওয়ার্ক কমান্ড চালানোর আগে — চেকলিস্ট

পরীক্ষা ও ইন্টারভিউতে এই বিষয়ে প্রায়ই যা জিজ্ঞেস করা হয়:

  • ping কোন protocol ব্যবহার করে, কোন port-এ? — ICMP-এর Echo Request (type 8) আর Echo Reply (type 0); ICMP-এ port নেই।
  • traceroute কীভাবে পথের router চেনে? — TTL ১, ২, ৩… দিয়ে probe পাঠায়; যে router-এ TTL ০ হয়, সে ICMP Time Exceeded (type 11) পাঠায়, তার উৎস-ঠিকানাই সেই hop.
  • একটি সার্ভার 0.0.0.0:80 আর 127.0.0.1:80-এ শুনলে পার্থক্য কী? — প্রথমটি যন্ত্রের সব IPv4 ঠিকানায় (বাইরে থেকেও পৌঁছানো যায়), দ্বিতীয়টি শুধু loopback-এ (শুধু ওই যন্ত্র থেকে)।
  • Linux-এ default gateway কীভাবে দেখবেন? Windows-এ? — ip route-এর default via লাইন; Windows-এ ipconfig বা route print.
  • ifconfig/netstat-এর বদলে ip/ss কেন? — net-tools-এর উন্নয়ন বহু বছর থেমে ছিল, আধুনিক বৈশিষ্ট্য দেখাতে পারে না; iproute2 netlink ব্যবহার করে, বেশি তথ্য দেয় আর বড় সিস্টেমে দ্রুত।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।

প্র ০১Linux কেন ifconfig আর netstat ছেড়ে ip আর ss-এ গেল? পুরোনো টুল তো দিব্যি কাজ করত।

ifconfig, route, arp আর netstat এসেছে BSD Unix-এর ঐতিহ্য থেকে, আর Linux-এ এদের সংকলন net-tools প্যাকেজ। যে যুগে এগুলো নকশা হয়েছিল, তখন একটি যন্ত্রে সাধারণত একটি নেটওয়ার্ক কার্ড, তাতে একটি IPv4 ঠিকানা আর একটি routing table থাকত। এই টুলগুলো kernel-এর সাথে কথা বলত ioctl নামের পুরোনো, নির্দিষ্ট-আকারের কাঠামোর system call দিয়ে।

১৯৯০-এর দশকের শেষ দিকে Linux-এর নেটওয়ার্ক স্তর অনেক জটিল হয়ে ওঠে: এক interface-এ অনেক ঠিকানা, IPv6, একাধিক routing table আর “policy routing” (উৎস দেখে পথ বাছাই), traffic control. এগুলো কনফিগার করার জন্য kernel-এ যোগ হয় netlink — একটি বিশেষ socket, যার ভেতরে বার্তা পাঠিয়ে kernel-এর নেটওয়ার্ক অবস্থা পড়া ও বদলানো যায়, আর বার্তার কাঠামো প্রসারণযোগ্য, তাই নতুন বৈশিষ্ট্যে নতুন ঘর যোগ করা যায়। এর ওপর Alexey Kuznetsov-এর হাতে গড়ে ওঠে iproute2 — ip, tc, পরে ss.

অন্যদিকে net-tools-এর রক্ষণাবেক্ষণ বহু বছর প্রায় থেমে ছিল। ফলে পুরোনো ifconfig একটি interface-এর দ্বিতীয় ঠিকানা দেখাতই না, যদি না সেটিকে eth0:1 ধাঁচের “alias” নামে যোগ করা হতো; ip addr add দিয়ে যোগ করা ঠিকানা সে বেমালুম লুকিয়ে রাখত। বড় সার্ভারে netstat-কে /proc/net/tcp-এর বিশাল লেখা পড়ে পার্স করতে হয়, যেখানে ss netlink-এর মাধ্যমে kernel-কেই ছেঁকে দিতে বলে — লক্ষাধিক সংযোগে পার্থক্য সেকেন্ড বনাম মিলিসেকেন্ডের। এসব কারণে Debian, Ubuntu, Fedora, Arch-এর মতো distribution-গুলো ধীরে ধীরে net-tools-কে ডিফল্ট ইনস্টল থেকে বাদ দিয়েছে; চাইলে আলাদা করে ইনস্টল করা যায়।

এর মানে এই নয় যে ifconfig “ভুল”। macOS আর FreeBSD-তে ifconfig আজও প্রধান, সক্রিয়ভাবে উন্নত হওয়া টুল — কারণ সেখানে kernel আর টুল একই প্রকল্পের অংশ হিসেবে একসাথে বদলায়। সমস্যাটা ছিল Linux-এ পুরোনো টুল আর নতুন kernel-এর মধ্যে ফাঁক।

মূল উপলব্ধি: টুল হলো kernel-এর জানালা। জানালা পুরোনো হলে ঘরের অর্ধেক দেখা যায় না, আর আপনি ভুল সিদ্ধান্ত নেন। কোনো টুলের আউটপুট বিশ্বাস করার আগে জানুন সেটি কোন interface দিয়ে তথ্য পাচ্ছে, আর আধুনিক সিস্টেমের সব বৈশিষ্ট্য দেখাতে পারে কি না।

প্র ০২ping-এ উত্তর আসছে না — এর মানে কি সার্ভার বন্ধ? ICMP আটকানো কি ভালো নিরাপত্তা?

ping লিখেছিলেন Mike Muuss, ১৯৮৩ সালে, খুব অল্প সময়ের মধ্যে — একটি নেটওয়ার্ক সমস্যা খুঁজতে গিয়ে। নামটি সোনারের “পিং” শব্দ থেকে: শব্দ পাঠানো, তারপর প্রতিধ্বনির অপেক্ষা। চার দশক পরেও এটিই সবার প্রথম টুল। কিন্তু উত্তর না আসার অনেক কারণ থাকতে পারে, আর সার্ভার বন্ধ থাকা তার একটি মাত্র।

প্রথমত, পথের যেকোনো firewall ICMP Echo আটকাতে পারে — অনেক ক্লাউড প্রদানকারীর ডিফল্ট নিয়মেই তা বন্ধ থাকে। দ্বিতীয়ত, router আর সার্ভার ICMP উত্তরের হার সীমিত রাখে (rate limit), তাই একসাথে অনেক ping-এ কিছু উত্তর হারাতে পারে। তৃতীয়ত, আপনার নিজের দিকেই সমস্যা থাকতে পারে — ভুল DNS (তাহলে ping নামটি ঠিকানায় বদলাতেই পারবে না), ভুল gateway, বা VPN. তাই ping-এর ফল পড়তে হয় অন্য তথ্যের সাথে মিলিয়ে: curl দিয়ে আসল সেবাটি পরীক্ষা, traceroute দিয়ে কোথায় থামছে দেখা।

ICMP আটকানো কেন শুরু হলো? ১৯৯০-এর দশকে “Ping of Death” (নিয়মের চেয়ে বড়, টুকরো করা ICMP packet, যা কিছু পুরোনো সিস্টেমকে crash করাত) আর ICMP দিয়ে বন্যা-আক্রমণের মতো ঘটনায় অনেক প্রশাসক সব ICMP-ই বন্ধ করে দিতে শুরু করেন। কিন্তু এটি একটি ভুল শিক্ষা। ICMP শুধু ping নয় — “Fragmentation Needed” বা IPv6-এর “Packet Too Big” বার্তা path MTU discovery-র জন্য অপরিহার্য। এগুলো আটকালে তৈরি হয় বিখ্যাত “PMTU black hole”: ছোট অনুরোধ চলে, বড় ফাইল বা কিছু ওয়েবপাতা আটকে থাকে, আর সমস্যাটা খুঁজে পেতে দিনের পর দিন লাগে। IPv6-এ তো ICMPv6 ছাড়া নেটওয়ার্ক চলেই না — Neighbor Discovery ICMPv6-এর ওপর দাঁড়ানো।

আধুনিক নিরাপত্তা-চিন্তা তাই বলে: ICMP পুরোপুরি বন্ধ নয়, বরং বেছে বেছে অনুমতি আর হার-সীমা। Echo বন্ধ রাখলে খুব বেশি নিরাপত্তা বাড়ে না — আক্রমণকারী অন্য উপায়েও জানতে পারে সার্ভার চালু আছে কি না — কিন্তু নিজের দলের সমস্যা খোঁজা কঠিন হয়ে যায়।

মূল উপলব্ধি: একটি পরীক্ষার “না” মানে শুধু “এই পরীক্ষাটি পাস করেনি”। সিদ্ধান্তে পৌঁছাতে একাধিক স্তরের পরীক্ষা মিলিয়ে দেখুন, আর নিরাপত্তার নামে এমন কিছু বন্ধ করবেন না, যার কাজ আপনি জানেন না।

প্র ০৩traceroute-এর দেখানো পথ কতটা বিশ্বাসযোগ্য? কোন কোন ক্ষেত্রে এটি ভুল ছবি দেয়?

traceroute লিখেছিলেন Van Jacobson, ১৯৮০-এর দশকের শেষ দিকে — TTL-এর একটি পার্শ্বপ্রতিক্রিয়াকে (ফেলে দেওয়ার সময় ICMP Time Exceeded পাঠানো) একটি মাপযন্ত্রে বদলে দিয়ে। কৌশলটি অসাধারণ, কারণ router-গুলোর কোনো সহযোগিতা বা বিশেষ বৈশিষ্ট্য লাগে না। কিন্তু এর ফল পড়ার সময় কয়েকটি ফাঁদ মনে রাখতে হয়।

  • শুধু যাওয়ার পথ: traceroute দেখায় আপনার কাছ থেকে গন্তব্যে যাওয়ার পথ। ফেরার পথ আলাদা হতে পারে (asymmetric routing), কারণ প্রতিটি নেটওয়ার্ক নিজের নীতিতে পথ বাছে — ইন্টারনেটে এটি খুবই সাধারণ। অথচ hop-এর RTT-তে যাওয়া আর ফেরা দুটোই ঢুকে থাকে।
  • Load balancing: বড় নেটওয়ার্কে একই গন্তব্যের একাধিক সমান পথ থাকে, আর router প্রতিটি “flow”-কে (ঠিকানা আর port দেখে) একটি পথে পাঠায়। ক্লাসিক traceroute প্রতিটি probe-এ port বদলায়, তাই আলাদা probe আলাদা পথে যেতে পারে, আর আউটপুটে এমন “পথ” দেখা যায় যা বাস্তবে নেই। ২০০৬ সালের দিকে গবেষকরা “Paris traceroute” প্রস্তাব করেন, যা probe-এর flow-পরিচয় স্থির রেখে এই সমস্যা কমায়।
  • লুকানো hop: MPLS-এর মতো প্রযুক্তি ব্যবহার করা ISP-এর ভেতরের কিছু router TTL কমায় না বা নিজেকে দেখায় না; তখন কয়েকটি hop মিলে একটি মনে হয়।
  • Control plane-এর ধীরতা: router-এর কাছে packet পাঠিয়ে দেওয়া (forwarding) হয় দ্রুত হার্ডওয়্যারে, কিন্তু ICMP বার্তা বানানো হয় তার ধীর CPU-তে, কম অগ্রাধিকারে। তাই মাঝের কোনো hop-এ বেশি RTT বা loss দেখা গেলেও পরের hop-গুলো স্বাভাবিক থাকলে বুঝবেন — সমস্যা আসলে নেই, ওই router শুধু উত্তর দিতে অলস।

তাই অভিজ্ঞ নেটওয়ার্ক প্রকৌশলী একটি traceroute দেখে রায় দেন না। তিনি mtr দিয়ে অনেকক্ষণ ধরে মাপেন, দুই দিক থেকে traceroute চালান (সার্ভার থেকে আপনার দিকেও), আর loss বা delay যে hop থেকে শুরু হয়ে শেষ পর্যন্ত টিকে থাকে, সেখানেই সন্দেহ করেন।

মূল উপলব্ধি: প্রতিটি মাপযন্ত্র নিজের পদ্ধতির ছাপ ফলের ওপর রেখে যায়। traceroute পথের একটি আনুমানিক ছবি দেয়, নিখুঁত মানচিত্র নয় — তার সীমা জানলেই আপনি এর সবচেয়ে ভালো ব্যবহার করতে পারবেন।

প্র ০৪tcpdump আর Wireshark এত শক্তিশালী হলে কেন সবার জন্য খোলা? Packet capture-এর নৈতিক সীমা কোথায়?

tcpdump আর এর library libpcap তৈরি হয় ১৯৮০-এর দশকের শেষে Lawrence Berkeley Laboratory-তে, Van Jacobson, Craig Leres আর Steven McCanne-এর হাতে। এর সাথে আসে BPF (Berkeley Packet Filter) — kernel-এর ভেতরেই packet ছেঁকে নেওয়ার একটি ছোট ভার্চুয়াল যন্ত্র, যার আধুনিক উত্তরসূরি eBPF আজ Linux-এর পর্যবেক্ষণ আর নিরাপত্তার মেরুদণ্ড। ১৯৯৮ সালে Gerald Combs শুরু করেন Ethereal, যা ২০০৬ সালে নাম বদলে হয় Wireshark. দুটোই মুক্ত সফটওয়্যার, আর প্রায় প্রতিটি নেটওয়ার্ক প্রকৌশলী, নিরাপত্তা বিশ্লেষক আর protocol-নির্মাতা এগুলো প্রতিদিন ব্যবহার করেন।

এগুলো সবার জন্য খোলা, কারণ প্রতিরক্ষা করতে হলে আগে দেখতে হয়। একটি অ্যাপ পাসওয়ার্ড এনক্রিপ্ট না করে পাঠাচ্ছে কি না, একটি IoT ক্যামেরা অচেনা সার্ভারে ডেটা পাঠাচ্ছে কি না, একটি সংযোগ handshake-এর কোন ধাপে আটকাচ্ছে — এসব প্রশ্নের উত্তর capture ছাড়া পাওয়া কঠিন। একটি ধারালো ছুরি রান্নাঘরেও লাগে; ছুরির দোষ নয়, ব্যবহারের দোষ।

ঝুঁকিটা বাস্তব। ২০১০ সালে Firesheep নামের একটি browser extension দেখিয়েছিল, public Wi-Fi-তে বসে অন্যের unencrypted cookie ধরে তাদের সামাজিক যোগাযোগ অ্যাকাউন্টে ঢোকা কত সহজ। এই প্রদর্শনী বড় ওয়েবসাইটগুলোকে পুরো সাইট HTTPS করতে চাপ দিয়েছিল, আর পরে বিনামূল্যের certificate (যেমন Let's Encrypt) সেই রূপান্তর সহজ করে। অর্থাৎ capture-এর ক্ষমতা দেখানোই প্রতিরক্ষা উন্নত করেছে।

নৈতিক সীমা তাই পরিষ্কার: যে নেটওয়ার্ক আপনার, বা যার জন্য লিখিত অনুমতি আছে, শুধু সেখানে। পেশাদার নিরাপত্তা পরীক্ষায়ও কাজ শুরুর আগে লিখিত চুক্তিতে পরিধি (scope) ঠিক করা হয়। Capture-এ যা পাওয়া যায় তা গোপন রাখা, দরকার শেষে মুছে ফেলা, আর অফিসের নেটওয়ার্কে capture করলেও শুধু নির্দিষ্ট সমস্যার traffic ছেঁকে নেওয়া — এগুলো পেশাদার আচরণের অংশ। আইনের দিক থেকে, অনুমতি ছাড়া অন্যের যোগাযোগে আড়ি পাতা বাংলাদেশসহ বহু দেশে শাস্তিযোগ্য হতে পারে; সুনির্দিষ্ট বিধান দেশ আর সময়ভেদে বদলায়, তাই প্রতিষ্ঠানের নীতি আর আইনজীবীর পরামর্শই চূড়ান্ত।

মূল উপলব্ধি: টুল নিরপেক্ষ, ব্যবহারকারী নয়। নেটওয়ার্ক পেশায় সুনাম গড়ে ওঠে দক্ষতা আর বিশ্বাস দুটো দিয়ে — যে প্রকৌশলীকে অন্যের traffic-এর কাছে বিশ্বাস করে পাঠানো যায়, তিনিই সবচেয়ে মূল্যবান।

প্র ০৫Kernel কেন নেটওয়ার্কের তথ্য /proc-এ “ফাইল” আকারে দেয়? এই নকশার সুবিধা আর দাম কী?

“সবকিছুই ফাইল” — Unix-এর এই দর্শনের একটি সাহসী প্রসারণ হলো /proc. ১৯৮৪ সালের দিকে Bell Labs-এ Tom Killian Unix-এর Eighth Edition-এ process-গুলোকে ফাইলের মতো দেখানোর জন্য প্রথম /proc বানান, মূলত debugger-এর সুবিধার জন্য। পরে Plan 9 অপারেটিং সিস্টেম এই চিন্তাকে আরও দূরে নিয়ে যায়, আর Linux এটি গ্রহণ করে প্রায় সব kernel তথ্যের জন্য — process, মেমরি, আর নেটওয়ার্ক।

সুবিধা: কোনো বিশেষ library বা টুল ছাড়াই cat, awk, grep দিয়ে তথ্য পড়া যায়, যেকোনো ভাষা থেকে — এই পর্বের bash, C আর JavaScript উদাহরণ তার প্রমাণ। ছোট container বা ভাঙা সিস্টেমে, যেখানে ip বা ss নেই, /proc/net তখনো থাকে। পড়ার অনুমতি ফাইলের অনুমতি দিয়েই নিয়ন্ত্রিত। আর তথ্য সবসময় তাজা, কারণ পড়ার মুহূর্তে বানানো হয়।

দাম: প্রথমত, লেখা (text) বানানো আর পার্স করা দুই দিকেই খরচ — লক্ষাধিক socket-এর সার্ভারে /proc/net/tcp পড়তে উল্লেখযোগ্য সময় লাগে। দ্বিতীয়ত, ফাইলটি এক মুহূর্তের ছবি নয়; পড়ার মাঝেই socket আসা-যাওয়া করে, তাই একটি সারি দুবার আসতে বা বাদ পড়তে পারে। তৃতীয়ত, ফরম্যাট কার্যত চিরস্থায়ী হয়ে যায়: অসংখ্য স্ক্রিপ্ট কলামের অবস্থান ধরে পড়ে, তাই kernel আর কলাম বদলাতে পারে না — এই কারণেই hex-এ উল্টো বাইটের মতো অদ্ভুত বৈশিষ্ট্যও দশকের পর দশক টিকে আছে। “Userspace ভাঙা যাবে না” — Linux kernel-এর এই কঠোর নীতি এখানে স্থবিরতারও কারণ।

এজন্যই নতুন তথ্যের জন্য kernel-এর পছন্দ এখন কাঠামোবদ্ধ, বাইনারি interface — netlink, আর পর্যবেক্ষণের জন্য eBPF. তবু /proc/net থেকে যাবে, কারণ এর সরলতার কোনো বিকল্প নেই।

মূল উপলব্ধি: প্রতিটি interface একটি চুক্তি। মানুষের পড়ার মতো সরল চুক্তি শেখা ও ব্যবহার সহজ করে, কিন্তু বদলানো কঠিন আর বড় মাপে ধীর; যন্ত্রের জন্য কাঠামোবদ্ধ চুক্তি দ্রুত আর প্রসারণযোগ্য, কিন্তু টুল ছাড়া পড়া যায় না। ভালো সিস্টেম দুটোই রাখে, কাজ অনুযায়ী।

অনুশীলন

কাগজ-কলমে হিসাব, আউটপুট অনুমান আর নিজের যন্ত্রে দেখা — চারটিই করুন।

  1. হাতে decode (হিসাব): একটি যন্ত্রের /proc/net/route-এ আছে wlp2s0 00000000 0100A8C0 0003 … Mask 00000000 আর wlp2s0 0000A8C0 00000000 0001 … Mask 00FFFFFF; আর /proc/net/tcp-এ আছে 6900A8C0:C350 0A7100CB:01BB 01. Default gateway, স্থানীয় নেটওয়ার্ক আর TCP সংযোগটি কী?

    Default gateway: Destination 00000000 = 0.0.0.0 (default); Gateway 0100A8C0 → বাইট 01 00 A8 C0 → উল্টে C0 A8 00 01 = 192.168.0.1; Flags ০০০৩ = U + G.

    স্থানীয় নেটওয়ার্ক: Destination 0000A8C0 → উল্টে C0 A8 00 00 = 192.168.0.0; Mask 00FFFFFF → উল্টে FF FF FF 00 = 255.255.255.0 = /24; Gateway ০ আর Flags ০০০১ (শুধু U) — সরাসরি সংযুক্ত। অর্থাৎ 192.168.0.0/24.

    TCP: local 6900A8C0 → 192.168.0.105, port C350 = ১২×৪০৯৬ + ৩×২৫৬ + ৫×১৬ + ০ = ৫০,০০০; remote 0A7100CB → উল্টে CB 00 71 0A = 203.0.113.10, port 01BB = ৪৪৩; state ০১ = ESTABLISHED. অর্থাৎ এই যন্ত্রটি একটি HTTPS সার্ভারের client.

  2. আউটপুট অনুমান: একটি Linux যন্ত্রে কেউ চালালেন python3 -m http.server 8000 --bind 127.0.0.1. এখন ss -tln চালালে এই সার্ভারের লাইনটি দেখতে কেমন হবে? অন্য একটি ল্যাপটপ থেকে curl http://192.168.0.105:8000/ চালালে কী হবে?

    লাইনটি হবে প্রায় এরকম:

    State  Recv-Q Send-Q Local Address:Port Peer Address:Port
    LISTEN 0      5          127.0.0.1:8000      0.0.0.0:*

    Send-Q 5, কারণ Python-এর socketserver ডিফল্টভাবে backlog ৫ চায়। আর ঠিকানা 127.0.0.1 — তাই অন্য ল্যাপটপ থেকে সংযোগ পৌঁছাবে না; সাধারণত curl: (7) Failed to connect … Connection refused আসবে, কারণ 192.168.0.105:8000-এ কেউ শুনছে না (মাঝে firewall থাকলে timeout-ও হতে পারে)। বাইরে থেকে দেখাতে চাইলে --bind 0.0.0.0 লাগবে — তবে সেটা শুধু বিশ্বস্ত নেটওয়ার্কে, আর কাজ শেষে বন্ধ।

  3. কমান্ড লিখুন: “৮০৮০ port-এ কোন প্রোগ্রাম শুনছে?” — প্রশ্নটির উত্তর বের করার কমান্ড লিখুন Linux, Windows (PowerShell বা cmd) আর macOS-এর জন্য।
    # Linux (অন্যের process দেখতে sudo)
    $ sudo ss -ltnp 'sport = :8080'
    
    # Windows cmd: শেষ কলাম PID, তারপর নাম
    > netstat -ano | findstr :8080
    > tasklist /FI "PID eq 4321"
    # Windows PowerShell
    PS> Get-Process -Id (Get-NetTCPConnection -LocalPort 8080 -State Listen).OwningProcess
    
    # macOS
    $ sudo lsof -nP -iTCP:8080 -sTCP:LISTEN

    পুরোনো Linux উত্তর sudo netstat -tlnp | grep 8080 বা sudo lsof -i :8080-ও কাজ করে, যদি টুলগুলো ইনস্টল থাকে। খেয়াল করুন, grep 8080 ভুল করে 18080-কেও ধরে ফেলবে; ss-এর filter নির্দিষ্ট।

  4. নিজের যন্ত্রে দেখুন: নিজের Linux (বা WSL) থেকে ping -c 5 চালান দুটি গন্তব্যে — নিজের gateway (ip route থেকে নিন) আর যেকোনো পরিচিত ওয়েবসাইট। দুটির RTT আর TTL তুলনা করুন। ওয়েবসাইটের TTL থেকে hop-সংখ্যা অনুমান করে traceroute (বা tracepath) দিয়ে মিলিয়ে দেখুন।

    সাধারণত gateway-এর RTT হবে কয়েক মিলিসেকেন্ড (Wi-Fi-তে ১–১০ ms; তারে আরও কম), আর TTL হবে ৬৪ (Linux-ভিত্তিক router) বা ২৫৫/১২৮-এর কাছাকাছি — কারণ মাঝে কোনো router নেই, উত্তরটি শুরুর মান নিয়েই আসে। ওয়েবসাইটের RTT অনেক বেশি হবে — দেশের ভেতরের বা CDN-এর সার্ভার হলে কম, বিদেশের সার্ভার হলে কয়েক দশক থেকে কয়েকশো ms.

    TTL ধরুন ৫৫ এলো: সবচেয়ে কাছের প্রচলিত শুরুর মান ৬৪, তাই অনুমান ৬৪ − ৫৫ = ৯টি router, আর traceroute-এ গন্তব্য থাকার কথা মোটামুটি ১০ নম্বর লাইনে। পুরোপুরি না মিললে অবাক হবেন না: ফেরার পথ আলাদা হতে পারে, কিছু hop লুকানো থাকতে পারে, আর ওয়েবসাইটটি হয়তো ICMP-তে সাড়া না দিয়ে শুধু ওয়েবে দেয়। এই অমিলগুলো ব্যাখ্যা করতে পারাটাই আসল শেখা।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রম“ইন্টারনেট চলছে না” — নিচের স্তর থেকে ওপরের স্তরে যাচাইয়ের ধাপগুলো সাজান (▲▼ চেপে সরান)

  1. ip -br addr — interface UP আর IP ঠিকানা আছে কি না
  2. ip route — default gateway আছে কি না
  3. ping gateway — LAN-এ পৌঁছানো যায় কি না
  4. নাম ছাড়া একটি বাইরের IP-তে ping — ইন্টারনেট পর্যন্ত পথ আছে কি না
  5. dig — নাম থেকে ঠিকানা পাওয়া যায় কি না
  6. curl -v — সার্ভার আর application সাড়া দেয় কি না

একটি Linux সার্ভারে ss -tln-এর একটি লাইন: LISTEN 0 200 127.0.0.1:5432 0.0.0.0:*. কোন কথাটি সত্য?

  • ইন্টারনেটের যে কেউ 5432 port-এ সংযোগ করতে পারবে
  • শুধু ওই একই যন্ত্রের প্রোগ্রাম এতে সংযোগ করতে পারবে
  • এটি একটি চলমান (ESTABLISHED) সংযোগ
  • এই মুহূর্তে 200 জন client সংযুক্ত আছে

x86 Linux-এর /proc/net/tcp-এ local_address লেখা 0100007F:1F90. এর মানে কী?

  • 1.0.0.127, port 8080
  • 127.0.0.1, port 36895
  • 127.0.0.1, port 8080
  • 10.0.0.7, port 1990

একটি সার্ভারকে ping করলে উত্তর আসে ttl=118 দিয়ে। প্রচলিত শুরুর মান (৬৪, ১২৮, ২৫৫) ধরে সবচেয়ে সম্ভাব্য ব্যাখ্যা কোনটি?

  • সার্ভারটি সম্ভবত TTL 128 দিয়ে শুরু করেছে (Windows-এর মতো), আর পথে প্রায় 10টি router
  • সার্ভারটি TTL 64 দিয়ে শুরু করেছে, আর পথে 54টি router
  • সার্ভারটি TTL 255 দিয়ে শুরু করেছে, আর পথে 137টি router
  • উত্তর আসতে 118 মিলিসেকেন্ড লেগেছে

traceroute পথের মাঝের router-গুলোর ঠিকানা জানতে পারে কীভাবে?

  • প্রতিটি router traceroute-কে নিজের routing table পাঠায়
  • DNS server পথের সব router-এর তালিকা দেয়
  • ARP দিয়ে প্রতিটি router-এর MAC জিজ্ঞেস করে
  • ক্রমশ বাড়ানো TTL দিয়ে probe পাঠিয়ে, TTL ফুরানো router-এর ICMP Time Exceeded বার্তা থেকে

ip route-এর আউটপুটে আছে default via 192.168.0.1 dev wlp2s0. এখানে 192.168.0.1 কী?

  • এই যন্ত্রের নিজের IP ঠিকানা
  • Default gateway — অন্য নেটওয়ার্কের সব packet যে router-এর কাছে যায়
  • DNS server-এর ঠিকানা
  • স্থানীয় নেটওয়ার্কের broadcast ঠিকানা

একজন শিক্ষার্থী tcpdump শিখতে চান। কোন পরিস্থিতিতে packet capture করা নৈতিক ও গ্রহণযোগ্য?

  • ক্যাফের public Wi-Fi-তে অন্য ক্রেতাদের traffic, শুধু শেখার উদ্দেশ্যে
  • বিশ্ববিদ্যালয়ের Wi-Fi-তে, কারণ শিক্ষার্থী হিসেবে তিনি এর ব্যবহারকারী
  • নিজের ল্যাপটপের loopback-এ নিজের চালানো nc বা curl-এর traffic
  • প্রতিবেশীর Wi-Fi-তে, যদি পাসওয়ার্ড ছাড়াই খোলা থাকে

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. আধুনিক Linux-এ ip (addr, route, neigh) আর ss; পুরোনো ifconfig/netstat অসম্পূর্ণ বা অনুপস্থিত। Windows আর macOS-এর কমান্ড আলাদা।
  2. ip addr বলে ঠিকানা আর state, ip route-এর default via বলে gateway, ip neigh বলে প্রতিবেশীর MAC, ss -tulpn বলে কে কোন ঠিকানা-port-এ শুনছে — 127.0.0.1 মানে শুধু ভেতরে।
  3. ping দেয় RTT, TTL আর loss; traceroute TTL ফুরানোর ICMP বার্তা দিয়ে hop চেনায়; উত্তর না আসা মানেই বন্ধ নয়।
  4. dig → curl -v → nc: নাম, application আর কাঁচা TCP — নিচের স্তর থেকে ওপরে তদন্ত।
  5. /proc/net/tcp-এ ঠিকানার বাইট উল্টে পড়ুন, port সোজা, state hex কোডে (০১ ESTABLISHED, ০A LISTEN, ০৬ TIME_WAIT). Capture শুধু নিজের বা অনুমতির নেটওয়ার্কে।

পরের পর্বে: মডিউল ২ শুরু — একদম নিচের স্তরে নামব। তারের ভেতর দিয়ে বিট আসলে যায় কীভাবে? সংকেত, encoding, bandwidth, আর একটি চ্যানেলে সর্বোচ্চ কত গতি সম্ভব — Nyquist আর Shannon-এর সূত্র।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান