এই পর্বে যা শিখবেন
- “Site চলছে না” শুনলে কোন ক্রমে, কোন কমান্ড দিয়ে খুঁজবেন
ip,ss,dig,nc,curl,opensslআরtcpdump-এর আউটপুট পড়া- Refused, timeout, DNS failure, TLS failure, 502 আর 504 আলাদা করে চেনা
- ধীর অনুরোধের কোন ধাপে সময় যাচ্ছে, তা সংখ্যা দিয়ে বের করা
- Certificate-এর মেয়াদ খোঁজা, আর নিরাপদে firewall পরীক্ষা করা
১ · “Site চলছে না” — অনুমান নয়, স্তর ধরে খোঁজা
রাত এগারোটা। একটি কাল্পনিক অনলাইন বাজার অ্যাপের দলের group-এ বার্তা এলো: “Site চলছে না!” কেউ বলছেন server restart দিন, কেউ বলছেন firewall বন্ধ করে দেখি। দুটোই অনুমান। অনুমানে কাজ হলেও আপনি জানবেন না কী হয়েছিল, আর পরের সপ্তাহে একই ঘটনা ফিরবে।
ধরুন আপনি CNG নিয়ে একজন ডাক্তারের চেম্বারে যাচ্ছেন। পাঁচটি জিনিস ঠিক থাকতে হবে: চেম্বারের ঠিকানা জানা, সেখানে যাওয়ার রাস্তা খোলা, চেম্বারের দরজা খোলা, রিসিপশনে পরিচয় মেলানো, আর শেষে ডাক্তার নিজে রোগী দেখছেন। দেখা না হলে “ডাক্তার নেই” বলার আগে দেখতে হয় কোন জায়গায় আটকালেন। একটি অনুরোধও ঠিক এই পাঁচ জায়গা পার হয়।
এই পাঁচটি জায়গা হলো নিচের পাঁচটি স্তর। নেটওয়ার্কের তত্ত্ব, মানে packet আর protocol কীভাবে কাজ করে, তা Computer Networks কোর্সের বিষয়। সেখানে Linux-এ নেটওয়ার্ক দেখা আর সমস্যা খোঁজা পর্ব দুটি গভীরে যায়। এখানে আমরা দেখব একজন server চালকের কাজ: কোন স্তরে কোন হাতিয়ার ধরবেন, আর তার আউটপুট কীভাবে পড়বেন।
অনুরোধের পথের পাঁচ স্তর আর প্রতিটির হাতিয়ার
Five layers of a request and the tool for each
পদ্ধতিটির তিনটি নিয়ম। এক, একবারে একটিই প্রশ্ন: “এই স্তর কি ঠিক আছে?” দুই, দুই জায়গা থেকে মিলিয়ে দেখুন: server-এর ভেতর থেকে আর বাইরে থেকে। ভেতর থেকে চললে কিন্তু বাইরে থেকে না চললে সমস্যা মাঝখানে। তিন, কিছু বদলানোর আগে লিখে রাখুন কী দেখলেন, আর একবারে একটিই জিনিস বদলান।
এই পর্বের সব আউটপুট নমুনা। এগুলো কোনো আসল server থেকে নেওয়া নয়। ip, ss, dig ইত্যাদি কমান্ড এই পাতায় চলে না, আর পাতার রানারের নেটওয়ার্কও বন্ধ। Public ঠিকানা হিসেবে আছে documentation-এর জন্য রাখা 203.0.113.0/24, 198.51.100.0/24 আর example.com. সেগুলো ইন্টারনেটে কারও আসল server নয়। 10.0.1.25 একটি নমুনা private ঠিকানা। আউটপুটের চেহারা version-ভেদে কিছুটা আলাদা হতে পারে। নিজে চেষ্টা করতে চাইলে নিজের কম্পিউটার বা নিজের পরীক্ষার server ব্যবহার করুন। Cloud-এ পরীক্ষার server চালালে খরচ হতে পারে, তাই শেষে সেটি মুছে ফেলুন।
২ · নিজের server-কে চিনুন — ip addr আর ip route
SSH দিয়ে server-এ ঢুকে (পর্ব ১২) প্রথম প্রশ্ন: এই যন্ত্রের ঠিকানা কী, আর বাইরে যাওয়ার পথ কোনটি? একটি server-এর এক বা একাধিক network interface থাকে, মানে যে “দরজা” দিয়ে সে নেটওয়ার্কে যুক্ত। প্রতিটি interface-এর নিজের ঠিকানা থাকে।
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ ip -br addr
lo UNKNOWN 127.0.0.1/8 ::1/128
eth0 UP 10.0.1.25/24
$ ip route
default via 10.0.1.1 dev eth0 proto dhcp src 10.0.1.25 metric 100
10.0.1.0/24 dev eth0 proto kernel scope link src 10.0.1.25
$ ip route get 203.0.113.50
203.0.113.50 via 10.0.1.1 dev eth0 src 10.0.1.25 uid 1000
cache
loহলো loopback interface: server নিজের সাথে কথা বলার পথ। ঠিকানা127.0.0.1. এর packet যন্ত্রের বাইরে যায় না।eth0 UPমানে interface চালু। নামens5বা অন্য কিছুও হতে পারে।DOWNদেখলে সমস্যা একদম নিচের স্তরে।default via 10.0.1.1হলো routing table-এর default gateway লাইন: যে ঠিকানার জন্য নির্দিষ্ট পথ নেই, সেগুলো সব এখানে যায়। এই লাইন না থাকলে server বাইরের কারও সাথে কথা বলতে পারবে না।ip route getবলে দেয় একটি নির্দিষ্ট ঠিকানায় যেতে kernel এখন কোন পথ বাছবে। Routing table নিজে হাতে পড়ার চেয়ে এটি দ্রুত আর ভুল কম।
Cloud-এর একটি চমক। অনেক cloud-এ VM-এর public ঠিকানা তার interface-এ থাকেই না। ip addr-এ দেখবেন শুধু private IP; public ঠিকানাটি cloud-এর network নিজে অনুবাদ করে (NAT). তাই কোনো অ্যাপকে 203.0.113.10-এ bind করতে বললে সাধারণত Cannot assign requested address error আসে। Provider-ভেদে নিয়ম আলাদা। আসল পথের গল্প পর্ব ২৬-এ।
পুরোনো টিউটোরিয়ালে ifconfig, route আর netstat দেখবেন। এগুলো net-tools নামের প্যাকেজের অংশ। Linux-এ পরে আসে iproute2 (ip, ss), যার শুরুর দিকের প্রধান লেখক Alexey Kuznetsov. এটি kernel-এর নতুন netlink ইন্টারফেস ব্যবহার করে। অনেক distribution-এ net-tools এখন ডিফল্টভাবে থাকে না, তাই নতুন কাজে ip আর ss শিখুন।
৩ · কে শুনছে — ss -tlnp আর 127.0.0.1 বনাম 0.0.0.0
একটি server-এ অনেক প্রোগ্রাম একসাথে চলে। বাইরের অনুরোধ কার কাছে যাবে, তা ঠিক হয় port নম্বর দিয়ে: ঠিকানা যদি ভবন হয়, port হলো ফ্ল্যাট নম্বর। একটি প্রোগ্রাম নির্দিষ্ট ঠিকানা আর port-এ অপেক্ষা করলে তাকে বলে “listen করছে”। সেই সংযোগের প্রান্তটির নাম socket. ss দেখায় কে কোথায় listen করছে।
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ sudo ss -tlnp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=812,fd=6))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=640,fd=4))
LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=901,fd=6))
চারটি অক্ষর মনে রাখুন: -t TCP, -l শুধু listen করা socket, -n নামের বদলে সংখ্যা, -p কোন process. অন্য user-এর process দেখতে sudo লাগে। পড়ার নিয়ম:
- Local Address:Port সবচেয়ে গুরুত্বপূর্ণ ঘর। এখানেই লেখা কে কোন দরজায় আছে।
- Process বলে কোন প্রোগ্রাম, তার
pidকত।users:(("nginx",pid=812,fd=6))মানে nginx, process নম্বর 812. - Recv-Q আর Send-Q: LISTEN লাইনে Recv-Q হলো অপেক্ষারত সংযোগের সংখ্যা, আর Send-Q তার সীমা। Recv-Q সীমার কাছে গেলে অ্যাপ সংযোগ নিতে পারছে না, যদিও সে “চলছে”।
Bind ঠিকানাই ঠিক করে কে ঢুকতে পারবে
একটি প্রোগ্রাম কোন ঠিকানায় listen করবে, সেটিই তার bind address. এই ছোট্ট সেটিংটিই সবচেয়ে বেশি ভোগায়। সেই ডাক্তারের কথা ভাবুন: 127.0.0.1 মানে তিনি শুধু নিজের বাড়ির লোক দেখেন। 0.0.0.0 মানে সব দরজা খোলা, যে দরজা দিয়েই আসুন দেখবেন। একে wildcard address বলে।
| Bind ঠিকানা | Server-এর ভেতর থেকে 127.0.0.1-এ | অন্য যন্ত্র থেকে | কখন ব্যবহার |
|---|---|---|---|
127.0.0.1:8080 | চলে | Refused | Reverse proxy-র পেছনের অ্যাপ, লোকাল ডেটাবেস |
10.0.1.25:8080 | Refused | চলে (যদি firewall দেয়) | শুধু private network-এর জন্য |
0.0.0.0:8080 | চলে | চলে (যদি firewall দেয়) | সব IPv4 interface; সত্যিই দরকার হলে |
[::]:8080 বা *:8080 | সাধারণত চলে | চলে (যদি firewall দেয়) | IPv6-ও শোনে; * সাধারণত দুটিই বোঝায় |
এবার নিজে চালিয়ে দেখুন। নিচের script হাতে লেখা একটি নমুনা তালিকা পড়ে। এটি কোনো আসল কমান্ড চালায় না। সব interface-এ listen করা service খুঁজে বের করে, আর যেগুলো অনুমোদিত তালিকায় নেই সেগুলোকে আলাদা করে দেখায়।
set -euo pipefail
# Sample text typed by hand; nothing here reads the machine this runs on.
ALLOWED="22 80 443" # ports that are meant to be public on this server
awk -v allowed="$ALLOWED" '
BEGIN { n = split(allowed, p, " "); for (i = 1; i <= n; i++) ok[p[i]] = 1 }
$1 == "LISTEN" {
c = split($4, parts, ":"); port = parts[c]
addr = substr($4, 1, length($4) - length(port) - 1)
match($6, /"[^"]+"/); proc = substr($6, RSTART + 1, RLENGTH - 2)
if (addr == "127.0.0.1" || addr == "[::1]") { kind = "local"; note = "ok, loopback only" }
else if (addr == "0.0.0.0" || addr == "[::]" || addr == "*") {
kind = "ALL"
note = (port in ok) ? "ok, meant to be public" : "REVIEW: not on the allow list"
if (!(port in ok)) bad++
} else { kind = "one-ip"; note = "bound to one address" }
printf "%-6s %-7s %-14s %s\n", port, kind, proc, note
}
END { printf "services to review: %d\n", bad + 0 }
' <<'EOF'
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=812,fd=6))
LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=812,fd=7))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=640,fd=4))
LISTEN 0 244 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=901,fd=6))
LISTEN 0 511 0.0.0.0:6379 0.0.0.0:* users:(("redis-server",pid=955,fd=6))
LISTEN 0 4096 *:9100 *:* users:(("node_exporter",pid=702,fd=3))
LISTEN 0 128 10.0.1.25:8080 0.0.0.0:* users:(("api",pid=1204,fd=9))
EOFআউটপুট:
80 ALL nginx ok, meant to be public
443 ALL nginx ok, meant to be public
22 ALL sshd ok, meant to be public
5432 local postgres ok, loopback only
6379 ALL redis-server REVIEW: not on the allow list
9100 ALL node_exporter REVIEW: not on the allow list
8080 one-ip api bound to one address
services to review: 2
Port বের করতে শেষ :-এর পরের অংশ নেওয়া হয়েছে, কারণ [::]:22-এর ভেতরে অনেক : আছে। ফলাফল দুটি service-কে ধরেছে। Redis সব interface-এ শুনছে, অথচ তালিকায় নেই: ডেটাবেস বা cache বাইরে খোলা রাখা গুরুতর ঝুঁকি। Script শুধু সন্দেহের তালিকা দেয়। শেষ সিদ্ধান্ত আপনার, আর firewall এই ঝুঁকি আড়াল করতে পারে কিন্তু মুছে দেয় না।
৪ · নাম আর পথ — dig, ping, traceroute আর mtr
dig: নামটি কোন ঠিকানায় যায়
DNS হলো ইন্টারনেটের ঠিকানা-বই: নাম দিলে IP দেয়। আপনার server যাকে জিজ্ঞেস করে, সে হলো resolver. DNS-এর তত্ত্ব Computer Networks কোর্সে আছে; cloud-এর DNS সেবা পর্ব ২৯-এ। এখানে আমরা শুধু আউটপুট পড়ব।
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ dig example.com A
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4242
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; ANSWER SECTION:
example.com. 287 IN A 203.0.113.10
;; Query time: 12 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
| যা দেখলেন | মানে | পরের কাজ |
|---|---|---|
NOERROR, ANSWER 1+ | নাম ঠিক আছে; ঠিকানাটি প্রত্যাশিত কি না মিলিয়ে নিন | স্তর ২-এ যান |
NOERROR, ANSWER 0 | নাম আছে, কিন্তু এই ধরনের record নেই | Record-এর ধরন দেখুন: A, AAAA, CNAME |
NXDOMAIN | এই নামই নেই | বানান, zone আর registrar দেখুন |
SERVFAIL | Resolver উত্তর আনতে পারেনি | dig +trace দিয়ে ধাপে ধাপে দেখুন |
connection timed out; no servers could be reached | Resolver-এর কাছেই পৌঁছানো যায়নি | Resolver ঠিকানা আর port 53 দেখুন |
ঠিকানার পাশের 287 হলো TTL: resolver আরও এত সেকেন্ড পুরোনো উত্তর মনে রাখবে। তাই DNS বদলানোর পরও কিছুক্ষণ পুরোনো ঠিকানা আসতে পারে। অন্য resolver-কে সরাসরি জিজ্ঞেস করে তুলনা করতে dig @1.1.1.1 example.com লিখুন। আর একটি সূক্ষ্ম কথা: dig সরাসরি DNS-কে জিজ্ঞেস করে, /etc/hosts ফাইল দেখে না। অ্যাপ সাধারণত সেই ফাইলও দেখে। অ্যাপ যা পাচ্ছে তা জানতে getent hosts example.com চালান।
ping: ওপারে কেউ সাড়া দিচ্ছে কি
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ ping -c 4 203.0.113.10
PING 203.0.113.10 (203.0.113.10) 56(84) bytes of data.
64 bytes from 203.0.113.10: icmp_seq=1 ttl=54 time=38.2 ms
64 bytes from 203.0.113.10: icmp_seq=2 ttl=54 time=38.6 ms
64 bytes from 203.0.113.10: icmp_seq=3 ttl=54 time=39.1 ms
64 bytes from 203.0.113.10: icmp_seq=4 ttl=54 time=37.9 ms
--- 203.0.113.10 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 37.9/38.4/39.1/0.4 ms
ping পাঠায় ICMP বার্তা, আর time হলো যাওয়া-আসার সময় (RTT). packet loss বলে কত ভাগ হারাল। সাবধান: ping না চলা মানেই server বন্ধ নয়। অনেক cloud firewall ডিফল্টে ICMP আটকায়। ping সফল হলে পথ খোলা বোঝা যায়, কিন্তু ব্যর্থ হলে কিছুই প্রমাণ হয় না।
traceroute আর mtr: পথের কোন মোড়ে আটকাচ্ছে
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ mtr -rwc 20 203.0.113.10
HOST: web-1 Loss% Snt Last Avg Best Wrst StDev
1.|-- 10.0.1.1 0.0% 20 0.4 0.5 0.3 0.9 0.1
2.|-- ??? 100.0% 20 0.0 0.0 0.0 0.0 0.0
3.|-- 198.51.100.1 30.0% 20 12.1 12.4 11.8 14.0 0.5
4.|-- 203.0.113.10 0.0% 20 38.3 38.5 37.9 39.4 0.3
traceroute পথের প্রতিটি router-এর তালিকা দেয়, আর mtr একই কাজ বারবার করে প্রতিটি মোড়ের ক্ষতি আর সময় মাপে। এই আউটপুট পড়ার আসল নিয়ম: শেষ লাইন দেখুন। ওপরে হপ ৩-এ 30% ক্ষতি দেখাচ্ছে, অথচ হপ ৪-এ 0%. তাহলে আসল ক্ষতি নেই; router 3 শুধু নিজের সম্পর্কে উত্তর দিতে কৃপণ। ক্ষতি যদি একটি হপ থেকে শুরু হয়ে শেষ পর্যন্ত চলে, তবেই সেটি আসল। ??? বা * * * মানে সেই router উত্তর দেয়নি, পথ ভাঙা নয়। Port-ভিত্তিক সমস্যায় sudo traceroute -T -p 443 example.com TCP ব্যবহার করে, যা firewall-এ HTTPS-এর মতো আচরণ পায়।
৫ · দরজায় কড়া নাড়া — nc আর ছয় রকম ব্যর্থতা
nc (netcat) কোনো protocol জানে না। সে শুধু একটি port-এ TCP সংযোগ করে দেখে। Three-way handshake সফল হলেই “দরজা খোলা”। TCP সংযোগের তত্ত্ব Computer Networks কোর্সে আছে।
# উদাহরণ · নমুনা আউটপুট, OpenBSD netcat; version-ভেদে আলাদা হতে পারে
$ nc -vz -w 3 203.0.113.10 443
Connection to 203.0.113.10 443 port [tcp/https] succeeded!
$ nc -vz -w 3 203.0.113.10 8080
nc: connect to 203.0.113.10 port 8080 (tcp) failed: Connection refused
$ nc -vz -w 3 203.0.113.10 5432
nc: connect to 203.0.113.10 port 5432 (tcp) timed out: Operation now in progress
এই পর্বের সবচেয়ে দামি টেবিল এটি। ভুলের ধরন দেখেই বোঝা যায় কোন স্তরে তাকাবেন:
| লক্ষণ | সাধারণ মেসেজ | ভেতরে কী ঘটেছে | কোথায় দেখবেন |
|---|---|---|---|
| DNS failure | Could not resolve host | নাম থেকে ঠিকানাই পাওয়া যায়নি, packet রওনাই হয়নি | dig, getent |
| Connection refused | Connection refused, খুব দ্রুত | Packet পৌঁছেছে, কিন্তু সেই ঠিকানা-port-এ কেউ শুনছে না, তাই RST ফিরেছে | ss -tlnp, process, bind |
| Timeout | timed out, দীর্ঘ অপেক্ষা | উত্তর আসেনি: কেউ চুপচাপ ফেলে দিচ্ছে, বা পথ নেই | Firewall, security group, route |
| TLS failure | certificate has expired, handshake failure | TCP ঠিক আছে, পরিচয় মিলছে না | openssl s_client |
| 502 Bad Gateway | Proxy-র ত্রুটি পাতা | Proxy আছে, কিন্তু পেছনের অ্যাপ সংযোগ নেয়নি বা অচল উত্তর দিয়েছে | Proxy-র error log, অ্যাপের process |
| 504 Gateway Timeout | Proxy-র ত্রুটি পাতা, দীর্ঘ অপেক্ষার পর | পেছনের অ্যাপ সময়মতো উত্তর দেয়নি | অ্যাপের log, ডেটাবেস |
Refused: চেম্বারের দরজায় টোকা দিলেন, ভেতর থেকে কেউ বলল “এখানে এই ডাক্তার বসেন না”। অন্তত উত্তর পেয়েছেন। Timeout: টোকা দিলেন, কোনো সাড়া নেই। কেউ কি শুনছে না, নাকি গেটের দারোয়ান আপনাকে না জানিয়ে চিঠি ফেলে দিয়েছে? 502: রিসিপশন আছে, কিন্তু ভেতরের ঘরে ডাক্তার নেই। 504: ডাক্তার আছেন, এত ব্যস্ত যে রিসিপশন অপেক্ষা করে আপনাকে ফিরিয়ে দিল।
সময়ও একটি সূত্র। Refused আসে প্রায় এক RTT-তেই। Timeout-এ Linux ডিফল্ট সেটিংয়ে (tcp_syn_retries=6) SYN পাঠাতে থাকে 1, 2, 4, 8, 16, 32 আর 64 সেকেন্ড বিরতিতে, মোট প্রায় 127 সেকেন্ড; তবে অ্যাপ বা curl-এর নিজের সীমা আগেই থামাতে পারে। একটি ব্যতিক্রম মনে রাখুন: কোনো firewall REJECT নিয়মে থাকলে সে নিজেই উত্তর দেয়, ফলে firewall থেকেও refused আসতে পারে। Nginx-এর log এই দুটিকে পরিষ্কার আলাদা করে (HTTP-র status code দেখুন, আর nginx-এর পুরো গল্প পর্ব ১৪-এ):
# উদাহরণ · নমুনা error.log, version-ভেদে আলাদা হতে পারে
connect() failed (111: Connection refused) while connecting to upstream → 502
upstream timed out (110: Connection timed out) while reading response header from upstream → 504
এখানে upstream মানে reverse proxy-র পেছনের অ্যাপ। এবার সব মিলিয়ে একটি পুরো তদন্ত দেখি। ধরুন কাল্পনিক বাজার অ্যাপের API চলে api.example.com:8080-এ। ল্যাপটপ থেকে এলো Connection refused. “পরে” চেপে এগোন।
- DNSনাম
- Routeপথ
- Portদরজা
- Processপ্রোগ্রাম
- Bindঠিকানা
- Firewallপাহারা
| কোথা থেকে | |
| ফল |
- DNS. নামটি প্রত্যাশিত public ঠিকানাই দিচ্ছে। Refused এসেছে মানে নাম মিলেছিলই, তবু যাচাই করা ভালো: ভুল ঠিকানা হলে আপনি হয়তো অন্য server-এর দরজায় টোকা দিচ্ছেন।
- Route. Ping ফিরছে, পথ খোলা। না ফিরলেও এই ক্ষেত্রে ক্ষতি নেই, কারণ refused নিজেই প্রমাণ যে একটি উত্তর ফিরে এসেছে।
- Port. একই server-এ port 22 খোলা, 8080 refused. তাহলে যন্ত্রটি বেঁচে আছে, সমস্যা শুধু এই port-এ। এবার SSH দিয়ে server-এ ঢুকে ভেতর থেকে দেখতে হবে।
- Process. Service চলছে (পর্ব ১১)। অর্থাৎ “অ্যাপ বন্ধ” এই সন্দেহটি বাদ। অনেকেই এখানেই থেমে restart দেন, আর সমস্যা থেকে যায়।
- Bind ঠিকানা। আসল কারণ পাওয়া গেল: অ্যাপ শুনছে
127.0.0.1:8080-এ। Server-এর ভেতর থেকে চলবে, বাইরে থেকে kernel ফিরিয়ে দেবে। অ্যাপের কোনো নতুন সেটিংয়ে ডিফল্ট ঠিকানা বদলে গিয়েছিল। - Firewall. নিশ্চিত হলাম এটি firewall-এর দোষ নয়: ভেতরের
ufwআর বাইরের security group, দুটিই 8080 দিচ্ছে। Security group আটকালে লক্ষণ হতো timeout, refused নয়। - সমাধান আর যাচাই। অ্যাপের bind বদলে
0.0.0.0:8080করে restart দেওয়া হলো, আর বাইরে থেকে 200 OK এলো। আরও ভালো নকশা: অ্যাপ127.0.0.1-এই থাকুক, সামনে reverse proxy বসুক (পর্ব ১৪), আর 8080 বাইরে থেকে বন্ধ থাকুক।
৬ · curl -v আর সময়ের হিসাব — ধীর কোন ধাপ
curl একটি পুরো অনুরোধ করে, তাই এক কমান্ডেই সব স্তর পরীক্ষা হয়। -v দিলে প্রতিটি ধাপ বলে দেয়। প্রথম চিহ্নটি দেখে পড়ুন: * মানে curl-এর নিজের খবর, > মানে যা পাঠাল, < মানে যা পেল।
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ curl -v -o /dev/null https://example.com/
* Host example.com:443 was resolved.
* IPv4: 203.0.113.10
* Trying 203.0.113.10:443...
* Connected to example.com (203.0.113.10) port 443
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* Server certificate:
* subject: CN=example.com
* expire date: Dec 28 23:59:59 2026 GMT
> GET / HTTP/2
> Host: example.com
< HTTP/2 200
< content-type: text/html
কোন লাইন পর্যন্ত এসে থেমেছে, সেটিই আপনার স্তর। curl-এর exit code-ও স্তর বলে: 6 নাম মেলেনি, 7 সংযোগ হয়নি, 28 সময় শেষ, 35 TLS handshake ব্যর্থ, 60 certificate যাচাই ব্যর্থ। একটি দরকারি কৌশল হলো DNS এড়িয়ে নির্দিষ্ট একটি server পরীক্ষা করা:
# Send the request to one chosen server, keep the real host name for TLS and HTTP
curl -sv -o /dev/null --resolve example.com:443:203.0.113.20 https://example.com/কোন ধাপে সময় গেল
ব্যবহারকারী বলছেন “পাতা ধীর”। “ধীর” একটি অনুভূতি, মাপ নয়। curl-এর -w (write-out) অপশন প্রতিটি ধাপের ঘড়ি দেখায়:
curl -sS -o /dev/null -w \
'dns=%{time_namelookup} conn=%{time_connect} tls=%{time_appconnect} ttfb=%{time_starttransfer} total=%{time_total}\n' \
https://example.com/reportসবচেয়ে সাধারণ ভুল: এই সংখ্যাগুলো আলাদা আলাদা ধাপের সময় নয়। প্রতিটি মান শুরু থেকে জমা হিসাব, যেন একটি স্টপওয়াচ না থামিয়ে প্রতিটি স্টেশনে সময় টুকে রাখা। ধাপের সময় পেতে পরপর দুটি মান বিয়োগ করুন।
- DNSনাম খোঁজা
- TCPসংযোগ
- TLSপরিচয়
- Serverকাজ করছে
- Transferডেটা আসছে
| -w চলক | |
| ঘড়ি (জমা) | |
| বিয়োগ | |
| এই ধাপ |
- DNS, 12 ms. শুরু থেকে নাম পাওয়া পর্যন্ত। এটি প্রথম ধাপ, তাই ঘড়ির মানই ধাপের সময়। Resolver সুস্থ।
- TCP, 40 ms. ঘড়ি 52 ms-এ, তাই 52 − 12 = 40 ms. TCP handshake-এ প্রায় একটি RTT লাগে, তাই এটি client আর server-এর দূরত্বের ভালো মাপ।
- TLS, 79 ms. 131 − 52 = 79 ms. Handshake আর certificate যাচাই। স্বাভাবিক। শুধু
http://হলেtime_appconnect0 থাকে, তখন এই বিয়োগ করবেন না। - Server, 1817 ms. 1948 − 131 = 1817 ms. অনুরোধ পাঠানো থেকে প্রথম byte পর্যন্ত, একেই বলে TTFB-এর server অংশ। এখানে network-এর ভাগ প্রায় এক RTT, বাকিটা অ্যাপ, ডেটাবেস বা কোনো নির্ভরতা। সন্দেহের কেন্দ্র এখানেই।
- Transfer, 37 ms. 1985 − 1948 = 37 ms. উত্তরের বাকি অংশ নামানো। উত্তর ছোট, তাই দ্রুত।
- রায়। পাঁচটি ধাপ যোগ করলে 1985 ms, মোটের সাথে মিলেছে। মোট সময়ের 91% server-এর কাজে। তাই network বদলে বা বড় bandwidth কিনে লাভ নেই; অ্যাপের log আর ডেটাবেসের ধীর query দেখুন (পর্ব ৬৩ থেকে ৬৫-এর হাতিয়ার এই কাজেই)।
এবার একসাথে পাঁচটি অনুরোধ বিশ্লেষণ করি। লাইনগুলো হাতে লেখা নমুনা; script বিয়োগ করে সবচেয়ে ধীর ধাপটি খুঁজে দেয়।
set -euo pipefail
# Sample lines typed by hand. Every time is cumulative, counted from the start.
awk '
function ms(x) { return int(x * 1000 + 0.5) }
{
for (i = 2; i <= NF; i++) { split($i, kv, "="); t[kv[1]] = kv[2] }
ph["dns"] = ms(t["dns"])
ph["tcp"] = ms(t["conn"]) - ms(t["dns"])
ph["tls"] = ms(t["tls"]) - ms(t["conn"])
ph["wait"] = ms(t["ttfb"]) - ms(t["tls"])
ph["recv"] = ms(t["total"]) - ms(t["ttfb"])
slow = "dns"
split("tcp tls wait recv", names, " ")
for (i = 1; i <= 4; i++) if (ph[names[i]] > ph[slow]) slow = names[i]
printf "%-8s dns=%-5d tcp=%-5d tls=%-3d wait=%-5d recv=%-5d slow=%s (%d%%)\n", \
$1, ph["dns"], ph["tcp"], ph["tls"], ph["wait"], ph["recv"], slow, \
100 * ph[slow] / ms(t["total"])
}' <<'EOF'
/health dns=0.004 conn=0.044 tls=0.121 ttfb=0.162 total=0.165
/report dns=0.012 conn=0.052 tls=0.131 ttfb=1.948 total=1.985
/login dns=5.014 conn=5.054 tls=5.133 ttfb=5.190 total=5.194
/search dns=0.006 conn=3.047 tls=3.126 ttfb=3.171 total=3.176
/export dns=0.005 conn=0.045 tls=0.124 ttfb=0.180 total=6.180
EOFআউটপুট:
/health dns=4 tcp=40 tls=77 wait=41 recv=3 slow=tls (46%)
/report dns=12 tcp=40 tls=79 wait=1817 recv=37 slow=wait (91%)
/login dns=5014 tcp=40 tls=79 wait=57 recv=4 slow=dns (96%)
/search dns=6 tcp=3041 tls=79 wait=45 recv=5 slow=tcp (95%)
/export dns=5 tcp=40 tls=79 wait=56 recv=6000 slow=recv (97%)
পাঁচটি অনুরোধ, পাঁচটি আলাদা গল্প। /health সুস্থ; মোট সময় মাত্র 165 ms, তাই “সবচেয়ে ধীর” কথাটির এখানে কোনো মানে নেই। /report-এ server-এর কাজ ধীর। /login-এ প্রায় ঠিক 5 সেকেন্ড DNS-এ: resolver-এর একটি প্রশ্ন হারালে ডিফল্ট 5 সেকেন্ড পরে আবার চেষ্টার পরিচিত চিহ্ন। /search-এ TCP-তে প্রায় 3 সেকেন্ড: SYN হারিয়ে 1 আর 2 সেকেন্ড পরে দুবার আবার পাঠানোর চিহ্ন, মানে packet loss. /export-এ ডেটা নামাতে 6 সেকেন্ড: উত্তর বড়, বা পথ সরু। পাঁচটির সমাধান সম্পূর্ণ আলাদা, আর এক লাইন সংখ্যা ছাড়া তা জানার উপায় ছিল না।
৭ · TLS আর certificate — openssl s_client
HTTPS-এর সংযোগে TLS দুটি কাজ করে: লেখা গোপন রাখে, আর server-এর পরিচয় প্রমাণ করে। পরিচয়ের কাগজটির নাম certificate: কোন নামের জন্য, কে দিয়েছে, কতদিন বৈধ। জাতীয় পরিচয়পত্রের মতো, তবে মেয়াদ অনেক ছোট। Handshake-এর তত্ত্ব Computer Networks কোর্সে আছে। curl বলে “ব্যর্থ”; openssl s_client দেখায় server আসলে কী দেখাচ্ছে।
# What the server really presents: subject, issuer and dates
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -datesএখানে -servername হলো SNI: একই ঠিকানায় অনেক site থাকলে client জানায় কোন নামটি চায়। ভুল নাম দিলে অন্য certificate আসতে পারে। পুরো আউটপুটের Verify return code লাইনটিও পড়ুন: 0 (ok) মানে যাচাই সফল, 10 মেয়াদ শেষ, 21 সাধারণত certificate chain-এর মাঝের অংশ server পাঠায়নি। শেষেরটি ঠকায়, কারণ browser অনেক সময় নিজে মাঝের অংশ জোগাড় করে নেয়, অথচ curl বা অন্য অ্যাপ ব্যর্থ হয়।
এবার সবচেয়ে পরিচিত ঘটনাটি দেখি। ধরে নিই আজ ৩০ অক্টোবর ২০২৬। Monitoring alert জানাল, shop.example.com-এ HTTPS ভাঙা।
$ curl -sS https://shop.example.com/
curl: (60) SSL certificate problem:
certificate has expired
$ openssl s_client -connect shop.example.com:443 \
-servername shop.example.com </dev/null 2>/dev/null \
| openssl x509 -noout -dates
notBefore=Jul 30 00:00:00 2026 GMT
notAfter=Oct 28 23:59:59 2026 GMT
$ ... | openssl x509 -noout -subject -ext subjectAltName
subject=CN=shop.example.com
X509v3 Subject Alternative Name:
DNS:shop.example.com
$ cd /etc/ssl/shop $ sudo openssl x509 -in fullchain.pem -noout -enddate notAfter=Dec 28 23:59:59 2026 GMT ↑ ফাইলটি নতুন, কিন্তু server দেখাচ্ছে পুরোনোটি
$ sudo nginx -t nginx: configuration file /etc/nginx/nginx.conf test is successful $ sudo systemctl reload nginx
$ ... | openssl x509 -noout -enddate -checkend 2592000
notAfter=Dec 28 23:59:59 2026 GMT
Certificate will not expire
- লক্ষণ। Exit code 60 আর মেসেজ বলছে TCP ঠিক আছে, আটকেছে certificate যাচাইয়ে। তাই DNS, port বা firewall খোঁজার দরকার নেই।
-kদিয়ে যাচাই বন্ধ করে “চলছে” বলাও সমাধান নয়। - Server যা দেখাচ্ছে।
notAfter২৮ অক্টোবর, আর আজ ৩০ অক্টোবর। মেয়াদ শেষ, নিশ্চিত। সব সময় GMT-তে পড়ুন। এই certificate-এর মেয়াদ ছিল ৯০ দিন। - নাম মিলিয়ে দেখা। এখানে নাম ঠিক। আধুনিক client মেলায় Subject Alternative Name তালিকা, শুধু CN নয়। নাম না মিললে মেসেজ হতো
no alternative certificate subject name matches. - Disk-এর ফাইল। আসল সূত্র এখানে। স্বয়ংক্রিয় নবায়ন ঠিকই চলেছে; ফাইলের মেয়াদ ২৮ ডিসেম্বর পর্যন্ত। অথচ চলন্ত server পুরোনোটি দেখাচ্ছে। Nginx certificate পড়ে শুরু বা reload-এর সময়, পরে ফাইল বদলালে নিজে থেকে জানে না।
- সমাধান। আগে
nginx -tদিয়ে config পরীক্ষা, তারপরreload. Reload চলমান সংযোগ না কেটে নতুন ফাইল পড়ে। Restart দরকার নেই। - যাচাই আর প্রতিরোধ। বাইরে থেকে আবার দেখুন, কারণ মাঝে load balancer থাকলে certificate সেখানেও থাকতে পারে।
-checkend 2592000মানে 30 × 86400 সেকেন্ড, অর্থাৎ ৩০ দিনের মধ্যে শেষ হবে কি না। নবায়নের পরে স্বয়ংক্রিয় reload বসান, আর মেয়াদের ওপর alert রাখুন।
৮ · Packet চোখে দেখা আর firewall — tcpdump, ufw, nftables
সব কমান্ড ব্যর্থ হলে একটি প্রশ্নই বাকি থাকে: packet কি আদৌ আমার server-এ পৌঁছাচ্ছে? tcpdump এর সরাসরি উত্তর দেয়। একে বলে packet capture.
# উদাহরণ · নিজের server-এ, নমুনা আউটপুট; version-ভেদে আলাদা হতে পারে
$ sudo tcpdump -i eth0 -nn -c 2 'tcp port 8080'
10:15:01.120418 IP 198.51.100.7.51514 > 10.0.1.25.8080: Flags [S], seq 1001, win 64240, length 0
10:15:01.120466 IP 10.0.1.25.8080 > 198.51.100.7.51514: Flags [R.], seq 0, ack 1002, win 0, length 0
গন্তব্যে 10.0.1.25 দেখছেন, কারণ cloud public ঠিকানা অনুবাদ করে দিয়েছে। পড়ার নিয়ম হলো Flags ঘর: [S] সংযোগের অনুরোধ (SYN), [S.] তার উত্তর, [.] ACK, [P.] ডেটা, [R.] প্রত্যাখ্যান। তিনটি দৃশ্য মনে রাখুন:
| Server-এ যা দেখলেন | সিদ্ধান্ত | পরের জায়গা |
|---|---|---|
| কোনো SYN নেই | Packet server-এ পৌঁছায়নি | Security group, route table, public ঠিকানা |
| SYN আছে, উত্তর নেই | পৌঁছেছে, কিন্তু server-এর ভেতরে ফেলা হচ্ছে বা ফেরার পথ ভাঙা | লোকাল firewall, route |
SYN আছে, [R.] ফিরছে | পৌঁছেছে, কেউ শুনছে না | ss -tlnp, bind ঠিকানা |
দ্বিতীয় সারির কারণ একটি সূক্ষ্ম তথ্য: ingress পথে tcpdump সাধারণত লোকাল firewall-এর আগে packet দেখে। তাই “SYN দেখা গেল” মানে “অ্যাপে পৌঁছাল” নয়।
দায়িত্ব। Packet capture শুধু নিজের বা অনুমতি পাওয়া server-এ করুন। Capture-এ ব্যবহারকারীর ডেটা, cookie বা token থাকতে পারে, তাই -c দিয়ে সংখ্যা সীমিত রাখুন, filter ব্যবহার করুন, আর ফাইলে রাখলে কাজ শেষে মুছে ফেলুন। ব্যস্ত server-এ filter ছাড়া চালালে কাজের চাপও বাড়ে।
Firewall: দুই বেড়া
একটি cloud VM-এর সামনে সাধারণত দুটি বেড়া থাকে। বাইরেরটি হলো security group: এটি cloud-এর network-এ থাকে, VM-এর ভেতর থেকে দেখা যায় না (পর্ব ২৭)। ভেতরেরটি হলো Linux kernel-এর firewall, যা চালানো হয় nftables বা তার ওপরের সহজ মোড়ক ufw দিয়ে। বিস্তারিত Firewall আর VPN পর্বে।
# উদাহরণ · নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে
$ sudo ufw status verbose
Status: active
Default: deny (incoming), allow (outgoing), disabled (routed)
To Action From
-- ------ ----
22/tcp ALLOW IN 203.0.113.0/24
443/tcp ALLOW IN Anywhere
$ sudo nft list ruleset
table inet filter {
chain input {
type filter hook input priority filter; policy drop;
ct state established,related accept
iif "lo" accept
tcp dport { 22, 443 } accept
}
}
দুই ধরনের প্রত্যাখ্যানের পার্থক্য এখানে স্পষ্ট। policy drop বা DROP নিয়মে packet চুপচাপ ফেলা হয়, ফলে অন্য প্রান্তে timeout. REJECT নিয়মে firewall ফিরতি বার্তা পাঠায়, ফলে দ্রুত ব্যর্থতা।
নিজেকে বাইরে আটকে ফেলবেন না। দূরের server-এ ufw enable বা policy drop বসানোর আগে নিশ্চিত করুন SSH অনুমোদিত আছে। sudo ufw allow from 203.0.113.0/24 to any port 22 proto tcp এমন একটি নিয়ম। একটি SSH সংযোগ খোলা রেখে অন্য একটি নতুন সংযোগ দিয়ে পরীক্ষা করুন। আরেকটি ফাঁদ: Docker নিজের firewall নিয়ম লেখে, তাই publish করা container port অনেক ক্ষেত্রে ufw-এর নিয়ম এড়িয়ে যায় (পর্ব ৩৯)।
৯ · সব মিলিয়ে সিদ্ধান্তের গাছ
এতক্ষণের সব নিয়ম একটি সিদ্ধান্তের গাছে আনা যায়, যাকে দলের runbook-এও রাখতে পারেন। নিচের সিমুলেটরে প্রতিটি কেসে লক্ষণ দেওয়া আছে। গাছ প্রশ্ন ধরে এগোয়, আর শেষে পরের কমান্ড আর সম্ভাব্য কারণ বলে। নিজের কেস যোগ করে আবার চালান, যেমন { dns: "ok", connect: "ok", tls: "ok", http: 502 }.
const leaf = (cmd, cause) => ({ cmd, cause });
const tree = { q: "dns",
nxdomain: leaf("dig example.com NS +short", "record missing, or wrong zone/name"),
servfail: leaf("dig +trace example.com", "broken delegation or name server down"),
ok: { q: "connect",
refused: { q: "listening",
no: leaf("systemctl status app; journalctl -u app -n 50", "process not running"),
loopback: leaf("ss -tlnp; check the app bind setting", "app bound to 127.0.0.1 only"),
all: leaf("nft list ruleset; ufw status verbose", "firewall REJECT rule or wrong host") },
timeout: { q: "synSeen",
no: leaf("check security group, route table, public IP", "dropped before the server"),
yes: leaf("nft list ruleset; ip route", "local firewall DROP or broken reply path") },
ok: { q: "tls",
expired: leaf("openssl x509 -noout -enddate", "expired, or old certificate still served"),
mismatch: leaf("openssl x509 -noout -ext subjectAltName", "wrong certificate for this name"),
ok: { q: "http",
502: leaf("tail nginx error.log; ss -tlnp", "upstream refused or sent a bad reply"),
504: leaf("tail nginx error.log; check app and DB", "upstream too slow: read timeout"),
200: { q: "slowPhase",
dns: leaf("resolvectl status", "slow or failing resolver"),
wait: leaf("app logs, DB slow query log", "server work: app, DB, dependency") } } } } };
function diagnose(s) {
let node = tree; const path = [];
while (node.q) { path.push(node.q + "=" + s[node.q]); node = node[s[node.q]]; }
return { path: path.join(" > "), ...node };
}
for (const s of [
{ dns: "ok", connect: "refused", listening: "loopback" },
{ dns: "ok", connect: "timeout", synSeen: "no" },
{ dns: "ok", connect: "ok", tls: "expired" },
{ dns: "ok", connect: "ok", tls: "ok", http: 504 },
{ dns: "ok", connect: "ok", tls: "ok", http: 200, slowPhase: "wait" },
]) {
const r = diagnose(s); console.log(r.path + "\n next : " + r.cmd + "\n cause: " + r.cause);
}আউটপুট:
dns=ok > connect=refused > listening=loopback
next : ss -tlnp; check the app bind setting
cause: app bound to 127.0.0.1 only
dns=ok > connect=timeout > synSeen=no
next : check security group, route table, public IP
cause: dropped before the server
dns=ok > connect=ok > tls=expired
next : openssl x509 -noout -enddate
cause: expired, or old certificate still served
dns=ok > connect=ok > tls=ok > http=504
next : tail nginx error.log; check app and DB
cause: upstream too slow: read timeout
dns=ok > connect=ok > tls=ok > http=200 > slowPhase=wait
next : app logs, DB slow query log
cause: server work: app, DB, dependency
প্রতিটি লাইনের > চিহ্ন গাছের একটি শাখা। লক্ষ করুন, গাছ DNS ঠিক না হলে port নিয়ে প্রশ্নই করে না। এটিই স্তর ধরে খোঁজার মূল কথা: আগের স্তর পরিষ্কার না হলে পরের স্তরের ফল অর্থহীন। Script-এর কারণগুলো “সম্ভাব্য”, প্রমাণ নয়; পরের কমান্ডের ফলই প্রমাণ।
আরও গভীরে: TCP-র RST আর SYN retransmission-এর আচরণ এখন RFC 9293 (২০২২)-এ সংজ্ঞায়িত, যা RFC 793 (১৯৮১)-এর জায়গা নিয়েছে। ss তথ্য আনে kernel-এর netlink sock_diag ইন্টারফেস থেকে, আর ss -ti প্রতিটি সংযোগের RTT, congestion window আর retransmit সংখ্যা দেখায়, যা ধীর সংযোগে খুব কাজের। Kubernetes-এর মতো পরিবেশে একই পদ্ধতি চলে, শুধু namespace-এর ভেতর থেকে চালাতে হয় (পর্ব ৪৫)।
পরীক্ষা ও ইন্টারভিউতে সাধারণত যে ধরনের প্রশ্ন আসে:
- Refused আর timeout-এর পার্থক্য? Refused-এ উত্তর আসে (RST), কেউ শুনছে না; timeout-এ উত্তর আসে না, সাধারণত DROP বা পথ নেই।
- 502 আর 504-এর পার্থক্য? 502: upstream অচল উত্তর দিয়েছে বা সংযোগ নেয়নি। 504: upstream সময়মতো উত্তর দেয়নি।
- Site-এ ঢুকতে না পারলে প্রথম কী করবেন? লক্ষণ নিশ্চিত করে স্তর ধরে এগোবেন: DNS, পথ, port, TLS, HTTP.
- একটি port কে ব্যবহার করছে কীভাবে জানবেন?
sudo ss -tlnp; Process ঘরে নাম আর pid পাবেন। - 0.0.0.0 আর 127.0.0.1-এ bind করার পার্থক্য? প্রথমটি সব IPv4 interface-এ, দ্বিতীয়টি শুধু server-এর ভেতর থেকে।
১০ · AI-এর যুগে network সমস্যা খোঁজা
AI আউটপুট পড়তে খুব ভালো সাহায্য করে। কিন্তু সে আপনার server দেখতে পায় না, আর তাড়াহুড়োর মধ্যে “কাজ চালানোর” পরামর্শ দিতে ভালোবাসে। Network-এর ক্ষেত্রে সেই পরামর্শ প্রায়ই নিরাপত্তা ভেঙে দেয়।
| AI-এর পরামর্শ | ঝুঁকি | যা করবেন |
|---|---|---|
ufw disable বা সব নিয়ম মুছে দেখা | Server পুরো খোলা, অথবা নিয়ম মুছতে গিয়ে SSH বন্ধ | tcpdump দিয়ে আগে জানুন packet কোথায় থামছে |
Security group-এ 0.0.0.0/0, সব port | সারা ইন্টারনেট থেকে খোলা | শুধু দরকারি port, দরকারি উৎস |
curl -k দিয়ে “ঠিক হয়ে গেছে” | Certificate যাচাই বন্ধ, লক্ষণ লুকানো | মেয়াদ, নাম আর chain যাচাই করুন |
ডেটাবেসকে 0.0.0.0-এ bind | ডেটাবেস বাইরের নাগালে আসার ঝুঁকি | Private ঠিকানা আর সীমিত firewall |
| বানানো flag বা পুরোনো কমান্ড | Error, অথবা ভিন্ন কাজ | man পাতা বা official docs দেখুন |
| Refused-কে firewall-এর দোষ বলা | ভুল জায়গায় সময় নষ্ট | আগে ss -tlnp দেখুন |
AI-কে আউটপুট দেওয়ার আগে token, cookie, password আর আসল ঠিকানা মুছে ফেলুন। তারপর নিচের কাঠামোয় প্রশ্ন করুন। শেষ তিনটি লাইনই আসল: এগুলো AI-কে অনুমান থামিয়ে প্রমাণ চাইতে বাধ্য করে।
AI-এর দেওয়া সমাধান হাতে পেলে
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।
প্র ০১Firewall চুপচাপ ফেলে দেবে (DROP), নাকি জানিয়ে দেবে (REJECT)? কোনটি ভালো?
TCP-র নকশায় “এখানে কেউ নেই” বলার ব্যবস্থা শুরু থেকেই ছিল। ১৯৮১ সালের RFC 793-এ RST packet-এর নিয়ম লেখা হয়, আর ২০২২ সালে RFC 9293 সেই নথির জায়গা নেয়। ICMP-তেও গন্তব্যে পৌঁছানো না গেলে বার্তা পাঠানোর ব্যবস্থা আছে। অর্থাৎ নকশাকারীরা চেয়েছিলেন ব্যর্থতা দ্রুত জানা যাক। পরে firewall এলে একটি নতুন প্রশ্ন ওঠে: অচেনা কাউকে উত্তর দেওয়াই কি উচিত?
- DROP-এর পক্ষে: উত্তর না দিলে বাইরের স্ক্যানার কম তথ্য পায়, আর উত্তর পাঠানোর খরচও বাঁচে। বড় স্ক্যানের সময় হাজার হাজার ফিরতি packet পাঠানো বিরক্তিকর বোঝা। অনেক cloud security group এজন্যই নীরবে ফেলে দেয়।
- DROP-এর দাম: বৈধ ব্যবহারকারী বা আপনার নিজের অ্যাপ অপেক্ষায় থাকে। Linux-এর ডিফল্টে সংযোগের চেষ্টা প্রায় ২ মিনিট চলতে পারে। দুটি service-এর মাঝে এমন নীরবতা থাকলে thread আটকে যায়, আর একটি ছোট ভুল সিস্টেমজুড়ে ধীরগতি ছড়ায়।
- REJECT-এর পক্ষে: ভেতরের network-এ দ্রুত ব্যর্থতা ভালো। অ্যাপ সাথে সাথে জেনে retry বা অন্য পথ নিতে পারে। Debug করাও সহজ।
তাই একটি সাধারণ, যদিও সর্বজনীন নয়, অনুশীলন হলো: ইন্টারনেটের দিকে DROP, আর নিজের নিয়ন্ত্রিত ভেতরের network-এ দরকার মতো REJECT. এটি নিরাপত্তার মূল প্রতিরক্ষাও নয়; দরজা লুকানো আর দরজা শক্ত করা আলাদা কথা। স্ক্যানার DROP দেখেও বুঝে নেয় একটি firewall আছে। আসল সুরক্ষা হলো শুধু দরকারি port খোলা, আর সেই service-গুলো হালনাগাদ রাখা।
মূল উপলব্ধি: নিরাপত্তার প্রতিটি সিদ্ধান্তের একটি পরিচালনার দাম আছে। “নীরবতা” বাইরের লোককে কম জানায়, কিন্তু আপনার দলকেও কম জানায়। তাই সিদ্ধান্ত নিন কে দেখছে তার ওপর ভিত্তি করে।
প্র ০২একটি সাধারণ certificate-এর মেয়াদ শেষ হলে বড় প্রতিষ্ঠানও কেন অচল হয়ে যায়?
মেয়াদ শেষ হওয়া এমন ব্যর্থতা, যা একটি নির্দিষ্ট মুহূর্তে একসাথে আসে, আর যার আগে কোনো লক্ষণ থাকে না। আগের দিন পর্যন্ত সব নিখুঁত। প্রকাশিত ঘটনায় এর বড় উদাহরণ আছে। ডিসেম্বর ২০১৮-তে Ericsson জানায়, তাদের কিছু core network software-এ মেয়াদোত্তীর্ণ certificate-এর কারণে যুক্তরাজ্যের O2-সহ কয়েকটি দেশের মোবাইল সেবা ব্যাহত হয়। ফেব্রুয়ারি ২০২০-তে Microsoft স্বীকার করে, একটি authentication certificate-এর মেয়াদ শেষ হওয়ায় Teams কয়েক ঘণ্টা বিঘ্নিত হয়েছিল।
এত অদ্ভুত কেন? কারণ certificate থাকে ফাঁকের জায়গায়। ভেতরের service-এর মাঝে, load balancer-এ, পুরোনো সিস্টেমে, যাঁদের দায়িত্ব কারও স্পষ্ট নয়। যে কর্মী বছর দুয়েক আগে সেটি বসিয়েছিলেন, তিনি হয়তো দল ছেড়েছেন। ক্যালেন্ডারে লেখা reminder মানুষের ওপর নির্ভর করে, আর মানুষ ভোলে।
শিল্পের উত্তর উল্টো দিকে গেছে: মেয়াদ বাড়ানো নয়, কমানো। ACME protocol (RFC 8555, ২০১৯) আর Let's Encrypt-এর মতো সেবা নবায়ন স্বয়ংক্রিয় করেছে, আর তাদের প্রচলিত ৯০ দিনের মেয়াদ হাতে নবায়ন প্রায় অসম্ভব করে দেয়, যা ইচ্ছাকৃত। CA/Browser Forum-এর ২০২৫ সালের সিদ্ধান্তে public TLS certificate-এর সর্বোচ্চ মেয়াদ ধাপে ধাপে কমিয়ে ২০২৯ সালের মধ্যে ৪৭ দিনে আনার পরিকল্পনা আছে। Let's Encrypt-ও নিজের ডিফল্ট মেয়াদ ২০২৮ সালের মধ্যে ৪৫ দিনে আনার পরিকল্পনা জানিয়েছে। সময়সূচি বদলাতে পারে, তাই বর্তমান নিয়ম দেখে নিন। যুক্তিটি সহজ: যে কাজ ঘন ঘন করতে হয়, মানুষ তা স্বয়ংক্রিয় করেই।
কিন্তু স্বয়ংক্রিয় করার পরও এই পর্বের ফাঁদটি থাকে: ফাইল নবায়ন হলো, service তা পড়ল না। তাই পর্যবেক্ষণ করতে হবে বাইরে থেকে দেখা certificate-এর মেয়াদ, disk-এর ফাইল নয়।
মূল উপলব্ধি: ভবিষ্যতের কোনো নির্দিষ্ট তারিখে নিশ্চিত ঘটবে এমন ব্যর্থতা হলো সবচেয়ে প্রতিরোধযোগ্য ব্যর্থতা। তবু তা ঘটে, কারণ কোনো একজনের নামে দায়িত্ব লেখা থাকে না। স্বয়ংক্রিয়তা, বাইরে থেকে পর্যবেক্ষণ আর স্পষ্ট মালিকানা, তিনটিই লাগে।
প্র ০৩অভিজ্ঞ প্রকৌশলীরা মজা করে বলেন “সবসময়ই DNS”. DNS কেন এত ঘনঘন দায়ী?
কথাটি মজা, কিন্তু কারণ আসল। DNS প্রায় প্রতিটি সংযোগের প্রথম ধাপ, তাই এটি ভাঙলে সবকিছু একসাথে ভাঙে। Service আর database-ও একে অপরকে নাম দিয়ে খোঁজে। ফলে DNS-এর একটি সমস্যা দেখতে লাগে “সব ভেঙে গেছে”-এর মতো।
এর সবচেয়ে ঠকানো স্বভাব হলো cache. একটি উত্তর TTL-এর জন্য resolver-এ জমা থাকে। “নাম নেই” উত্তরটিও জমা থাকে (RFC 2308, ১৯৯৮)। ফলে আপনি record বসিয়ে ঠিক করলেন, কিন্তু আগে যে জিজ্ঞেস করেছিল সে আরও কিছুক্ষণ “নেই” শোনে। একই মুহূর্তে একজনের জন্য site চলছে, অন্যজনের জন্য চলছে না। এরকম আংশিক সমস্যা খোঁজা কঠিন।
আরও স্তর আছে: /etc/hosts, লোকাল stub resolver, প্রতিষ্ঠানের resolver, ISP-র resolver, আর authoritative server. ভেতরের আর বাইরের জন্য একই নামের আলাদা উত্তরও থাকতে পারে (split-horizon). তাই “আমার কাছে তো চলছে” কথাটি DNS-এ প্রমাণ হিসেবে দুর্বল।
একটি বিখ্যাত প্রকাশিত ঘটনা হলো অক্টোবর ২০২১-এর Facebook বিভ্রাট। প্রতিষ্ঠানটির প্রকৌশল-লেখা অনুযায়ী backbone network-এ একটি ভুল পরিবর্তনের পর তাদের DNS server নিজেদের BGP ঘোষণা তুলে নেয়, ফলে বাইরের দুনিয়া নামই খুঁজে পাচ্ছিল না। লক্ষণ ছিল DNS, মূল কারণ network. এখানে একটি বড় শিক্ষা আছে: যে স্তরে লক্ষণ দেখা গেল, মূল কারণ সবসময় সেই স্তরে নয়।
ব্যবহারিক অভ্যাস তিনটি: একাধিক resolver থেকে তুলনা, dig +trace দিয়ে শিকড় থেকে পথ দেখা, আর পরিবর্তনের আগে TTL কমিয়ে রাখা (পর্ব ২৯)।
মূল উপলব্ধি: DNS একটি বিতরণ করা, cache-ভরা ব্যবস্থা। এতে “সত্য” এক জায়গায় থাকে না, প্রতিটি দর্শকের কাছে আলাদা হতে পারে। তাই আপনার প্রশ্ন হওয়া উচিত “কার কাছে, কখন, কোন resolver থেকে?”
প্র ০৪traceroute কীভাবে কাজ করে, আর এর আউটপুট কেন প্রায়ই ভুল পথে নিয়ে যায়?
ping ১৯৮৩ সালে লেখেন Mike Muuss, আর traceroute ১৯৮৮ সালের দিকে Van Jacobson. দ্বিতীয়টির কৌশলটি চমৎকার। প্রতিটি IP packet-এ একটি TTL ঘর থাকে; প্রতিটি router সেটি এক কমায়, আর শূন্য হলে packet ফেলে দিয়ে প্রেরককে ICMP “Time Exceeded” বার্তা পাঠায়। Traceroute ইচ্ছা করে TTL 1, তারপর 2, তারপর 3 দিয়ে packet পাঠায়। প্রতিটি মোড়ের router নিজের ঠিকানা জানিয়ে দেয়। যে সুবিধা অন্য কাজের জন্য বানানো, তা দিয়ে পথের মানচিত্র আঁকা হলো।
ভুল বোঝার কারণ চারটি:
- উত্তর দেওয়া router-এর ঐচ্ছিক কাজ। Router-এর আসল কাজ packet পাঠানো। নিজের সম্পর্কে ICMP বানানো কম অগ্রাধিকারের, আর প্রায়ই সীমিত। তাই মাঝের হপে ক্ষতি দেখা গেলেও পরের হপে ক্ষতি না থাকলে সেটি আসল সমস্যা নয়। এজন্য
mtr-এ শেষ হপ থেকে পড়তে হয়। * * *মানে ভাঙা নয়। সেই router হয়তো উত্তর দিতে চায় না। পরের হপ উত্তর দিলে পথ ঠিকই আছে।- পথ একমুখী। ইন্টারনেটে যাওয়া আর ফেরার পথ আলাদা হতে পারে। Traceroute দেখায় শুধু যাওয়ার পথ, অথচ সময় মাপে পুরো যাওয়া-আসায়।
- বহু পথ। ভারসাম্যের জন্য router একই গন্তব্যের packet আলাদা পথে পাঠাতে পারে। আর ডিফল্ট packet firewall-এ HTTPS-এর মতো আচরণ না-ও পেতে পারে; তাই
-T -p 443কাজে লাগে।
Cloud-এ আরেকটি স্তর যোগ হয়। VPC-র ভেতরের network ভার্চুয়াল, তাই আসল physical hop অনেক সময় দেখাই যায় না (Cloud আর container networking).
তাই traceroute-এর একটি ফল দেখে কোনো ISP বা router-কে দোষ দেওয়ার আগে একাধিক দিক থেকে, একাধিক সময়ে মেপে নিন।
মূল উপলব্ধি: প্রতিটি হাতিয়ার একটি পরোক্ষ মাপ। আউটপুট কী দেখায় তার সাথে জানতে হয় সেটি কীভাবে তৈরি হয়। পদ্ধতি না জানলে সঠিক সংখ্যা থেকেও ভুল সিদ্ধান্ত আসে।
প্র ০৫ডেটাবেস আর cache-এর ডিফল্ট bind ঠিকানা কেন নিরাপত্তার বড় প্রশ্ন হয়ে উঠল?
একটি ডিফল্ট সেটিং হাজার হাজার server-এর ভাগ্য ঠিক করে দেয়, কারণ বেশিরভাগ মানুষ ডিফল্ট বদলান না। MongoDB-র পুরোনো কিছু সংস্করণ ডিফল্টে সব interface-এ শুনত, আর authentication-ও বাধ্যতামূলক ছিল না। ২০১৭ সালের শুরুতে নিরাপত্তা গবেষকেরা জানান, ইন্টারনেটে খোলা বিপুলসংখ্যক MongoDB ডেটাবেসের তথ্য মুছে মুক্তিপণ চাওয়া হচ্ছে। Redis-এর ক্ষেত্রেও খোলা instance নিয়ে সমস্যা হয়েছিল, আর ২০১৬ সালের ৩.২ সংস্করণে আসে protected mode: bind ঠিকানা বা password ঠিক না করলে বাইরের সংযোগ আটকায়। পরে অনেক সফটওয়্যার ডিফল্ট 127.0.0.1 করেছে।
এখান থেকে একটি নকশার নীতি আসে: secure by default. নিরাপদ ডিফল্টে প্রথম দিনের অভিজ্ঞতা একটু খারাপ হয়: নতুন ব্যবহারকারী বাইরে থেকে সংযোগ পান না, আর এই পর্বের refused-এর গল্পটি দেখেন। কিন্তু একটি refused বিরক্তিকর, আর একটি খোলা ডেটাবেস ভয়াবহ। দুটি ভুলের দাম সমান নয়, তাই ডিফল্ট কম দামি ভুলের দিকে থাকা উচিত।
তবে bind একমাত্র প্রতিরক্ষা নয়। ভালো নকশায় কয়েকটি স্তর থাকে:
- ডেটাবেস থাকে private subnet-এ, যার public ঠিকানাই নেই (পর্ব ২৫)।
- Security group শুধু অ্যাপের server থেকে অনুমতি দেয় (পর্ব ২৭)।
- Bind শুধু private ঠিকানায়, সাথে authentication আর TLS.
- নিয়মিত বাইরে থেকে নিজের ঠিকানা স্ক্যান, আর এই পর্বের মতো একটি allow-list পরীক্ষা।
Container-এ গল্পটি উল্টে যেতে পারে: container-এর ভেতরে 127.0.0.1-এ bind করা অ্যাপে publish করা port দিয়ে পৌঁছানো যায় না। তাই সেখানে ভেতরে 0.0.0.0 স্বাভাবিক, আর নিয়ন্ত্রণ আসে port publish থেকে (পর্ব ৩৯)।
মূল উপলব্ধি: “কে আমাকে পৌঁছাতে পারে?” প্রশ্নটির উত্তর কোনো একটি সেটিংয়ে থাকে না। Bind ঠিকানা, firewall, subnet আর authentication একসাথে এর উত্তর দেয়, আর একটি ভুল হলে বাকিগুলো যেন বাঁচাতে পারে, নকশা এমন হওয়া উচিত।
অনুশীলন
প্রথমে নিজে করুন, তারপর উত্তর মিলিয়ে দেখুন। কোনো কাজের জন্য cloud account লাগবে না।
-
সময়ের হিসাব: একটি অনুরোধের
curl -wমান:namelookup=0.020,connect=0.070,appconnect=0.190,starttransfer=0.950,total=1.250. পাঁচটি ধাপের সময় আর সবচেয়ে ধীর ধাপটির শতাংশ বের করুন। কোথায় তদন্ত করবেন?মানগুলো জমা হিসাব, তাই বিয়োগ করুন। DNS = 20 ms. TCP = 70 − 20 = 50 ms. TLS = 190 − 70 = 120 ms. Server = 950 − 190 = 760 ms. Transfer = 1250 − 950 = 300 ms. যোগফল 20 + 50 + 120 + 760 + 300 = 1250 ms, মোটের সাথে মিলেছে।
সবচেয়ে ধীর server অংশ: 760 ÷ 1250 = 0.608, মানে 60.8%. তদন্ত শুরু হবে অ্যাপের log আর ডেটাবেসের query-তে। তবে transfer-এর 300 ms-ও অবহেলার নয়; উত্তরের আকার বড় হলে compression বা CDN ভাবা যায়।
-
ফল আগে বলুন: একটি server-এ
ss -tlnpদেখাচ্ছে অ্যাপ127.0.0.1:3000-এ listen করছে। Server-এর ঠিকানা10.0.1.25. Security group-এ port 3000 খোলা নেই, আর সে নীরবে ফেলে দেয়। নিচের প্রতিটিতে কী হবে? (ক) Server-এর ভেতর থেকেcurl 127.0.0.1:3000. (খ) Server-এর ভেতর থেকেcurl 10.0.1.25:3000. (গ) ল্যাপটপ থেকে port 3000-এnc. (ঘ) এবার অ্যাপকে0.0.0.0:3000-এ bind করলে (গ)-এর ফল।(ক) সফল, কারণ loopback-এ অ্যাপ শুনছে। (খ) Connection refused. একই যন্ত্র হলেও গন্তব্য ঠিকানা
10.0.1.25, আর সেখানে কেউ শুনছে না। (গ) Timeout, কারণ security group packet-কে server পর্যন্ত পৌঁছাতেই দেয় না। (ঘ) এখনো timeout. Bind ঠিক হলেও বাইরের বেড়া বদলায়নি। শিক্ষা: Refused আসতে হলে packet-কে আগে পৌঁছাতে হয়। -
Runbook সমালোচনা: একজন সহকর্মী লিখেছেন: “Site down হলে: ১. server reboot করুন। ২. না হলে
ufw disableকরুন। ৩. security group-এ সব port0.0.0.0/0খুলে দিন। ৪. তবু না হলে AI-কে জিজ্ঞেস করুন।” কী কী সমস্যা আছে? ভালো করে আবার লিখুন।সমস্যা: Reboot সব প্রমাণ মুছে দেয়, আর চলমান সংযোগ কাটে। কারণ জানা যায় না, তাই ঘটনা ফিরবে।
ufw disableআর সব port খোলা হলো নিরাপত্তা ভাঙা; সমস্যা না মিটলে ঝুঁকিটিই থেকে যায়, কেউ বন্ধ করতে ভুলে যায়। কোথাও লক্ষণ নথি করার কথা নেই। AI একদম শেষে, আর প্রমাণ ছাড়া।ভালো runbook: ১. লক্ষণ লিখুন: কে, কখন, কোন মেসেজ, কতক্ষণে। ২. বাইরে থেকে
dig,nc,curl -v. ৩. ভেতর থেকেss -tlnp, লোকালcurl, service-এর অবস্থা আর log. ৪. TLS সমস্যায়openssl s_client. ৫. Packet না মিললে সীমিতtcpdump. ৬. একবারে একটি পরিবর্তন, ফেরার পথ ঠিক রেখে। ৭. বাইরে থেকে যাচাই, আর কারণ নথি করা (পর্ব ৬৭)। -
কমান্ড লিখুন:
example.com-এর server যে certificate দেখাচ্ছে, তা আগামী ১৪ দিনের মধ্যে শেষ হবে কি না জানার একটি কমান্ড লিখুন। script-এ ব্যবহার করতে হলে ফল কীভাবে পড়বেন?১৪ দিন = 14 × 86400 = 1209600 সেকেন্ড।
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \ | openssl x509 -noout -checkend 1209600মেয়াদ বাকি থাকলে exit code 0 আর লেখা
Certificate will not expire; শেষ হতে চললে exit code 1 আরCertificate will expire. Script-এifদিয়ে এই exit code দেখে alert পাঠানো যায়, আর পাইপ থাকায়set -o pipefailরাখা ভালো।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমএকটি site-এর সমস্যা খোঁজার যাচাইগুলো অনুরোধের পথের ক্রমে সাজান (▲▼ চেপে সরান)
dig— নাম থেকে ঠিকানা মিলছে কি নাmtr— ঠিকানা পর্যন্ত পথ আছে কি নাnc -vz— Port-এ TCP সংযোগ হচ্ছে কি নাopenssl s_client— Certificate ঠিক আছে কি নাcurl -v— HTTP উত্তর আর status code কী- অ্যাপের log — অ্যাপ ভেতরে কী করল
বাইরে থেকে port 8080-এ সাথে সাথে Connection refused আসছে। Server-এ ss -tlnp দেখাচ্ছে অ্যাপ 127.0.0.1:8080-এ listen করছে। সবচেয়ে সম্ভাব্য কারণ কী?
- Security group port 8080 আটকে রেখেছে
- অ্যাপ শুধু loopback ঠিকানায় bind করেছে
- DNS record ভুল আছে
- অ্যাপের process বন্ধ হয়ে গেছে
nc অনেকক্ষণ অপেক্ষার পর timeout দিচ্ছে। Server-এর tcpdump-এ সেই port-এর কোনো SYN দেখা যাচ্ছে না। পরের জায়গা কোনটি?
- অ্যাপের bind ঠিকানা
- TLS certificate
- Security group, route table আর public ঠিকানা
- অ্যাপের ডেটাবেস query
একটি curl -w আউটপুটে time_connect=0.050 আর time_appconnect=0.130. TLS ধাপে কত সময় লেগেছে?
- 80 ms
- 130 ms
- 50 ms
- 180 ms
Nginx-এর error log-এ লেখা: connect() failed (111: Connection refused) while connecting to upstream. ব্যবহারকারী সাধারণত কোন status দেখবেন, আর কেন?
- 504, কারণ upstream ধীর
- 404, কারণ পাতা নেই
- 500, কারণ nginx-এর config ভুল
- 502, কারণ পেছনের অ্যাপ সংযোগ নিচ্ছে না
একজন ডেভেলপার server-এর /etc/hosts-এ একটি নাম যোগ করলেন। অ্যাপ নতুন ঠিকানায় যাচ্ছে, অথচ dig পুরোনো ঠিকানা দেখাচ্ছে। কেন?
- TTL এখনো শেষ হয়নি বলে
- dig সরাসরি DNS-কে জিজ্ঞেস করে, /etc/hosts পড়ে না
- Server reboot করা হয়নি বলে
- dig-এর version পুরোনো বলে
Server-এর disk-এ certificate ফাইলের মেয়াদ দুই মাস বাকি, অথচ বাইরে থেকে openssl s_client দেখাচ্ছে মেয়াদ শেষ। সবচেয়ে সম্ভাব্য কারণ কী?
- Laptop-এর ঘড়ি ভুল
- TLS version পুরোনো
- Server পুরোনো certificate ধরে আছে, reload হয়নি, বা সামনে অন্য TLS প্রান্ত আছে
- Private key-র মেয়াদ শেষ
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- অনুরোধের ক্রমেই খুঁজুন: নাম → পথ → port → TLS → HTTP; ভেতর আর বাইরে, দুই দিক থেকে মিলিয়ে দেখুন।
- Refused মানে পৌঁছেছে কিন্তু কেউ শুনছে না; timeout মানে সাড়া নেই, সাধারণত firewall বা পথ; 502 অ্যাপ সংযোগ নেয়নি বা অচল উত্তর, 504 অ্যাপ দেরি করেছে।
ss -tlnp-এর Local Address দেখুন:127.0.0.1শুধু ভেতর থেকে,0.0.0.0সব interface থেকে।curl -w-এর সময় জমা হিসাব; বিয়োগ করে ধাপের সময় বের করুন।- Certificate-এ বাইরে থেকে দেখা মেয়াদই সত্য; নবায়নের পরে reload নিশ্চিত করুন। Firewall বন্ধ না করে
tcpdumpদিয়ে packet খুঁজুন।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ১৪ · Nginx আর reverse proxy — virtual host, TLS আর প্রথম deploymentপরবর্তী পর্বঅ্যাপকে
127.0.0.1-এ রেখে নিরাপদে বাইরে আনা। - ক্লাউড কম্পিউটিং ও DevOps · কোর্স হোম৮১টি পর্বপুরো কোর্সের রোডম্যাপ।
- সমস্যা খোঁজা — tcpdump, Wireshark আর পদ্ধতিগত তদন্তগভীরে যানPacket capture আর পদ্ধতিগত তদন্তের বিস্তারিত।
- Linux-এ নেটওয়ার্ক দেখা — ip, ping, ss, curl আর /proc/netগভীরে যানএই হাতিয়ারগুলোর পেছনের তত্ত্ব।
- TLS আর HTTPS — handshake, certificate আর বিশ্বাসের শিকলপাশের ট্র্যাকCertificate কীভাবে বিশ্বাস তৈরি করে।