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

DNS — নাম থেকে ঠিকানা, resolver আর caching

DNS — Namespace, Resolvers, Iterative Resolution Step by Step, Caching & TTL, Records, Message Bytes, Reverse DNS & Security

Taught in Bangla, this lesson explains DNS as a distributed phonebook: the namespace and delegation, stub and recursive resolvers, iterative resolution from root to TLD to authoritative servers step by step, caching, TTL and negative caching, record types such as A, AAAA, CNAME, MX and NS, DNS message bytes, reverse DNS, and DNS security threats and defences.

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

  • নামের গাছ — root, TLD (gTLD, ccTLD যেমন .bd), domain, zone আর delegation — আর কোন সার্ভার কোন কাজ করে
  • www.example.com-এর iterative resolution বার্তা ধরে ধরে, recursive-এর সাথে তুলনা, আর বার্তা ও সময় গোনার পরীক্ষার হিসাব
  • প্রতিটি স্তরে caching আর TTL, negative caching, আর একটি resolver simulator-এ cache hit, miss ও মেয়াদ ফুরানো
  • প্রধান record-এর ধরন, SOA-র সংখ্যাগুলো, glue, reverse DNS-এর নাম বানানো, আর DNS বার্তার প্রতিটি বাইট — compression pointer-সহ
  • Linux-এ নাম খোঁজার ক্রম (/etc/hosts, nsswitch.conf, resolv.conf), DNS-এর নিরাপত্তা ও গোপনীয়তা, আর NXDOMAIN, SERVFAIL ও timeout আলাদা করে চেনা

১ · নাম মানুষের জন্য, ঠিকানা যন্ত্রের জন্য — আর HOSTS.TXT থেকে DNS

পর্ব ১৬ আর ২১-এ দেখেছেন, ইন্টারনেটে প্রতিটি packet যায় IP ঠিকানা ধরে — 192.0.2.80 বা 2001:db8::80. কিন্তু কেউ ব্রাউজারে সংখ্যা লেখেন না; লেখেন www.example.com. নাম আর ঠিকানা আলাদা রাখার তিনটি বড় কারণ আছে:

  • মনে রাখা: মানুষ শব্দ মনে রাখে, ১২৮ bit-এর IPv6 ঠিকানা নয়।
  • বদলানোর স্বাধীনতা: একটি ওয়েবসাইট অন্য hosting-এ সরলে ঠিকানা বদলায়, নাম একই থাকে। ঠিক যেমন কেউ বাসা বদলালেও তাঁর নাম বদলায় না।
  • একাধিক ঠিকানা: একটি নামের পেছনে অনেক সার্ভার থাকতে পারে — কাছেরটি বা সুস্থটি বেছে দেওয়া যায় (অংশ ৯)।

নাম থেকে ঠিকানা বের করার ব্যবস্থার নাম DNS (Domain Name System). এটি একটি application layer protocol (পর্ব ৩৪-এর application layer-এর client-server ধাঁচে), কিন্তু প্রায় সব অ্যাপ্লিকেশন কাজ শুরুর আগে এর ওপর নির্ভর করে — HTTP, ইমেইল, ভিডিও কল, সবাই।

ভাবুন ঢাকার একটি বড় অফিসের রিসেপশন। আপনি বললেন “হিসাব বিভাগের রহিম সাহেবের সাথে দেখা করব”। রিসেপশনিস্ট পুরো ভবনের সবার রুম নম্বর মুখস্থ রাখেন না। তিনি জানেন হিসাব বিভাগ পাঁচ তলায়, আর পাঁচ তলার রিসেপশনকে ফোন করেন; পাঁচ তলা জানে রহিম সাহেব রুম ৫১২-তে। আজ রুম নম্বর জেনে রিসেপশনিস্ট খাতায় টুকে রাখলেন — বিকেলে আরেকজন একই প্রশ্ন করলে আর ফোন করতে হবে না। এই তিনটি ধারণাই DNS: দায়িত্ব ভাগ করা (প্রতিটি তলা নিজের তথ্য রাখে), ধাপে ধাপে খোঁজা, আর খাতায় টুকে রাখা (cache).

১৯৭০-এর দশকে ARPANET-এ নাম আর ঠিকানার পুরো তালিকা ছিল একটিমাত্র ফাইলে — HOSTS.TXT. এটি রাখত Stanford Research Institute-এর Network Information Center (SRI-NIC); নতুন কম্পিউটার যুক্ত হলে সেখানে জানাতে হতো, আর প্রতিটি host নিয়মিত পুরো ফাইলটি নামিয়ে নিত। কম্পিউটারের সংখ্যা বাড়তে থাকায় ফাইল বড় হলো, নামানোর চাপ বাড়ল, একই নামে দ্বন্দ্ব দেখা দিল, আর হালনাগাদ পৌঁছাতে দেরি হতে লাগল। সমাধান হিসেবে Paul Mockapetris ১৯৮৩ সালে বিকেন্দ্রীভূত, স্তরভিত্তিক একটি নকশা প্রস্তাব করেন (RFC 882 ও 883). পরিমার্জিত রূপটি ১৯৮৭ সালে RFC 1034 (ধারণা) আর RFC 1035 (বাস্তবায়ন ও বার্তার গঠন) হিসেবে প্রকাশিত হয় — আজও DNS-এর মূল ভিত্তি সেগুলোই, যদিও পরে বহু RFC যোগ হয়েছে। পুরোনো ফাইলের উত্তরসূরি এখনো আপনার কম্পিউটারে আছে: /etc/hosts (অংশ ৮)।

মূল ধারণা

DNS তিনটি সমস্যার সমাধান: কেউ একা পুরো তালিকা রাখবে না (বিকেন্দ্রীকরণ), প্রতিটি অংশের মালিক নিজের অংশ হালনাগাদ করবেন (delegation), আর একবার পাওয়া উত্তর নির্দিষ্ট সময় পর্যন্ত বারবার ব্যবহার হবে (caching).

২ · নামের গাছ — root, TLD, domain, zone আর delegation

DNS-এর নামগুলো একটি উল্টো গাছ (namespace). সবার ওপরে root — নামহীন, লেখা হয় একটি ফাঁকা বিন্দু . দিয়ে। নাম পড়া হয় ডান থেকে বাঁয়ে, গাছের গোড়া থেকে পাতার দিকে। www.example.com.-এর শেষের বিন্দুটিই root — সাধারণত আমরা লিখি না, কিন্তু সব নামের শেষে সেটি আছে। শেষ বিন্দুসহ পুরো নামকে বলে FQDN.

                       .  (root)
        ┌──────────┬───────┴──────┬──────────────┐
       com        org            bd            arpa      ← TLD
    ┌───┴───┐      │        ┌─────┼─────┐        │
 example  ...   example    com   gov   ac   in-addr  ← দ্বিতীয় স্তর
 ┌──┴──┐                    │                    │
www   mail                 ...                  ...

প্রতিটি অংশকে বলে label — www, example, com. একটি label সর্বোচ্চ ৬৩ বাইট, পুরো নাম তারে সর্বোচ্চ ২৫৫ বাইট; বড়-ছোট হাতের অক্ষরে পার্থক্য নেই (Example.COM আর example.com একই)।

TLD — গাছের প্রথম শাখা

gTLD

Generic TLD: .com, .org, .net, .edu, .gov, আর ২০১০-এর দশকে যোগ হওয়া শত শত নতুন নাম (.app, .dev…)। প্রতিটির একটি registry থাকে, যারা zone চালায়।

.com .org .net

ccTLD

Country-code TLD: দুই অক্ষরের দেশ-কোড — বাংলাদেশের .bd, ভারতের .in. পরিচালনা করে সেই দেশের দায়িত্বপ্রাপ্ত প্রতিষ্ঠান, নিজেদের নিয়মে।

.bd .in .uk

অবকাঠামো আর সংরক্ষিত

.arpa — reverse DNS-এর জন্য (অংশ ৬)। আর উদাহরণ ও পরীক্ষার জন্য সংরক্ষিত নাম: .test, .example, .invalid, .localhost, আর example.com/.org/.net (RFC 2606).

.arpa .test

.bd-এর কথা: বাংলাদেশের ccTLD-এ সাধারণত সরাসরি নাম.bd না দিয়ে দ্বিতীয় স্তরের অধীনে নাম দেওয়া হয় — .com.bd (ব্যবসা), .gov.bd (সরকার), .edu.bd ও .ac.bd (শিক্ষা), .org.bd, .net.bd ইত্যাদি। এটি দেশীয়ভাবে পরিচালিত; কোন শাখায় কে নাম নিতে পারবেন, কী কাগজ লাগবে — এসব নিয়ম সময়ের সাথে বদলায়, তাই নাম নেওয়ার আগে দায়িত্বপ্রাপ্ত কর্তৃপক্ষের সর্বশেষ নির্দেশনা দেখে নিন। বাংলা লিপিতে একটি IDN ccTLD-ও আছে (.বাংলা)।

Domain বনাম zone, আর delegation

Domain মানে গাছের একটি শাখা আর তার নিচের সবকিছু — example.com domain-এ আছে www.example.com, mail.example.com, এমনকি dev.eu.example.com. Zone হলো গাছের সেই অংশ, যার তথ্য একটি প্রশাসন একসাথে রাখে আর যার উত্তর একই সার্ভার-সেট দেয়। মালিক চাইলে নিচের কোনো শাখার দায়িত্ব অন্য কাউকে দিয়ে দিতে পারেন — এটিই delegation. তখন সেই শাখা নতুন একটি zone হয়।

উদাহরণDomainZone
example.com-এর প্রশাসক eu.example.com ইউরোপের দলকে delegate করলেনexample.com domain-এ eu শাখাও আছেদুটি zone: example.com (শাখা বাদে) আর eu.example.com
.comকোটি কোটি নামসহ বিশাল domain.com zone-এ শুধু delegation-এর তথ্য (কোন নামের NS কারা), ভেতরের record নয়
rootপুরো DNSশুধু TLD-গুলোর delegation — ছোট একটি zone

Delegation আসলে দুটি record: ওপরের zone-এ (parent) লেখা থাকে নিচের zone-এর NS record — “example.com-এর উত্তর দেবে ns1.example.com আর ns2.example.com”. আর নিচের zone-এ (child) একই NS record থাকে, সাথে zone-এর পরিচয়পত্র SOA (অংশ ৬)। Root zone-এর ব্যবস্থাপনা IANA-র দায়িত্বে; সেখানে প্রতিটি TLD-এর delegation থাকে। কেউ একটি নাম কেনেন একটি registrar-এর মাধ্যমে, যে registry-কে জানায় কোন NS-এ delegate করতে হবে।

৩ · কে কোন কাজ করে — stub, recursive resolver, root, TLD আর authoritative

ভূমিকাকোথায় থাকেকী করেরিসেপশনের উপমায়
Stub resolverআপনার OS-এর ভেতরে (Linux-এ glibc, অনেক distro-তে systemd-resolved; Windows-এ DNS Client সেবা)শুধু একটি প্রশ্ন পাঠায় আর পুরো উত্তর চায় (RD = 1). নিজে গাছ ধরে খোঁজে নাদর্শনার্থী
Recursive resolverISP-র সার্ভার, অফিসের সার্ভার, বাসার router, বা public resolverroot থেকে শুরু করে ধাপে ধাপে খোঁজে, ফল cache-এ রাখে, stub-কে চূড়ান্ত উত্তর দেয়নিচতলার রিসেপশনিস্ট
Root server১৩টি নাম: a থেকে m.root-servers.net; প্রতিটি নামের পেছনে বিশ্বজুড়ে অনেক anycast instanceউত্তর জানে না; বলে দেয় কোন TLD-এর সার্ভার কারা (referral)ভবনের তলা-নির্দেশিকা
TLD server.com, .bd ইত্যাদির registryবলে দেয় example.com-এর authoritative সার্ভার কারাপাঁচ তলার রিসেপশন
Authoritative serverdomain-মালিক বা তাঁর DNS সেবাদাতানিজের zone-এর আসল উত্তর দেয় — উত্তরে AA (authoritative answer) bit চালুরহিম সাহেবের বিভাগ

Root server-এর “১৩” সংখ্যাটি: নাম ১৩টি, যন্ত্র ১৩টি নয়। প্রায় এক ডজন আলাদা সংস্থা এই নামগুলো চালায়, আর প্রতিটি নামের পেছনে anycast দিয়ে পৃথিবীর বহু শহরে instance আছে — সব মিলিয়ে এক হাজারেরও বেশি (সর্বশেষ সংখ্যা root-servers.org-এ)। সংখ্যাটি ১৩-তে আটকে থাকার মূল কারণ পুরোনো ৫১২ বাইটের UDP উত্তরে সবার নাম-ঠিকানা আঁটানো। Anycast কীভাবে একই ঠিকানাকে বহু জায়গায় বসায়, তা পর্ব ২৫-এ (BGP) দেখেছেন। প্রতিটি recursive resolver-এ root server-দের ঠিকানার একটি ছোট তালিকা আগে থেকে দেওয়া থাকে (root hints) — নইলে প্রথম প্রশ্ন কাকে করবে?

Recursive resolver কোথা থেকে আসে? বাসায় Wi-Fi-তে যুক্ত হলে DHCP সাধারণত router বা ISP-র resolver-এর ঠিকানা দেয় (পর্ব ১৮, DHCP আর ARP). অনেকে হাতে public resolver বসান — বড় কোম্পানি বা অলাভজনক সংস্থার চালানো, anycast-এ ছড়ানো resolver. এখানে একটি বাণিজ্যিক বিনিময় আছে: আপনার সব নাম-খোঁজা resolver-চালকের চোখে পড়ে, তাই কার resolver ব্যবহার করছেন, তা গোপনীয়তার সিদ্ধান্তও (অংশ ৯)।

দুটি ভূমিকা মেশাবেন না। Authoritative সার্ভার শুধু নিজের zone-এর প্রশ্নের উত্তর দেয়, অন্যদের হয়ে খোঁজে না; recursive resolver অন্যদের হয়ে খোঁজে, নিজের কোনো zone নেই। একই সার্ভারে দুটো চালানো পুরোনো অভ্যাস, এখন অনুৎসাহিত — আর recursive resolver যদি পৃথিবীর সবার জন্য খোলা থাকে, তা open resolver, যা amplification আক্রমণের প্রতিফলক হয় (পর্ব ২৮, UDP).

৪ · ধাপে ধাপে খোঁজা — iterative বনাম recursive

পরীক্ষার সবচেয়ে প্রিয় ছবি: একটি ল্যাপটপ প্রথমবার www.example.com খুঁজছে, resolver-এর cache সম্পূর্ণ ফাঁকা। দুই রকম প্রশ্ন আছে। Recursive query-তে প্রশ্নকারী বলে “পুরো উত্তর এনে দিন” — stub resolver এভাবেই resolver-কে জিজ্ঞেস করে। Iterative query-তে সার্ভার যা জানে তা-ই বলে — উত্তর বা পরের ঠিকানা (referral); resolver নিজে পরের জনকে জিজ্ঞেস করে। Root আর TLD সার্ভার শুধু iterative উত্তর দেয় — লাখো resolver-এর হয়ে খুঁজতে গেলে তারা ডুবে যেত।

  1. Stubল্যাপটপRD = 1
  2. RecursiveISP resolvercache ফাঁকা
  3. Root.anycast
  4. TLD.comgtld-servers
  5. Authoritativens1.example.com203.0.113.53
বার্তার খাতা
বার্তা নং
কে → কাকে
বিষয়বস্তু
Resolver-এর cache-এ জমল
  1. Stub-এর recursive প্রশ্ন। ব্রাউজার OS-কে নাম দিল; stub resolver একটি UDP datagram পাঠাল resolver-এর port 53-এ: “www.example.com-এর A record?” — header-এ RD (recursion desired) = 1, মানে “পুরো উত্তর চাই”।
  2. Resolver root-কে জিজ্ঞেস করল। Cache ফাঁকা, তাই root hints থেকে একটি root server বাছাই। প্রশ্ন একই নাম নিয়ে — যদিও root শুধু com. অংশটি নিয়ে মাথা ঘামায় (অংশ ৯-এর QNAME minimisation এখানে শুধু com. জিজ্ঞেস করত)। RD = 0: “নিজে খুঁজতে হবে না, যা জানেন বলুন”।
  3. Root-এর referral. উত্তর নেই (ANSWER ফাঁকা), কিন্তু authority section-এ com.-এর NS তালিকা (a থেকে m.gtld-servers.net), আর additional section-এ তাদের ঠিকানা। AA = 0 — root এই নামের মালিক নয়। এই NS record-এর TTL দুই দিন (১৭২,৮০০ সেকেন্ড), তাই পরের দুই দিন resolver আর root-কে .com-এর কথা জিজ্ঞেস করবে না।
  4. Resolver .com TLD-কে জিজ্ঞেস করল। একই প্রশ্ন, এবার a.gtld-servers.net-কে।
  5. TLD-এর referral, glue-সহ। “example.com-এর NS হলো ns1.example.com”. কিন্তু ns1-এর ঠিকানা খুঁজতে আবার example.com-কেই জিজ্ঞেস করতে হবে — ডিমের আগে মুরগি! তাই TLD additional section-এ ns1-এর ঠিকানাও দেয়: glue record, 203.0.113.53.
  6. Resolver authoritative সার্ভারকে জিজ্ঞেস করল। 203.0.113.53-এ একই প্রশ্ন। এই সার্ভারের কাছে example.com zone-এর আসল record আছে।
  7. আসল উত্তর, AA = 1. www.example.com. 300 IN A 192.0.2.80 — header-এ AA চালু, মানে উত্তরটি zone-এর মালিকের কাছ থেকে সরাসরি। TTL ৩০০: “এই উত্তর ৫ মিনিট পর্যন্ত মনে রাখা যাবে”।
  8. Resolver stub-কে উত্তর দিল। উত্তরে RA (recursion available) = 1, AA = 0 (resolver নিজে মালিক নয়)। মোট ৮টি বার্তা — ৪টি প্রশ্ন, ৪টি উত্তর; resolver আর সার্ভারদের মধ্যে ৬টি। ব্রাউজার এখন 192.0.2.80-এ TCP বা QUIC সংযোগ শুরু করতে পারে (পর্ব ৩৬)।

Recursive বনাম iterative — তুলনা ও হিসাব

পাঠ্যবইয়ে একটি দ্বিতীয় ছবিও থাকে: সব সার্ভার recursive হলে resolver root-কে, root TLD-কে, TLD authoritative-কে জিজ্ঞেস করে, আর উত্তর একই পথে ফেরে। তখনো বার্তা ৮টি (stub ↔ resolver ২টি, তারপর তিন জোড়া চেইনে) — কিন্তু root আর TLD-কে প্রতিটি অনুরোধের অবস্থা মনে রাখতে হতো। বাস্তবে তাই root ও TLD শুধু iterative.

প্রথমবারের সময় ≈ RTT(stub↔resolver) + RTT(root) + RTT(TLD) + RTT(authoritative)
যেমন ২ + ৩০ + ৪০ + ৫০ = ১২২ ms; .com-এর NS cache-এ থাকলে ২ + ৪০ + ৫০ = ৯২ ms, example.com-এর NS-ও থাকলে ২ + ৫০ = ৫২ ms; পুরো উত্তর cache-এ থাকলে শুধু ২ ms (অনুশীলন ১)

৫ · Caching আর TTL — প্রতিটি স্তরে খাতায় টুকে রাখা

প্রতিটি নাম-খোঁজায় ৮টি বার্তা লাগলে root server-গুলো এক সেকেন্ডও টিকত না। DNS টিকে আছে cache-এর জোরে। প্রতিটি record-এর সাথে থাকে একটি TTL — সেকেন্ডে, “এই উত্তর কতক্ষণ মনে রাখা যাবে”। (নামটি IP header-এর TTL-এর মতো হলেও মানে আলাদা: সেখানে hop গোনা, এখানে সময়।) TTL ঠিক করেন zone-এর মালিক, আর cache-এ থাকা সময়ে resolver উত্তর দেওয়ার সময় বাকি TTL কমিয়ে জানায়।

Cache থাকে অনেক জায়গায়: ব্রাউজারের ভেতরে, OS-এর stub-এ (systemd-resolved, Windows DNS Client), বাসার router-এ, ISP-র resolver-এ। সবচেয়ে বড় প্রভাব resolver-এর cache-এর — হাজারো গ্রাহক একই resolver ব্যবহার করেন, তাই জনপ্রিয় নাম প্রায় সবসময় সেখানে তৈরি থাকে।

নিচের simulator একটি ছোট নকল জগৎ: root, .com TLD আর ns1.example.com. এখানে www.example.com একটি CNAME — আসল নাম web.example.com, যার A record-এর TTL ৩০০. একই zone-এ থাকায় authoritative সার্ভার একই উত্তরে CNAME আর A দুটোই দেয়। Simulator চারটি সময়ে খোঁজে, আর একটি অস্তিত্বহীন নাম দিয়ে negative caching দেখায়। (ঠিকানাগুলো documentation ব্লকের, কাল্পনিক।)

// Iterative resolution over a mock hierarchy, with a TTL cache (all addresses are documentation IPs).
const SERVERS = {
  "root": { "com.": ["REFERRAL", "a.gtld-servers.net", "192.0.2.30", 172800] },
  "a.gtld-servers.net": { "example.com.": ["REFERRAL", "ns1.example.com", "203.0.113.53", 172800] },
  "ns1.example.com": { "www.example.com.": ["CNAME", "web.example.com.", 3600],
                       "web.example.com.": ["A", "192.0.2.80", 300], "SOA-MIN": 900 } };
const cache = new Map(); let sent = 0;                    // key "name type" -> {type, data, exp}
const get = (k, now) => { const e = cache.get(k); return e && e.exp > now ? e : null; };
const put = (name, type, data, ttl, now) => cache.set(name + " " + type, { type, data, exp: now + ttl });
function lookup(name, now) {
  for (;;) {
    const hit = get(name + " A", now) || get(name + " CNAME", now) || get(name + " NEG", now);
    if (hit) { console.log(`  cache HIT  ${name} ${hit.type} ${hit.data} (ttl left ${hit.exp - now}s)`);
      if (hit.type !== "CNAME") return hit.data; name = hit.data; continue; }
    const zone = ["example.com.", "com."].find(z => name.endsWith(z) && get(z + " NS", now));
    let server = zone ? get(zone + " NS", now).data : "root"; console.log(`  cache MISS ${name} -> ask ${server}`);
    for (;;) {
      const zd = SERVERS[server], key = Object.keys(zd).find(k => name.endsWith(k)); sent += 2;  // query + reply
      let rr = zd["SOA-MIN"] ? zd[name] : zd[key];
      if (!rr) { console.log(`    ${server}: NXDOMAIN, SOA minimum ${zd["SOA-MIN"]}s`);
        put(name, "NEG", "NXDOMAIN", zd["SOA-MIN"], now); return "NXDOMAIN"; }
      if (rr[0] === "REFERRAL") {
        console.log(`    ${server}: referral ${key} NS ${rr[1]} (glue ${rr[2]}) ttl=${rr[3]}`);
        put(key, "NS", rr[1], rr[3], now); server = rr[1]; continue; }
      for (; rr; rr = zd[name]) {                         // answer; in-zone CNAME target comes in the same reply
        console.log(`    ${server}: answer AA ${name} ${rr[0]} ${rr[1]} ttl=${rr[2]}`);
        put(name, rr[0], rr[1], rr[2], now);
        if (rr[0] === "A") return rr[1]; name = rr[1];
      } break;                                            // CNAME pointed outside this zone: start again
    }
  }
}
for (const [t, n] of [[0, "www"], [100, "www"], [400, "www"], [410, "nope"], [500, "nope"]]) {
  const before = sent; console.log(`t=${t}s lookup ${n}.example.com.`);
  console.log(`  => ${lookup(n + ".example.com.", t)}   (resolver<->server messages: ${sent - before})`); }

আউটপুট:

t=0s lookup www.example.com.
  cache MISS www.example.com. -> ask root
    root: referral com. NS a.gtld-servers.net (glue 192.0.2.30) ttl=172800
    a.gtld-servers.net: referral example.com. NS ns1.example.com (glue 203.0.113.53) ttl=172800
    ns1.example.com: answer AA www.example.com. CNAME web.example.com. ttl=3600
    ns1.example.com: answer AA web.example.com. A 192.0.2.80 ttl=300
  => 192.0.2.80   (resolver<->server messages: 6)
t=100s lookup www.example.com.
  cache HIT  www.example.com. CNAME web.example.com. (ttl left 3500s)
  cache HIT  web.example.com. A 192.0.2.80 (ttl left 200s)
  => 192.0.2.80   (resolver<->server messages: 0)
t=400s lookup www.example.com.
  cache HIT  www.example.com. CNAME web.example.com. (ttl left 3200s)
  cache MISS web.example.com. -> ask ns1.example.com
    ns1.example.com: answer AA web.example.com. A 192.0.2.80 ttl=300
  => 192.0.2.80   (resolver<->server messages: 2)
t=410s lookup nope.example.com.
  cache MISS nope.example.com. -> ask ns1.example.com
    ns1.example.com: NXDOMAIN, SOA minimum 900s
  => NXDOMAIN   (resolver<->server messages: 2)
t=500s lookup nope.example.com.
  cache HIT  nope.example.com. NEG NXDOMAIN (ttl left 810s)
  => NXDOMAIN   (resolver<->server messages: 0)

t = 0: cache ফাঁকা — root আর TLD থেকে দুটি referral, তারপর authoritative উত্তরে CNAME আর A একসাথে। resolver ও সার্ভারের মধ্যে ৬টি বার্তা; stub ↔ resolver-এর ২টি যোগ করলে stepper-এর মতো ৮টি। t = 100: দুটি record-ই cache-এ, বাকি TTL ৩,৫০০ আর ২০০ — কোনো বার্তা লাগল না। t = 400: A record-এর ৩০০ সেকেন্ড পেরিয়েছে, কিন্তু CNAME (৩,৬০০) এখনো আছে, আর example.com-এর NS-ও (১৭২,৮০০) — তাই resolver root বা TLD-কে না জিজ্ঞেস করে সোজা ns1.example.com-এ গেল: মাত্র ২টি বার্তা। t = 410 ও 500: nope.example.com নেই — উত্তর NXDOMAIN, আর সেই “নেই” খবরটিও ৯০০ সেকেন্ডের জন্য cache-এ রাখা হলো, তাই ৫০০-তে কোনো বার্তা নেই (বাকি ৮১০)। নিজে চেষ্টা করুন: "web.example.com."-এর TTL 300 বদলে 30 করুন — t = 100-এ কী হবে?

  1. প্রশ্নwww.example.comstub থেকে
  2. CacheTTL গোনাresolver-এ
  3. Authoritativens1.example.comদরকার হলে
Resolver-এর cache (বাকি TTL, সেকেন্ড)
সময়
example.com. NS
www CNAME web
web.example.com. A
nope.example.com. (negative)
ফল │ বার্তা
  1. t = 0: পুরো MISS. কিছুই নেই, তাই root → TLD → authoritative. ফেরার পথে তিন স্তরের তথ্য cache-এ জমল, প্রতিটি নিজের TTL নিয়ে: NS দুই দিন, CNAME এক ঘণ্টা, A পাঁচ মিনিট।
  2. t = 100: পুরো HIT. CNAME আর A দুটোই আছে। Resolver সাথে সাথে উত্তর দিল, আর stub-কে TTL জানাল কমিয়ে — A-এর ক্ষেত্রে ২০০. শূন্য বার্তা, সময় শুধু stub ↔ resolver-এর এক RTT.
  3. t = 400: A-এর মেয়াদ শেষ। CNAME এখনো আছে (৩,২০০ বাকি), তাই resolver জানে আসল নাম web.example.com. তার A নেই, কিন্তু example.com-এর NS আছে — সোজা ns1-কে জিজ্ঞেস, ২টি বার্তা। নতুন A আবার ৩০০ সেকেন্ডের জন্য।
  4. t = 410: অস্তিত্বহীন নাম। nope.example.com-এর উত্তর NXDOMAIN, সাথে zone-এর SOA. RFC 2308 অনুযায়ী “নেই” খবরটি রাখা যায় SOA-র TTL আর SOA-র minimum ঘরের মধ্যে ছোটটি পর্যন্ত — এখানে ৯০০ সেকেন্ড।
  5. t = 500: negative HIT. আবার একই ভুল নাম — resolver সার্ভারকে বিরক্ত না করে সাথে সাথে NXDOMAIN দিল (বাকি ৮১০)। এর একটি পার্শ্বপ্রতিক্রিয়া: কেউ নতুন record যোগ করার আগে নামটি খুঁজে থাকলে, যোগ করার পরেও negative TTL শেষ না হওয়া পর্যন্ত সেই resolver-এর ব্যবহারকারীরা “নেই” দেখবেন।

“DNS propagation” বলে কিছু নেই — আছে TTL

Hosting বদলালে প্রায়ই শোনা যায় “DNS propagate হতে ২৪–৪৮ ঘণ্টা লাগবে”। আসলে কোনো হালনাগাদ কোথাও “ছড়ায়” না। Authoritative সার্ভারে record বদলানো মাত্রই নতুন উত্তর দেওয়া শুরু হয়; পুরোনো উত্তর টিকে থাকে শুধু সেই resolver-গুলোতে, যারা আগে এটি cache করেছিল — সর্বোচ্চ পুরোনো TTL পর্যন্ত। তাই পেশাদারেরা বদলের এক-দুই দিন আগে TTL কমিয়ে (যেমন ৩০০) রাখেন, বদলান, তারপর আবার বাড়ান। NS বদলের সময় parent zone-এর NS TTL (প্রায়ই দুই দিন) গুরুত্বপূর্ণ — সেটি আপনার হাতে নেই। কিছু resolver নিজের নিয়মে TTL-এর সর্বনিম্ন বা সর্বোচ্চ সীমা বসায়, তাই বাস্তবে সামান্য ব্যতিক্রম দেখা যায়।

৬ · Resource record — A থেকে HTTPS পর্যন্ত

Zone-এর প্রতিটি তথ্য একটি resource record (RR): নাম TTL class type ডেটা. Class প্রায় সবসময় IN (Internet). একটি ছোট zone ফাইল (BIND-এর প্রচলিত লেখার ধাঁচে):

$ORIGIN example.com.
$TTL 3600
@     IN SOA  ns1.example.com. hostmaster.example.com. (
              2026102601 ; serial
              7200       ; refresh (2 h)
              900        ; retry (15 min)
              1209600    ; expire (14 days)
              300 )      ; minimum = negative-caching TTL
@     IN NS    ns1.example.com.
@     IN NS    ns2.example.net.
@     IN A     192.0.2.80
@     IN AAAA  2001:db8::80
www   IN CNAME web.example.com.
web   300 IN A 192.0.2.80
@     IN MX    10 mail.example.com.
mail  IN A     192.0.2.25
@     IN TXT   "v=spf1 mx -all"
_sip._tcp IN SRV 10 60 5060 sip.example.com.
@     IN CAA   0 issue "ca.example.net"
ns1   IN A     203.0.113.53
80.2.0.192.in-addr.arpa. IN PTR web.example.com.  ; থাকে reverse zone-এ, এখানে শুধু দেখানোর জন্য
Type (নম্বর)ডেটাকাজ ও খেয়াল রাখার কথা
A (1)IPv4 ঠিকানাসবচেয়ে প্রচলিত; একাধিক A থাকলে resolver সবগুলোই দেয়
AAAA (28)IPv6 ঠিকানাdual-stack ক্লায়েন্ট A আর AAAA দুটোই চায় (পর্ব ২১)
CNAME (5)আরেকটি নাম“এই নাম আসলে ওই নামের ডাকনাম”; resolver আসল নাম ধরে আবার খোঁজে। নিচে apex-এর সমস্যা দেখুন
MX (15)অগ্রাধিকার + মেইল সার্ভারের নামছোট সংখ্যা আগে; ইমেইলের পথ পর্ব ৩৯-এ (ইমেইল)
NS (2)নাম-সার্ভারের নামdelegation; অন্তত দুটি, আলাদা নেটওয়ার্কে রাখা ভালো
SOA (6)zone-এর পরিচয়পত্রপ্রতিটি zone-এ ঠিক একটি; নিচে ঘরগুলো
PTR (12)একটি নামঠিকানা থেকে নাম (reverse DNS), নিচে দেখুন
TXT (16)যেকোনো লেখাইমেইলের SPF, DKIM, DMARC (পর্ব ৩৯), domain-এর মালিকানা প্রমাণ
SRV (33)priority, weight, port, targetকোন সেবা কোন সার্ভারের কোন port-এ — SIP, XMPP, কিছু directory সেবা
CAA (257)flag, tag, CA-র নামকোন certificate authority এই নামে certificate দিতে পারবে (পর্ব ৪৮)
SVCB (64) / HTTPS (65)priority, target, parameterসংযোগের আগেই জানায় h3/h2 সমর্থন, বিকল্প সার্ভার (RFC 9460; পর্ব ৩৭)

CNAME-এর নিয়ম আর apex-এর সমস্যা

নিয়ম: যে নামে CNAME আছে, সেখানে আর কোনো record থাকতে পারবে না — কারণ CNAME মানে “এই নামের সব প্রশ্ন ওই নামে যান”। কিন্তু zone-এর মূল নামে (apex, যেমন খালি example.com) সবসময় SOA আর NS থাকে। তাই example.com-এ CNAME বসানো যায় না — অথচ CDN-গুলো চায় গ্রাহক একটি CNAME দিয়ে তাদের দিকে নির্দেশ করুক। সমাধান: অনেক DNS সেবাদাতার নিজস্ব “ALIAS/ANAME” বা CNAME flattening — authoritative সার্ভার নিজেই লক্ষ্য-নামের A/AAAA খুঁজে apex-এ বসিয়ে দেয় (এটি মান নয়, সেবাদাতা ভেদে আচরণ আলাদা)। নতুন মানসম্মত পথ HTTPS record-এর “alias mode”, তবে সব ক্লায়েন্ট এখনো তা ব্যবহার করে না।

SOA-র সংখ্যাগুলো — primary আর secondary

একটি zone সাধারণত একটি primary সার্ভারে সম্পাদিত হয় আর এক বা একাধিক secondary সার্ভার কপি রাখে (zone transfer). SOA-র সংখ্যাগুলো secondary-কে নিয়ম বলে দেয়:

ঘরউদাহরণমানে
MNAME, RNAMEns1.example.com., hostmaster.example.com.primary সার্ভার; দায়িত্বপ্রাপ্ত ব্যক্তির ইমেইল (প্রথম বিন্দু = @)
Serial2026102601সংস্করণ নম্বর; zone বদলালে বাড়াতে হয়। প্রচলিত ধাঁচ YYYYMMDDnn. বাড়াতে ভুলে গেলে secondary বদল টেরই পায় না
Refresh৭,২০০ (২ ঘণ্টা)secondary কতক্ষণ পরপর primary-র serial দেখবে
Retry৯০০ (১৫ মিনিট)primary-তে পৌঁছাতে না পারলে কতক্ষণ পর আবার চেষ্টা
Expire১,২০৯,৬০০ (১৪ দিন)এতদিন primary-র নাগাল না পেলে secondary zone-এর উত্তর দেওয়াই বন্ধ করবে — পুরোনো তথ্য চিরকাল না দেওয়ার জন্য
Minimum৩০০আজকের অর্থ: negative caching-এর TTL (RFC 2308)

Refresh-এর অপেক্ষা না করে primary বদলের খবর সাথে সাথে জানাতে পারে NOTIFY বার্তায় (RFC 1996); তখন secondary serial দেখে বড় হলে transfer চায়।

Reverse DNS — ঠিকানা থেকে নাম

কখনো উল্টো প্রশ্ন লাগে: “192.0.2.10 কার?” — log পড়ার সময়, traceroute-এ router-এর নাম দেখাতে, মেইল সার্ভার যাচাইয়ে। DNS নাম ধরে খোঁজে, তাই ঠিকানাকে একটি বিশেষ নামে রূপ দেওয়া হয়। IPv4-এ অক্টেটগুলো উল্টো ক্রমে লিখে শেষে .in-addr.arpa: 10.2.0.192.in-addr.arpa. উল্টো কেন? DNS নাম ডান দিকে সাধারণ (গাছের গোড়া), বাঁয়ে নির্দিষ্ট; IP ঠিকানা বাঁ দিকে সাধারণ (network), ডানে নির্দিষ্ট (host). উল্টালে দুটি মিলে যায়, আর 192.0.2.0/24-এর মালিককে 2.0.192.in-addr.arpa zone delegate করা যায়। IPv6-এ প্রতিটি hex অঙ্ক (nibble) একটি label, উল্টো ক্রমে, শেষে .ip6.arpa (RFC 3596). Reverse DNS-এর record হলো PTR.

// Build reverse-DNS (PTR) names for IPv4 and IPv6 - documentation addresses only.
function ptr4(ip) {
  return ip.split(".").reverse().join(".") + ".in-addr.arpa.";
}
function expand6(ip) {                              // "2001:db8::5" -> 8 groups of 4 hex digits
  const [head, tail] = ip.split("::");
  const h = head ? head.split(":") : [], t = tail !== undefined && tail ? tail.split(":") : [];
  const zeros = tail === undefined ? [] : Array(8 - h.length - t.length).fill("0");
  return [...h, ...zeros, ...t].map(g => g.padStart(4, "0"));
}
function ptr6(ip) {
  const nibbles = expand6(ip).join("").split("");  // 32 hex digits, one label each
  return nibbles.reverse().join(".") + ".ip6.arpa.";
}
for (const ip of ["192.0.2.10", "198.51.100.53", "203.0.113.7"])
  console.log(ip.padEnd(15), "->", ptr4(ip));
console.log("zone for 192.0.2.0/24     ->", ptr4("192.0.2"));
for (const ip of ["2001:db8::1", "2001:db8:abcd:12::567:89ab"]) {
  console.log("\n" + ip);
  console.log("  expanded :", expand6(ip).join(":"));
  const name = ptr6(ip);
  console.log("  PTR name :", name);
  console.log("  labels   :", name.split(".").length - 1, "(32 nibbles + ip6 + arpa)");
}
console.log("\nzone for 2001:db8::/32     ->", ptr6("2001:db8::").slice(-25));

আউটপুট:

192.0.2.10      -> 10.2.0.192.in-addr.arpa.
198.51.100.53   -> 53.100.51.198.in-addr.arpa.
203.0.113.7     -> 7.113.0.203.in-addr.arpa.
zone for 192.0.2.0/24     -> 2.0.192.in-addr.arpa.

2001:db8::1
  expanded : 2001:0db8:0000:0000:0000:0000:0000:0001
  PTR name : 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.
  labels   : 34 (32 nibbles + ip6 + arpa)

2001:db8:abcd:12::567:89ab
  expanded : 2001:0db8:abcd:0012:0000:0000:0567:89ab
  PTR name : b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.2.1.0.0.d.c.b.a.8.b.d.0.1.0.0.2.ip6.arpa.
  labels   : 34 (32 nibbles + ip6 + arpa)

zone for 2001:db8::/32     -> 8.b.d.0.1.0.0.2.ip6.arpa.

IPv4-এ চারটি অক্টেট উল্টে গেল: 192.0.2.10 → 10.2.0.192.in-addr.arpa. IPv6-এ আগে :: খুলে পুরো ৮টি group, প্রতিটি ৪ অঙ্কে (0db8, 0012) — বাদ পড়া শূন্য না বসালে নাম ভুল হবে, এটাই সবচেয়ে প্রচলিত ভুল। তারপর ৩২টি অঙ্ক এক এক করে উল্টে বিন্দু দিয়ে জোড়া — মোট ৩৪টি label. শেষ লাইন দেখায়, 2001:db8::/32 প্রথম ৩২ bit = ৮টি nibble, তাই তার reverse zone 8.b.d.0.1.0.0.2.ip6.arpa. — nibble-এর সীমানায় delegate করা সহজ, এজন্য IPv6 prefix সাধারণত ৪-এর গুণিতক। একটি নিরাপত্তার কথা: PTR record লেখেন ঠিকানার মালিক, তাই যে-কেউ নিজের ঠিকানার PTR-এ যেকোনো নাম লিখতে পারেন। মেইল সার্ভার তাই forward-confirmed reverse DNS দেখে — PTR-এর নামের A আবার সেই ঠিকানায় ফেরে কি না।

৭ · DNS বার্তার ভেতরে — header, চারটি section আর compression

প্রশ্ন আর উত্তরের গঠন একই (RFC 1035): ১২ বাইটের header, তারপর চারটি section.

 0                   1
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5   (bit)
┌───────────────────────────────┐
│              ID               │  byte 0-1
├─┬───────┬─┬─┬─┬─┬─┬─┬─┬───────┤
│Q│Opcode │A│T│R│R│Z│A│C│ RCODE │  byte 2-3
│R│       │A│C│D│A│ │D│D│       │
├─┴───────┴─┴─┴─┴─┴─┴─┴─┴───────┤
│QDCOUNT│ANCOUNT│NSCOUNT│ARCOUNT│  byte 4-11 (2 bytes each)
├───────────────────────────────┤
│ Question   (name, type, class)│
│ Answer     (RR …)             │
│ Authority  (NS, SOA …)        │
│ Additional (glue, OPT …)      │
└───────────────────────────────┘
  • ID (১৬ bit) — প্রশ্নকারী বাছে, উত্তরে হুবহু ফেরত আসে; এ দিয়েই উত্তর প্রশ্নের সাথে মেলে।
  • QR 0 = প্রশ্ন, 1 = উত্তর। Opcode 0 = সাধারণ প্রশ্ন। AA authoritative উত্তর। TC উত্তর কাটা পড়েছে (truncation) — TCP-তে আবার জিজ্ঞেস করুন। RD recursion চাই, RA recursion দেওয়া যায়। AD/CD DNSSEC-এর জন্য। RCODE: 0 NOERROR, 2 SERVFAIL, 3 NXDOMAIN, 5 REFUSED.
  • চারটি count — প্রতিটি section-এ কয়টি entry.
  • নাম লেখার নিয়ম: প্রতিটি label-এর আগে তার দৈর্ঘ্যের একটি বাইট, শেষে 00 (root-এর ফাঁকা label). বিন্দু তারে যায় না। www.example.com = 03 'www' 07 'example' 03 'com' 00 = ১৭ বাইট।

একই নাম একটি উত্তরে বারবার আসে (প্রশ্নে, প্রতিটি answer-এ, authority-তে)। জায়গা বাঁচাতে আছে name compression: দৈর্ঘ্য-বাইটের ওপরের দুই bit 11 হলে (অর্থাৎ বাইট 0xC0 বা তার বেশি) সেটি label নয়, একটি pointer — পরের ১৪ bit বার্তার শুরু থেকে একটি offset, “বাকি নাম ওখান থেকে পড়ুন”। c0 0c মানে offset ১২ — ঠিক যেখানে প্রশ্নের নাম শুরু (header ১২ বাইট)। এজন্য উত্তরে c0 0c প্রায় সবসময় দেখবেন।

নিচের প্রোগ্রাম প্রথমে হাতে একটি প্রশ্ন বানায় (ID 0x1a2b, RD = 1, www.example.com A), তারপর একটি হাতে-বানানো উত্তর পড়ে — যেখানে CNAME-এর ডেটা আর দ্বিতীয় answer-এর নাম দুটোই pointer দিয়ে লেখা।

// Build a DNS query by hand, then parse a hand-made response that uses compression pointers.
const hx = a => a.map(b => b.toString(16).padStart(2, "0")).join(" ");
const u16 = (m, o) => m[o] << 8 | m[o + 1];
const encName = n => [...n.split(".").flatMap(l => [l.length, ...[...l].map(c => c.charCodeAt(0))]), 0];
const q = [0x1a, 0x2b, 0x01, 0x00, 0, 1, 0, 0, 0, 0, 0, 0, ...encName("www.example.com"), 0, 1, 0, 1];
console.log(`QUERY (${q.length} bytes)\n header:     ${hx(q.slice(0, 12))}\n qname:      ${hx(q.slice(12, 29))}\n type/class: ${hx(q.slice(29))}`);
function readName(m, o, path) {                       // returns [name, offset after the name]
  const labels = []; let end = -1;
  while (m[o] !== 0) {
    if ((m[o] & 0xc0) === 0xc0) {                     // two top bits 11 -> 14-bit pointer
      const to = u16(m, o) & 0x3fff; path.push(`ptr@${o}->${to}`);
      if (end < 0) end = o + 2; o = to; continue;
    }
    labels.push(String.fromCharCode(...m.slice(o + 1, o + 1 + m[o]))); o += m[o] + 1;
  }
  return [labels.join(".") + ".", end < 0 ? o + 1 : end];
}
// response: same id, flags 8180, 1 question, 2 answers (CNAME, then A) - names compressed
const r = [0x1a, 0x2b, 0x81, 0x80, 0, 1, 0, 2, 0, 0, 0, 0, ...q.slice(12),
  0xc0, 0x0c, 0, 5, 0, 1, 0, 0, 0x0e, 0x10, 0, 6, 3, 0x77, 0x65, 0x62, 0xc0, 0x10,
  0xc0, 0x2d, 0, 1, 0, 1, 0, 0, 0x01, 0x2c, 0, 4, 192, 0, 2, 80];
const f = u16(r, 2);
console.log(`\nRESPONSE (${r.length} bytes) id=0x${u16(r, 0).toString(16)} flags=0x${f.toString(16)}`);
console.log(` QR=${f >> 15} opcode=${f >> 11 & 15} AA=${f >> 10 & 1} TC=${f >> 9 & 1} RD=${f >> 8 & 1} RA=${f >> 7 & 1} RCODE=${f & 15}`);
console.log(` counts: QD=${u16(r, 4)} AN=${u16(r, 6)} NS=${u16(r, 8)} AR=${u16(r, 10)}`);
let [qn, o] = readName(r, 12, []);
console.log(` question: ${qn} type=${u16(r, o)} class=${u16(r, o + 2)}`); o += 4;
for (let i = 0; i < u16(r, 6); i++) {
  const path = [], start = o; let name; [name, o] = readName(r, o, path);
  const type = u16(r, o), ttl = u16(r, o + 4) * 65536 + u16(r, o + 6), len = u16(r, o + 8), rd = o + 10;
  const data = type === 1 ? r.slice(rd, rd + 4).join(".") : readName(r, rd, path)[0];
  console.log(` answer@${start}: ${name} ${type === 1 ? "A" : "CNAME"} ttl=${ttl} rdlen=${len} -> ${data}  [${path.join(", ")}]`);
  o = rd + len;
}

আউটপুট:

QUERY (33 bytes)
 header:     1a 2b 01 00 00 01 00 00 00 00 00 00
 qname:      03 77 77 77 07 65 78 61 6d 70 6c 65 03 63 6f 6d 00
 type/class: 00 01 00 01

RESPONSE (67 bytes) id=0x1a2b flags=0x8180
 QR=1 opcode=0 AA=0 TC=0 RD=1 RA=1 RCODE=0
 counts: QD=1 AN=2 NS=0 AR=0
 question: www.example.com. type=1 class=1
 answer@33: www.example.com. CNAME ttl=3600 rdlen=6 -> web.example.com.  [ptr@33->12, ptr@49->16]
 answer@51: web.example.com. A ttl=300 rdlen=4 -> 192.0.2.80  [ptr@51->45, ptr@49->16]

প্রশ্ন ৩৩ বাইট: header-এ ID 1a 2b, flag 01 00 (শুধু RD = 1), QDCOUNT 1, বাকি count শূন্য। নামের ১৭ বাইটে 77 77 77 = “www”, 65 78 61 6d 70 6c 65 = “example”. শেষে type 1 (A), class 1 (IN). উত্তর ৬৭ বাইট: flag 0x8180 = QR 1, RD 1, RA 1, AA 0 — একটি recursive resolver-এর সাধারণ উত্তর। প্রথম answer offset ৩৩-এ: নামের জায়গায় শুধু c0 0c → offset ১২, অর্থাৎ প্রশ্নের নাম; ডেটা ৬ বাইট: 03 'web' তারপর pointer → ১৬, যেখানে “example.com” শুরু — তাই web.example.com. দ্বিতীয় answer (offset ৫১)-এর নাম c0 2d → ৪৫, যেখানে প্রথম answer-এর ডেটায় “web” লেখা ছিল; সেখান থেকে আবার pointer ১৬-তে। Pointer ছাড়া এই উত্তর ৬৭-এর বদলে ১০৮ বাইট হতো (দুটি answer-এর নাম ১৫ + ১৫ আর CNAME-এর ডেটা ১১ — মোট ৪১ বাইট বাড়তি)। TTL ৩,৬০০ লেখা আছে 00 00 0e 10 হিসেবে, ৩০০ লেখা 00 00 01 2c.

  1. offset 51c0 2dpointer
  2. offset 4503 weblabel
  3. offset 49c0 10pointer
  4. offset 1607 examplelabel
  5. offset 24–2803 com 00শেষ
Parser-এর অবস্থা
এখন পড়ছি (offset)
বাইট
সিদ্ধান্ত
জোড়া নাম
  1. প্রথম বাইট 0xc0. বাইনারি 1100 0000 — ওপরের দুই bit 11. Label-এর দৈর্ঘ্য সর্বোচ্চ ৬৩ (0011 1111), তাই 11 দিয়ে শুরু বাইট কখনো দৈর্ঘ্য হতে পারে না — এটি pointer.
  2. Offset বের করা। দুই বাইট মিলে 0xc02d; ওপরের দুই bit মুছতে AND 0x3fff → 0x002d = ৪৫. Pointer সবসময় বার্তার আগের কোনো জায়গায় নির্দেশ করে।
  3. Offset ৪৫: label “web”. দৈর্ঘ্য-বাইট 03, তারপর 77 65 62. এটি প্রথম answer-এর CNAME ডেটার ভেতরের অংশ — নামের একটি অংশ অন্য record-এর ডেটা থেকেও ধার নেওয়া যায়।
  4. Offset ৪৯: আবার pointer. c0 10 → ১৬. একটি নামে একাধিক লাফ বৈধ; কিন্তু parser-কে লাফ গুনে সীমা রাখতে হয়, নইলে ইচ্ছে করে বানানো pointer-এর লুপে চিরকাল ঘুরবে — বাস্তব DNS parser-এর পরিচিত নিরাপত্তা-ত্রুটি।
  5. Offset ১৬: label “example”. এটি প্রশ্নের নামের দ্বিতীয় label — প্রশ্নের নাম শুরু ১২-তে (03 www), তাই 07 আছে ১৬-তে।
  6. “com” আর 00. Offset ২৪-এ 03 63 6f 6d, ২৮-এ 00 — root, নাম শেষ: web.example.com.
  7. কোথা থেকে চলবে? নামের পরের ঘর (type) পড়া শুরু হয় প্রথম pointer-এর ঠিক পরে — ৫১ + ২ = ৫৩, লাফের জায়গা থেকে নয়। কোডে end = o + 2 শুধু প্রথম pointer-এ বসানো হয় এজন্যই।

UDP 53, TCP 53, আর zone transfer

সাধারণ প্রশ্ন-উত্তর যায় UDP port 53-এ — একটি প্রশ্ন, একটি উত্তর, handshake নেই। উত্তর বড় হলে সার্ভার TC bit বসায়, আর ক্লায়েন্ট একই প্রশ্ন TCP port 53-এ আবার করে। TCP-তে প্রতিটি বার্তার আগে ২ বাইটের দৈর্ঘ্য থাকে (TCP-র byte stream-এ সীমানা চিহ্ন)। আজ TCP সমর্থন ঐচ্ছিক নয়, বাধ্যতামূলক (RFC 7766). পুরোনো ৫১২ বাইটের সীমা, EDNS(0), ১,২৩২ বাইটের পরামর্শ আর retry-র timeout — এগুলো পর্ব ২৮-এ (UDP) বিস্তারিত দেখেছেন। পুরো zone কপি করা (AXFR) বা শুধু বদলগুলো (IXFR) সবসময় TCP-তে, কারণ ডেটা বড় আর নির্ভরযোগ্যভাবে পৌঁছাতে হবে। AXFR শুধু নিজের secondary-দের জন্য খোলা রাখুন (ঠিকানা-তালিকা বা TSIG key দিয়ে) — নইলে যে-কেউ পুরো zone-এর তালিকা নামিয়ে নিতে পারে।

৮ · Linux-এ নাম খোঁজা — /etc/hosts, nsswitch.conf আর resolv.conf

একটি প্রোগ্রাম নাম দিয়ে সংযোগ করতে চাইলে সাধারণত ডাকে getaddrinfo(). Linux-এর glibc তখন তিনটি ফাইল দেখে:

  1. /etc/nsswitch.conf — কোন উৎস কোন ক্রমে দেখা হবে। প্রচলিত লাইন hosts: files dns: আগে ফাইল, তারপর DNS. systemd-ভিত্তিক distro-তে প্রায়ই files mdns4_minimal [NOTFOUND=return] resolve dns-এর মতো লম্বা লাইন দেখবেন।
  2. /etc/hosts — হাতে লেখা নাম-ঠিকানার ছোট তালিকা, HOSTS.TXT-এর উত্তরসূরি। এখানে থাকলে DNS-এ প্রশ্নই যায় না — পরীক্ষার জন্য সুবিধাজনক, ভুলে গেলে রহস্যময়।
  3. /etc/resolv.conf — DNS-এর পালা এলে কোন resolver-কে জিজ্ঞেস করবে: nameserver (glibc সর্বোচ্চ ৩টি ব্যবহার করে, ক্রমানুসারে), search (ছোট নামের পেছনে যোগ করার domain), আর options (timeout: ডিফল্ট ৫ সেকেন্ড, attempts: ডিফল্ট ২, ndots:)। systemd-resolved থাকলে এখানে প্রায়ই nameserver 127.0.0.53 — আসল resolver-এর তালিকা দেখায় resolvectl status.

নিচের স্ক্রিপ্ট এই রানারে ফাইলগুলো পড়ে, getent দিয়ে glibc-র একই পথে localhost খোঁজে, তারপর একটি পাবলিক নাম আর একটি অস্তিত্বহীন নাম খোঁজে। এই রানার একটি sandbox — সাধারণ বাইরের সংযোগ এখানে ধরে নেওয়া যায় না, তাই ফল যা-ই হোক, স্ক্রিপ্ট সুন্দরভাবে জানায় আর সর্বোচ্চ ৮ সেকেন্ড অপেক্ষা করে। গোপনীয়তার জন্য স্ক্রিপ্ট নিজেই loopback, 10.0.2.x আর IPv6-এর স্থানীয় ঠিকানা ছাড়া সব ঠিকানা, search domain আর host-এর নিজস্ব নাম ঢেকে দেয়।

private() { case "$1" in 127.*|10.0.2.*|::1|fd*|fe80:*|ff0*|fe00:*) return 0;; esac; return 1; }
echo "== 1. /etc/resolv.conf (which resolver? which options?) =="
if [ -r /etc/resolv.conf ]; then
  grep -Ev '^[[:space:]]*(#|;|$)' /etc/resolv.conf | while read -r key val rest; do
    case "$key" in
      nameserver) private "$val" || val="<resolver-IP>";;
      search|domain) val="<search-domain>"; rest="";;
    esac
    echo "  $key $val${rest:+ $rest}"
  done
else echo "  (resolv.conf নেই)"; fi
echo "== 2. /etc/hosts (the local name table) =="
if [ -r /etc/hosts ]; then
  grep -Ev '^[[:space:]]*(#|$)' /etc/hosts | while read -r ip names; do
    private "$ip" || ip="<host-IP>"; case "$names" in *localhost*|ip6-*) ;; *) names="<hostname>";; esac
    echo "  $ip $names"
  done
else echo "  (hosts নেই)"; fi
echo "== 3. lookup order (/etc/nsswitch.conf) =="
grep '^hosts:' /etc/nsswitch.conf 2>/dev/null || echo "  (nsswitch.conf নেই -> glibc default: files, then dns)"
echo "== 4. getent hosts localhost (uses the same order as programs) =="
getent hosts localhost || echo "  not found"
echo "== 5. DNS tools here? =="
for t in dig nslookup host resolvectl; do command -v "$t" >/dev/null && echo "  $t: আছে" || echo "  $t: নেই"; done
echo "== 6. two names through DNS =="
for name in example.com does-not-exist.invalid; do
  out=$(timeout 8 getent ahosts "$name"); rc=$?
  case $rc in
    0) echo "  $name: found, $(echo "$out" | awk '{print $1}' | sort -u | wc -l) distinct addresses (not shown)";;
    2) echo "  $name: exit 2 = name not found";;
    124) echo "  $name: exit 124 = no reply within 8 s";;
    *) echo "  $name: exit $rc = lookup failed";;
  esac
done

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

== 1. /etc/resolv.conf (which resolver? which options?) ==
  nameserver 10.0.2.3
  nameserver <resolver-IP>
  nameserver <resolver-IP>
  nameserver <resolver-IP>
  nameserver <resolver-IP>
== 2. /etc/hosts (the local name table) ==
  127.0.1.1 <hostname>
  127.0.0.1 localhost
  ::1 localhost ip6-localhost ip6-loopback
  ff02::1 ip6-allnodes
  ff02::2 ip6-allrouters
  <host-IP> <hostname>
  10.0.2.100 <hostname>
== 3. lookup order (/etc/nsswitch.conf) ==
hosts:          files dns
== 4. getent hosts localhost (uses the same order as programs) ==
::1             localhost ip6-localhost ip6-loopback
== 5. DNS tools here? ==
  dig: নেই
  nslookup: নেই
  host: নেই
  resolvectl: নেই
== 6. two names through DNS ==
  example.com: found, 4 distinct addresses (not shown)
  does-not-exist.invalid: exit 2 = name not found

resolv.conf: প্রথম nameserver 10.0.2.3 — একটি private ঠিকানা; এ ধরনের user-mode ভার্চুয়াল নেটওয়ার্কে এটি সাধারণত একটি DNS forwarder, যা প্রশ্ন বাইরের আসল resolver-এ পাঠায়। বাকি চারটি resolver-এর ঠিকানা স্ক্রিপ্ট ঢেকে দিয়েছে (<resolver-IP>). লক্ষ করুন, তালিকায় ৫টি nameserver, কিন্তু glibc শুধু প্রথম ৩টি ব্যবহার করে — বাকি দুটি অকেজো। hosts: localhost আর IPv6-এর লাইনগুলো প্রায় সব Linux-এ একই; container-এর নিজের নামের লাইনগুলো ঢাকা। nsswitch: hosts: files dns — আগে /etc/hosts, না পেলে DNS. তাই ধাপ ৪-এ localhost এল hosts ফাইল থেকেই (::1, কারণ getent hosts IPv6 ঠিকানা আগে দেখায়), কোনো DNS প্রশ্ন যায়নি। টুল: এখানে dig, nslookup, host নেই (পর্ব ০৬-এও দেখেছেন), তাই getent ব্যবহার — এটি প্রোগ্রামগুলোর মতো একই glibc পথে খোঁজে, যা dig করে না (dig hosts ফাইল দেখে না, সরাসরি DNS-এ যায়)। শেষ ধাপ: সাধারণ বাইরের সংযোগ না থাকলেও এই রানারে নাম খোঁজা কাজ করল — forwarder-এর মাধ্যমে। example.com-এর ৪টি আলাদা ঠিকানা এল (IPv4 আর IPv6 মিলিয়ে; আসল ঠিকানা ছাপা হয়নি, আর সংখ্যাটি সময়ের সাথে বদলাতে পারে)। .invalid সংরক্ষিত TLD, তাই সেই নাম কখনো থাকবে না — getent exit code 2 দিল, যা DNS-এর NXDOMAIN-এর মতো “নাম নেই”। Resolver পৌঁছানোর বাইরে থাকলে একই কমান্ড কয়েক সেকেন্ড আটকে থেকে (resolv.conf-এর timeout আর attempts) ব্যর্থ হতো — সেজন্য স্ক্রিপ্টে timeout 8.

একটি সাধারণ Linux ল্যাপটপে (ইন্টারনেট আছে, dig ইনস্টল করা) একই প্রশ্নের চেহারা এরকম — header-এর flag আর section-গুলো অংশ ৭-এর সাথে মিলিয়ে দেখুন:

$ dig www.example.com A

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6699
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
www.example.com.        3543    IN      CNAME   web.example.com.
web.example.com.        243     IN      A       192.0.2.80

;; Query time: 3 msec
;; SERVER: 127.0.0.53#53(127.0.0.53) (UDP)
;; MSG SIZE  rcvd: 78

TTL ৩,৫৪৩ আর ২৪৩ — দুটোই মূল মান (৩,৬০০ আর ৩০০) থেকে ৫৭ সেকেন্ড কম, অর্থাৎ উত্তরটি cache থেকে, কেউ প্রায় এক মিনিট আগে এটি এনেছিল। আকার ৭৮ বাইট: অংশ ৭-এর ৬৭ বাইটের উত্তর আর EDNS-এর ১১ বাইটের OPT record. aa flag নেই — authoritative নয়। dig +trace www.example.com নিজেই root থেকে ধাপে ধাপে খোঁজে (stepper ১-এর মতো), dig -x 192.0.2.80 PTR খোঁজে, আর dig @ns1.example.com example.com SOA একটি নির্দিষ্ট সার্ভারকে সরাসরি জিজ্ঞেস করে।

PS> Resolve-DnsName www.example.com -Type A     # dig-এর মতো, Windows-এ
PS> nslookup www.example.com                     # পুরোনো, Windows আর macOS দুটোতেই
PS> ipconfig /displaydns                         # Windows-এর stub cache দেখা
PS> ipconfig /flushdns                           # সেই cache মুছে ফেলা
# hosts ফাইল: C:\Windows\System32\drivers\etc\hosts

Linux-এ systemd-resolved-এর cache মুছতে resolvectl flush-caches; macOS-এ সাধারণত sudo dscacheutil -flushcache আর sudo killall -HUP mDNSResponder (সংস্করণ ভেদে একটু আলাদা)। মনে রাখবেন, নিজের যন্ত্রের cache মুছলেও ISP-র resolver-এর cache থেকে যায়।

৯ · Load balancing, নিরাপত্তা, গোপনীয়তা আর সমস্যা খোঁজা

DNS দিয়ে ট্রাফিক ভাগ করা

একটি নামের একাধিক A record থাকলে সার্ভার প্রতিবার ক্রম ঘুরিয়ে দিতে পারে — round-robin DNS, সবচেয়ে সরল load balancing. তবে DNS জানে না কোন সার্ভার মরে গেছে, আর cache-এর কারণে ভাগ সমান হয় না। আরও বুদ্ধিমান authoritative সার্ভার প্রশ্নকারী resolver-এর অবস্থান দেখে কাছের data center-এর ঠিকানা দেয়, অসুস্থ সার্ভার বাদ দেয় — CDN-গুলো ঠিক এভাবে ব্যবহারকারীকে কাছের সার্ভারে পাঠায় (পর্ব ৩৮, web cache আর CDN). এখানে ছোট TTL (৩০–৩০০ সেকেন্ড) জরুরি, যাতে সিদ্ধান্ত দ্রুত বদলানো যায়।

Cache poisoning — জাল উত্তর বিশ্বাস করানো

UDP-তে resolver একটি উত্তর গ্রহণ করে যদি তা ঠিক সার্ভারের ঠিকানা থেকে, ঠিক port-এ, ঠিক ID নিয়ে আসে। কেউ যদি আসল উত্তরের আগে এগুলো অনুমান করে জাল উত্তর পাঠাতে পারে, resolver সেটি cache-এ রেখে TTL ধরে হাজারো ব্যবহারকারীকে ভুল ঠিকানা দেবে — cache poisoning. ২০০৮ সালে Dan Kaminsky দেখান যে অস্তিত্বহীন উপ-নাম দিয়ে এই অনুমানের সুযোগ প্রায় অসীমবার পাওয়া যায়, ফলে শুধু ১৬ bit-এর ID-র ওপর নির্ভর করা বিপজ্জনক (ইতিহাসটি পর্ব ২৮-এর ভাবনার প্রশ্নে আছে)। প্রতিরক্ষা স্তরে স্তরে:

  • এলোমেলো ID আর এলোমেলো উৎস port (source port randomization) — অনুমানের জায়গা কয়েক হাজার গুণ বাড়ে (RFC 5452).
  • 0x20 encoding — প্রশ্নের নামে বড়-ছোট অক্ষর এলোমেলো মেশানো (wWw.ExAmPle.cOm); DNS case-insensitive হলেও উত্তরে প্রশ্নের হুবহু বানান ফেরে, তাই জাল উত্তরকে সেটাও অনুমান করতে হয়। সব resolver এটি ব্যবহার করে না।
  • Bailiwick যাচাই — example.com-এর সার্ভারের উত্তরে অন্য domain-এর record এলে বিশ্বাস না করা।
  • DNSSEC — শেষ কথা: cryptographic স্বাক্ষর।

DNSSEC-এর বিশ্বাসের শিকল — ধারণা

DNSSEC (মূল মান RFC 4033–4035, ২০০৫) record গোপন করে না, শুধু প্রমাণ করে যে record zone-মালিকের লেখা আর পথে বদলায়নি। প্রতিটি record-সেটের সাথে একটি স্বাক্ষর RRSIG; স্বাক্ষর যাচাইয়ের public key থাকে zone-এর DNSKEY record-এ। কিন্তু সেই key-কে বিশ্বাস কেন? কারণ parent zone-এ (.com) child-এর key-এর একটি hash রাখা থাকে — DS record, যা parent নিজের key দিয়ে স্বাক্ষর করে। এভাবে example.com-এর key-কে নিশ্চিত করে .com, .com-কে root, আর root-এর key resolver-এ আগে থেকে বসানো থাকে (trust anchor; root zone ২০১০ সালে স্বাক্ষরিত হয়) — এটিই chain of trust. যাচাই সফল হলে resolver উত্তরে AD bit বসায়; ব্যর্থ হলে SERVFAIL দেয়। বিস্তারিত cryptography পর্ব ৪৭–৪৮-এ, আক্রমণের প্রেক্ষাপট পর্ব ৫০-এ।

গোপনীয়তা — DoT, DoH, QNAME minimisation আর filtering

সাধারণ DNS এনক্রিপ্ট করা নয়: পথের যে-কেউ (Wi-Fi-র মালিক, ISP) দেখতে পারেন আপনি কোন নাম খুঁজছেন, এমনকি বদলেও দিতে পারেন। সমাধানগুলো:

ব্যবস্থাকী করেসীমা
DoT — DNS over TLS (RFC 7858)stub ↔ resolver পথে TLS, TCP port 853আলাদা port, তাই নেটওয়ার্ক সহজে চিনে আটকাতে পারে
DoH — DNS over HTTPS (RFC 8484)DNS বার্তা HTTPS-এর ভেতরে, port 443সাধারণ ওয়েব ট্রাফিকের সাথে মিশে যায় — অফিসের নীতি প্রয়োগ কঠিন হয়; ব্রাউজার OS-এর সেটিং এড়িয়ে নিজের resolver বাছতে পারে
DNS over QUIC (RFC 9250)QUIC-এর ওপর, সাধারণত UDP 853নতুন, সমর্থন সীমিত
QNAME minimisation (RFC 7816, পরে 9156)resolver root-কে শুধু com., TLD-কে শুধু example.com. জিজ্ঞেস করে — পুরো নাম শুধু authoritative-এর কাছেresolver নিজে সব দেখে; এনক্রিপশন নয়
DNS-ভিত্তিক filteringresolver ক্ষতিকর বা নিষিদ্ধ নামের উত্তর দেয় না (NXDOMAIN বা একটি সতর্কতা-পাতার ঠিকানা) — অফিস, স্কুল, অভিভাবক নিয়ন্ত্রণ, malware ঠেকানোঅন্য resolver বা DoH ব্যবহার করে এড়ানো যায়; ভুল তালিকায় বৈধ সাইটও আটকায়

লক্ষ করুন, DoT/DoH আর DNSSEC দুটি আলাদা সমস্যার সমাধান: প্রথমটি পথের গোপনীয়তা (stub ↔ resolver), দ্বিতীয়টি তথ্যের সত্যতা (মালিক থেকে resolver পর্যন্ত)। আর DNS এনক্রিপ্ট করলেও যে ঠিকানায় পরে সংযোগ হয়, আর TLS-এর SNI (পর্ব ৪৮) থেকে অনেক কিছু বোঝা যায়।

এই আলোচনা শুধু বোঝা আর প্রতিরক্ষার জন্য। অন্যের resolver-এ জাল উত্তর পাঠানো, অন্যের zone-এ AXFR চেষ্টা বা ঠিকানা-পরিসর স্ক্যান করা অনৈতিক এবং আইনত দণ্ডনীয় হতে পারে। নিজের সার্ভারে যাচাই করুন: recursive resolver শুধু নিজের নেটওয়ার্কের জন্য খোলা কি না, AXFR শুধু secondary-দের জন্য কি না, সফটওয়্যার হালনাগাদ কি না।

আরও গভীরে: বড় resolver-গুলো cache-কে আরও কাজে লাগায় — “aggressive NSEC” (RFC 8198) DNSSEC-এর অস্তিত্বহীনতার প্রমাণ থেকে পুরো একটি পরিসরের নাম “নেই” বলে ধরে নেয়, আর “serve-stale” (RFC 8767) authoritative সার্ভার পৌঁছানো না গেলে মেয়াদোত্তীর্ণ উত্তরও কিছুক্ষণ দেয়। কিছু resolver root zone-এর পুরো কপি নিজের কাছে রাখে (RFC 8806), ফলে root-এ প্রশ্নই যায় না। আর resolver-এর ভেতরে প্রায়ই প্রতিটি সার্ভারের মাপা RTT অনুযায়ী দ্রুততম NS বাছাই হয় — BIND, Unbound, Knot Resolver, PowerDNS Recursor-এর উৎস-কোডে এই কৌশলগুলো পড়া যায়।

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

  • Iterative আর recursive query-র পার্থক্য? — recursive-এ সার্ভার পুরো উত্তর এনে দেয় (stub → resolver); iterative-এ সার্ভার যা জানে বা referral দেয়, প্রশ্নকারী নিজে পরের জনকে জিজ্ঞেস করে (resolver → root/TLD/authoritative).
  • Cache ফাঁকা থাকলে একটি নাম খুঁজতে কয়টি বার্তা? — সাধারণ পাঠ্যবইয়ের মডেলে ৮টি: stub ↔ resolver ২, root, TLD আর authoritative-এর সাথে ২টি করে ৬।
  • DNS কোন transport আর port? — UDP 53; বড় উত্তর (TC bit) আর zone transfer-এ TCP 53; DoT 853, DoH 443.
  • Glue record কেন লাগে? — NS-এর নাম নিজেই delegate হওয়া zone-এর ভেতরে হলে তার ঠিকানা জানার আর পথ থাকে না; parent তাই additional section-এ ঠিকানাটিও দেয়।
  • “google.com লিখে Enter চাপলে” প্রথম কী হয়? — ব্রাউজার আর OS cache, /etc/hosts, তারপর resolver — DNS দিয়েই যাত্রা শুরু (পুরো উত্তর পর্ব ৬২-এ)।

সমস্যা খোঁজা — NXDOMAIN, SERVFAIL, timeout আর পুরোনো cache

“সাইট খুলছে না, DNS-এর সমস্যা মনে হচ্ছে” — প্রথমে বুঝুন কোন সমস্যা। তিনটি ফল দেখতে একই রকম (“not found”), কিন্তু কারণ সম্পূর্ণ আলাদা:

ফলমানেসাধারণ কারণকী দেখবেন
NXDOMAIN (RCODE 3)authoritative সার্ভার নিশ্চিতভাবে বলছে: এই নাম নেইবানান ভুল; domain-এর মেয়াদ শেষ; record এখনো যোগ হয়নি; negative cacheবানান; dig @authoritative; registrar-এ মেয়াদ
SERVFAIL (RCODE 2)resolver উত্তর জোগাড় করতে পারেনিauthoritative সার্ভার বন্ধ বা ভুল উত্তর; DNSSEC যাচাই ব্যর্থ (মেয়াদোত্তীর্ণ স্বাক্ষর, ভুল DS); delegation ভাঙা (lame)dig +cd দিয়ে চললে DNSSEC সমস্যা; dig +trace; প্রতিটি NS আলাদা জিজ্ঞেস
Timeoutকেউ উত্তরই দেয়নিresolver-এ পৌঁছানো যায় না; firewall UDP 53 আটকাচ্ছে; বড় উত্তরের fragment হারাচ্ছেresolv.conf-এর nameserver-এ ping; অন্য resolver দিয়ে চেষ্টা; +tcp
পুরোনো ঠিকানাউত্তর আসছে, কিন্তু আগেরকোনো স্তরের cache-এ পুরোনো record, TTL এখনো ফুরায়নি; /etc/hosts-এ পুরোনো লাইনauthoritative আর resolver-এর উত্তর মিলিয়ে দেখুন; TTL কত বাকি; hosts ফাইল
REFUSED (RCODE 5)সার্ভার এই প্রশ্নের উত্তর দিতে রাজি নয়resolver আপনার নেটওয়ার্কের জন্য খোলা নয়; authoritative-কে অন্য zone জিজ্ঞেসঠিক সার্ভারকে জিজ্ঞেস করছেন কি না

একটি পদ্ধতি: (১) getent hosts নাম — OS কী দেখছে (hosts ফাইলসহ); (২) dig নাম — resolver কী দিচ্ছে, status আর TTL; (৩) dig @অন্য-resolver নাম — সমস্যা কি শুধু আপনার resolver-এ; (৪) dig +trace নাম — গাছের কোন ধাপে ভাঙছে; (৫) নাম ছাড়া সরাসরি IP-তে সংযোগ — DNS আদৌ দায়ী কি না। পদ্ধতিগত সমস্যা-খোঁজা পর্ব ৫৫-এ।

১০ · AI-এর যুগে DNS — record, কমান্ড আর নিরাপত্তার পরামর্শ যাচাই

“আমার domain-এর DNS ঠিক করে দিন” — AI দ্রুত zone ফাইল বা dig কমান্ড লিখে দেবে। কিন্তু DNS-এর ভুল সাথে সাথে ধরা পড়ে না; TTL-এর কারণে ঘণ্টা বা দিন পরে, অন্য কারও resolver-এ। AI-এর পরিচিত ভুলগুলো:

AI-এর ভুলকেন ভুলকীভাবে ধরবেন
apex-এ (example.com) CNAME বসানোর পরামর্শ, বা CNAME-এর পাশে MXCNAME অন্য record-এর সাথে থাকতে পারে না; apex-এ SOA/NS থাকেইzone ফাইল named-checkzone দিয়ে যাচাই; সেবাদাতার ALIAS/flattening-এর নথি পড়ুন
“propagation-এ ৪৮ ঘণ্টা লাগবে, অপেক্ষা করুন”সময় নির্ভর করে পুরোনো TTL-এর ওপর; সমস্যা অন্য জায়গায় হতে পারেdig @authoritative দিয়ে নতুন record সত্যিই আছে কি না দেখুন; resolver-এর বাকি TTL দেখুন
trailing dot বাদ দেওয়া zone ফাইল (mail.example.com শেষে বিন্দু ছাড়া)zone ফাইলে বিন্দু ছাড়া নামের পেছনে origin জুড়ে যায় → mail.example.com.example.com.লোড করার পর dig দিয়ে আসল নাম দেখুন
Serial না বাড়িয়ে zone বদলsecondary বদল দেখে না, দুই সার্ভার আলাদা উত্তর দেয়প্রতিটি NS-কে আলাদা করে SOA জিজ্ঞেস করে serial মেলান
“resolver-এ allow-recursion { any; } দিন, সমস্যা মিটবে”open resolver তৈরি হয় — amplification-এর প্রতিফলকশুধু নিজের নেটওয়ার্কের ঠিকানা-পরিসর অনুমতি দিন
PTR-এর নাম ভুল ক্রমে বা IPv6-এর শূন্য বাদ দিয়েঅক্টেট/nibble উল্টো ক্রমে আর পুরো ৩২টি nibble লাগেঅংশ ৬-এর simulator বা dig -x দিয়ে মিলিয়ে নিন
পুরোনো বা ভুল কমান্ড (nslookup-কে একমাত্র পথ বলা, systemd-resolved থাকা যন্ত্রে resolv.conf হাতে বদলানো) বা বানানো RFC নম্বরdistro ভেদে আলাদা; হাতে বদল পরের reboot-এ মুছে যেতে পারে; ভাষার মডেল বিশ্বাসযোগ্য নম্বর বানাতে পারেman resolv.conf, man resolvectl; rfc-editor.org-এ শিরোনাম মেলান: 1034/1035, 2308, 4033, 7858, 8484, 9460

AI-কে DNS-এর কাজ দিলে শর্তগুলো আগেই বলে দিন:

আমার domain example.com-এর জন্য একটি BIND zone ফাইল লিখে দাও: ওয়েব সার্ভার 192.0.2.80 আর 2001:db8::80, মেইল সার্ভার mail.example.com (192.0.2.25), www একটি CNAME. ১. প্রতিটি record-এর TTL কেন এই মান দিলে, ব্যাখ্যা করো; পরিবর্তনের আগে TTL কমানোর পরিকল্পনাও বলো। ২. CNAME কোথায় বৈধ আর কোথায় নয় (apex, MX-এর লক্ষ্য), তা যাচাই করে বলো। ৩. SOA-র serial, refresh, retry, expire, minimum-এর মান আর কারণ দাও। ৪. সব পূর্ণ নামের শেষে বিন্দু আছে কি না নিজে আবার দেখো, আর named-checkzone দিয়ে যাচাইয়ের কমান্ড দাও। ৫. কোনো RFC বা ডিফল্ট মানের কথা বললে নম্বর দাও; নিশ্চিত না হলে স্পষ্ট বলো।

AI-এর DNS পরামর্শ ব্যবহারের আগে — চেকলিস্ট

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

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

প্র ০১HOSTS.TXT-এর মতো একটি কেন্দ্রীয় ফাইল কেন টিকল না, আর DNS-এর কোন নকশা-সিদ্ধান্তগুলো চার দশক পরেও কোটি কোটি নাম সামলাতে পারছে?

HOSTS.TXT-এর সমস্যাগুলো আজকের যেকোনো কেন্দ্রীয় ব্যবস্থার শিক্ষা। প্রথমত, আকার আর চাপ: প্রতিটি host পুরো ফাইল নামাত, তাই host বাড়লে ফাইলও বড় হয় আর নামানোর সংখ্যাও বাড়ে — চাপ বাড়ে প্রায় বর্গাকারে, আর পুরোটা পড়ে একটি প্রতিষ্ঠানের সার্ভারের ঘাড়ে। দ্বিতীয়ত, দেরি: নতুন কম্পিউটারের নাম সবার কাছে পৌঁছাতে দিন লাগত, কারণ সবাই নিজের সময়ে নামাত। তৃতীয়ত, নামের দ্বন্দ্ব: সমতল নামের জগতে দুটি প্রতিষ্ঠান একই নাম চাইলে কেন্দ্রকে বিচারক হতে হতো। চতুর্থত, প্রশাসনিক বাধা: প্রতিটি বদলে একটি অফিসের মাধ্যমে যেতে হতো।

Mockapetris-এর নকশা প্রতিটি সমস্যার আলাদা উত্তর দেয়। স্তরভিত্তিক নাম দ্বন্দ্ব মেটায় — mail.example.com আর mail.example.org দুটোই বৈধ, কারণ নাম অনন্য হয় শুধু নিজের শাখার ভেতরে। Delegation প্রশাসন ভাগ করে — .com-এর registry জানতেও পারে না আপনি example.com-এর ভেতরে কয়টি নাম রাখলেন; আপনার নিজের zone, নিজের সময়ে বদল। আর caching চাপ ভাগ করে — জনপ্রিয় তথ্য বারবার পাওয়া যায় কাছের resolver থেকে, মালিকের সার্ভারে প্রশ্ন যায় শুধু TTL ফুরালে। লক্ষ করুন, TTL দিয়ে মালিকই ঠিক করেন তথ্য কতটা “তাজা” রাখতে হবে — নির্ভুলতা আর চাপের মধ্যে বিনিময় প্রতিটি record-এর জন্য আলাদা।

আরেকটি দূরদর্শী সিদ্ধান্ত ছিল DNS-কে শুধু “নাম → ঠিকানা” না বানিয়ে সাধারণ একটি বিতরণকৃত ডেটাবেস বানানো: record-এর type সম্প্রসারণযোগ্য। তাই ১৯৮৭-র নকশায় পরে যোগ হয়েছে AAAA (IPv6), SRV, DNSSEC-এর record, CAA, HTTPS — মূল protocol না বদলে। সীমাবদ্ধতাও ছিল: শুরুর নকশায় নিরাপত্তা প্রায় ছিল না, আর বার্তার ৫১২ বাইটের সীমা দশকের পর দশক ঝামেলা দিয়েছে (EDNS, TCP fallback). তবু ইন্টারনেটের সবচেয়ে সফল বিতরণকৃত ব্যবস্থাগুলোর মধ্যে DNS একটি — যেকোনো বড় সিস্টেম ডিজাইন ইন্টারভিউতে “cache, partition, delegation” যে তিনটি শব্দ আসে, DNS তাদের পাঠ্যবইয়ের উদাহরণ।

মূল উপলব্ধি: বড় হতে হলে কেন্দ্রকে ছোট রাখতে হয়। DNS-এর root zone আজও ছোট, কারণ প্রতিটি স্তর শুধু নিচের স্তরের ঠিকানা জানে, পুরো তথ্য নয় — আর caching সেই ছোট কেন্দ্রকেও বেশিরভাগ চাপ থেকে আড়াল করে।

প্র ০২সব root server একসাথে কয়েক ঘণ্টা বন্ধ থাকলে ইন্টারনেটের কী হবে? Root-এর ওপর আক্রমণের ইতিহাস আর caching-এর ভূমিকা দিয়ে ব্যাখ্যা করুন।

অনেকে ভাবেন root বন্ধ মানে ইন্টারনেট বন্ধ। বাস্তবে প্রভাব প্রথম কয়েক ঘণ্টায় খুব কম হওয়ার কথা, আর কারণ caching. Root zone-এ TLD-গুলোর NS record-এর TTL সাধারণত দুই দিন। একটি ব্যস্ত resolver প্রতিনিয়ত .com, .org, .bd-এর নাম খোঁজে, তাই এই referral-গুলো প্রায় সবসময় তার cache-এ থাকে। Root-এ নতুন প্রশ্ন যায় মূলত তখন, যখন কোনো TLD-এর তথ্য মেয়াদোত্তীর্ণ হয়, বা কেউ অস্তিত্বহীন TLD খোঁজে — আর বাস্তবে root-এ আসা প্রশ্নের বড় অংশই শেষের ধরনের (ভুল বানান, ভেতরের নেটওয়ার্কের নাম বাইরে ফাঁস হওয়া)। কয়েক ঘণ্টা root বন্ধ থাকলে জনপ্রিয় TLD প্রায় সবার cache-এ টিকে থাকবে; দীর্ঘ হলে আস্তে আস্তে মেয়াদ ফুরিয়ে সমস্যা ছড়াবে।

ইতিহাসে root server-গুলো কয়েকবার বড় DDoS-এর শিকার হয়েছে — যেমন অক্টোবর ২০০২-এ এবং ফেব্রুয়ারি ২০০৭-এ বহুল আলোচিত আক্রমণ, আর পরেও কয়েকবার। প্রকাশিত বিশ্লেষণ অনুযায়ী কিছু root server তখন অনেক প্রশ্নের উত্তর দিতে পারেনি, কিন্তু সাধারণ ব্যবহারকারীরা তেমন কিছু টের পাননি — caching আর ১৩টি নামের মধ্যে বৈচিত্র্য রক্ষা করেছে। এসব অভিজ্ঞতার পর root অপারেটররা ব্যাপকভাবে anycast-এ ছড়িয়েছেন (পর্ব ২৫-এ দেখেছেন), যাতে আক্রমণের ট্রাফিক বহু জায়গায় ভাগ হয়ে যায় আর প্রতিটি অঞ্চলের ব্যবহারকারী কাছের instance পান।

আরও দুটি প্রতিরক্ষা এখন আছে। এক, “serve-stale” (RFC 8767): authoritative সার্ভারে পৌঁছানো না গেলে resolver কিছুক্ষণ মেয়াদোত্তীর্ণ উত্তরও দিতে পারে — একেবারে কিছু না দেওয়ার চেয়ে ভালো। দুই, resolver নিজেই root zone-এর পুরো কপি রাখতে পারে (RFC 8806) — root zone ছোট আর DNSSEC দিয়ে স্বাক্ষরিত, তাই কপি বিশ্বাসযোগ্য। তবে মনে রাখুন, বাস্তবে বড় বিভ্রাট বেশি হয়েছে নিচের স্তরে: একটি বড় DNS সেবাদাতা বা একটি বড় কোম্পানির নিজস্ব authoritative সার্ভার পৌঁছানোর বাইরে চলে গেলে তার সব গ্রাহকের নাম একসাথে অদৃশ্য হয় (প্র ০৪)।

মূল উপলব্ধি: DNS-এর দৃঢ়তা আসে ওপরের স্তরের দীর্ঘ TTL, বহু অপারেটর আর anycast থেকে। গাছের গোড়া সবচেয়ে শক্ত — দুর্বলতা সাধারণত নিচের শাখায়, যেখানে একটি প্রতিষ্ঠান একটি সেবাদাতার ওপর পুরো নির্ভর করে।

প্র ০৩DNSSEC আর DNS over HTTPS প্রায়ই একসাথে “নিরাপদ DNS” বলা হয়। এরা আসলে কোন দুটি আলাদা সমস্যা সমাধান করে, আর DoH নিয়ে বিতর্ক কেন?

DNS-এর পথে দুটি আলাদা প্রশ্ন আছে: “উত্তরটি কি আসল?” আর “আমি কী খুঁজছি, তা কে দেখছে?” DNSSEC প্রথম প্রশ্নের উত্তর দেয়। zone-এর মালিক record-এ স্বাক্ষর করেন, আর resolver root থেকে শিকল ধরে সেই স্বাক্ষর যাচাই করে। পথে কেউ উত্তর বদলালে বা cache poisoning করলে স্বাক্ষর মিলবে না। কিন্তু DNSSEC কিছুই গোপন করে না — প্রশ্ন আর উত্তর খোলা অবস্থায় যায়। আর সাধারণত যাচাই হয় resolver-এ; resolver থেকে আপনার ল্যাপটপ পর্যন্ত শেষ পথটুকু (AD bit) নিজে সুরক্ষিত নয়।

DoT/DoH দ্বিতীয় প্রশ্নের উত্তর দেয়: stub থেকে resolver পর্যন্ত TLS-এর ভেতরে, তাই ক্যাফের Wi-Fi বা পথের কোনো যন্ত্র দেখতে বা বদলাতে পারে না। কিন্তু resolver নিজে সব দেখে, আর resolver যদি authoritative-এর কাছ থেকে জাল উত্তর পায়, DoH সেটি ঠেকায় না। তাই পূর্ণ সুরক্ষায় দুটোই লাগে — একটি পথের গোপনীয়তা, অন্যটি তথ্যের সত্যতা।

DoH-এর বিতর্ক মূলত নিয়ন্ত্রণ নিয়ে। ২০২০ সালের দিকে কিছু ব্রাউজার কিছু দেশে ডিফল্টভাবে DoH চালু করা শুরু করে, নিজের বাছাই করা resolver-এ। সমর্থকেরা বলেন: ISP বা পথের নজরদারি থেকে সাধারণ মানুষের সুরক্ষা। সমালোচকেরা বলেন: প্রতিষ্ঠানের নেটওয়ার্ক প্রশাসক DNS-ভিত্তিক malware ঠেকানো আর নীতি প্রয়োগ হারান, অভিভাবক নিয়ন্ত্রণ এড়ানো যায়, আর অনেক দেশের মানুষের নাম-খোঁজা কয়েকটি বড় resolver-চালকের কাছে কেন্দ্রীভূত হয়। ব্রাউজারগুলো তাই কিছু মাঝামাঝি পথ নিয়েছে — যেমন প্রতিষ্ঠানের নীতি (enterprise policy) থাকলে বা একটি বিশেষ “canary” নাম দিয়ে নেটওয়ার্ক জানালে DoH ডিফল্টভাবে বন্ধ রাখা। এই খুঁটিনাটি ব্রাউজার আর সংস্করণ ভেদে বদলায়।

মূল উপলব্ধি: “নিরাপদ” শব্দটি সবসময় জিজ্ঞেস করুন — কার থেকে নিরাপদ? DNSSEC জালিয়াতি থেকে, DoH পথের নজরদারি থেকে; কোনোটিই resolver-চালকের কাছ থেকে নয়। প্রযুক্তির সিদ্ধান্ত এখানে বিশ্বাস কাকে করবেন, সেই সিদ্ধান্তও।

প্র ০৪অক্টোবর ২০১৬-এর Dyn আক্রমণ আর অক্টোবর ২০২১-এর Facebook বিভ্রাট — দুটিতেই DNS কেন্দ্রে ছিল। একটি প্রতিষ্ঠান তার DNS কীভাবে সাজালে এমন ঝুঁকি কমে?

অক্টোবর ২০১৬-এ Dyn নামের একটি বড় managed DNS সেবাদাতার authoritative সার্ভারে বিশাল DDoS হয়, যার বড় অংশ এসেছিল Mirai নামের botnet-এ দখল হওয়া IoT যন্ত্র (ক্যামেরা, DVR) থেকে — এমনটাই প্রকাশিত বিশ্লেষণে বলা হয়। Dyn-এর গ্রাহক ছিল বহু পরিচিত ওয়েবসাইট, যাদের নিজেদের সার্ভার পুরোপুরি সুস্থ ছিল; কিন্তু resolver-গুলো তাদের নামের উত্তর পাচ্ছিল না, ফলে কিছু অঞ্চলের ব্যবহারকারীর কাছে সাইটগুলো কয়েক ঘণ্টা অদৃশ্য ছিল। শিক্ষা: আপনার সব NS একটি সেবাদাতার হাতে থাকলে সেই সেবাদাতা আপনার single point of failure.

অক্টোবর ২০২১-এ Facebook-এর বিভ্রাট অন্য রকম। প্রকাশিত ব্যাখ্যা অনুযায়ী একটি রক্ষণাবেক্ষণ-কমান্ডের ভুলে backbone বিচ্ছিন্ন হয়, আর তাদের authoritative DNS সার্ভারগুলো — নকশা অনুযায়ী backbone-এর সাথে যোগাযোগ না পেলে — নিজেদের anycast route প্রত্যাহার করে নেয় (পর্ব ২৫)। ফলে পুরো পৃথিবীর resolver-এর কাছে facebook.com-এর NS পৌঁছানোর অযোগ্য হয়, আর SERVFAIL ছড়িয়ে পড়ে। এখানে শিক্ষা: স্বয়ংক্রিয় নিরাপত্তা-ব্যবস্থা ভুল পরিস্থিতিতে সবকিছু একসাথে বন্ধ করতে পারে, আর পুনরুদ্ধারের পথ মূল ব্যবস্থার ওপর নির্ভরশীল হওয়া উচিত নয়।

নকশার পরামর্শগুলো তাই: (১) অন্তত দুটি স্বাধীন DNS সেবাদাতা বা নিজের আর একটি বাইরের সেবা, আলাদা নেটওয়ার্ক আর আলাদা AS-এ — দুজনের মধ্যে zone একই রাখার ব্যবস্থাসহ (DNSSEC থাকলে এটি জটিল, পরিকল্পনা লাগে)। (২) NS আর গুরুত্বপূর্ণ record-এ যুক্তিসংগত দীর্ঘ TTL, যাতে সংক্ষিপ্ত বিভ্রাটে cache রক্ষা করে; শুধু দ্রুত বদলাতে হয় এমন record-এ ছোট TTL. (৩) ভেতরের জরুরি টুল আর যোগাযোগের বিকল্প পথ, যা মূল DNS-এর ওপর নির্ভর করে না। (৪) নিয়মিত পরীক্ষা: একটি NS বন্ধ করে দেখা সেবা চলে কি না।

মূল উপলব্ধি: DNS সবকিছুর আগে আসে, তাই DNS-এর বিভ্রাট সবকিছুর বিভ্রাট। নিরাপত্তা মানে শুধু আক্রমণ ঠেকানো নয় — নির্ভরতার মানচিত্র আঁকা, আর প্রতিটি একক বিন্দুর বিকল্প রাখা।

প্র ০৫TTL ছোট রাখবেন না বড়? দ্রুত failover, resolver-এর চাপ, খরচ আর বিভ্রাট-সহনশীলতার বিনিময় বিশ্লেষণ করুন।

TTL হলো zone-মালিকের একটি প্রতিশ্রুতি: “এই সময়ের মধ্যে উত্তর বদলালে পুরোনোটা ব্যবহার হলেও আমি মেনে নেব।” ছোট TTL (৩০–৩০০ সেকেন্ড) মানে বদল দ্রুত সবার কাছে পৌঁছায়: একটি সার্ভার মরে গেলে DNS-ভিত্তিক failover মিনিটের মধ্যে কাজ করে, CDN ব্যবহারকারীকে মুহূর্তের অবস্থা অনুযায়ী অন্য data center-এ পাঠাতে পারে। খরচ: resolver-কে বারবার authoritative-এ যেতে হয় — বেশি প্রশ্ন (managed DNS-এ প্রায়ই প্রতি প্রশ্নে বিল), ব্যবহারকারীর জন্য বেশি cache miss আর বাড়তি delay, আর authoritative বিভ্রাটে সাথে সাথে প্রভাব — cache-এর রক্ষাকবচ প্রায় থাকে না।

বড় TTL (কয়েক ঘণ্টা থেকে দিন) উল্টোটা দেয়: কম প্রশ্ন, বেশিরভাগ ব্যবহারকারীর জন্য cache hit, আর authoritative সার্ভার কিছুক্ষণ বন্ধ থাকলেও অনেকে টের পান না। দাম: ভুল record বসালে বা জরুরি বদল লাগলে সংশোধন পৌঁছাতে দীর্ঘ সময়, আর বাস্তবে ভুল record-এর ক্ষতি দীর্ঘস্থায়ী হয়। তাই সাধারণ চর্চা: NS আর খুব স্থির record-এ বড় TTL, ঠিকানা-record-এ মাঝারি, আর failover বা CDN-এর record-এ ছোট; বড় বদলের আগে পরিকল্পিতভাবে TTL কমানো।

দুটি বাস্তব জটিলতা আছে। এক, সব cache TTL মানে না — কিছু অ্যাপ বা পুরোনো লাইব্রেরি নিজের মতো দীর্ঘ সময় ধরে রাখে (যেমন কিছু Java রানটাইমে ঠিকানা-cache-এর সেটিং নিয়ে পুরোনো সমস্যার কথা পরিচিত), আর কিছু resolver সর্বনিম্ন TTL বসায়। দুই, খুব ছোট TTL-এ resolver-এর সংখ্যা বেশি হলে authoritative-এর চাপ অনেক গুণ বাড়ে; গবেষণাগুলো দেখায় বড় অংশের প্রশ্ন আসলে cache-যোগ্য ছিল। এজন্য “TTL ৬০ রাখলেই নিরাপদ” কথাটি সব জায়গায় খাটে না।

মূল উপলব্ধি: TTL হলো তাজা তথ্য আর দৃঢ়তার মধ্যে একটি নব। সঠিক মান নির্ভর করে record-টি কত ঘন ঘন বদলায় আর বদল কত দ্রুত পৌঁছানো জরুরি তার ওপর — আর “propagation”-এর সব রহস্য এই একটি সংখ্যার মধ্যেই।

অনুশীলন

খাতা-কলম নিন — বার্তা, সময় আর বাইট ধরে ধরে হিসাব করুন।

  1. হিসাব (বার্তা আর সময়): একটি ল্যাপটপ থেকে local resolver-এর RTT ২ ms, resolver থেকে root ৩০ ms, .com TLD ৪০ ms, example.com-এর authoritative ৫০ ms. ধরুন সব প্রশ্ন iterative, আর processing সময় নগণ্য। (ক) Resolver-এর cache ফাঁকা হলে www.example.com খুঁজতে কত বার্তা আর কত সময়? (খ) .com-এর NS cache-এ থাকলে? (গ) ঠিক এর পরে mail.example.com খুঁজলে? (ঘ) তারপর ব্রাউজার www.example.com-এর HTML আনল (TCP handshake ১ RTT + request-response ১ RTT, সার্ভারের RTT ৮০ ms) — মোট সময় (ক)-এর ক্ষেত্রে কত?

    (ক) ৮টি বার্তা; সময় = ২ + ৩০ + ৪০ + ৫০ = ১২২ ms. (খ) Root বাদ: ৬টি বার্তা, ২ + ৪০ + ৫০ = ৯২ ms. (গ) এখন example.com-এর NS-ও cache-এ (প্রথম খোঁজায় জমেছে), কিন্তু mail-এর A নেই — resolver সোজা authoritative-এ: ৪টি বার্তা, ২ + ৫০ = ৫২ ms. (ঘ) DNS ১২২ + TCP handshake ৮০ + HTTP ৮০ = ২৮২ ms — প্রায় অর্ধেক সময় DNS-এ! এজন্যই ব্রাউজার আগেভাগে নাম খুঁজে রাখে (DNS prefetch), আর cache এত গুরুত্বপূর্ণ।

  2. আউটপুট অনুমান করুন: অংশ ৭-এর dns_message.js-এ শুধু প্রশ্নের নাম "www.example.com" বদলে "mail.example.org" করা হলো (আর q.slice(12, 29) সংখ্যাগুলো ঠিক করা হলো)। প্রথম চার লাইনে প্রশ্নের দৈর্ঘ্য আর qname-এর বাইট কী হবে? তারপর বলুন, ID বদলে 0x0001 করলে header-এর প্রথম ৪ বাইট কী?
    QUERY (34 bytes)
     header:     1a 2b 01 00 00 01 00 00 00 00 00 00
     qname:      04 6d 61 69 6c 07 65 78 61 6d 70 6c 65 03 6f 72 67 00
     type/class: 00 01 00 01

    নাম: ১ + ৪ (“mail”) + ১ + ৭ + ১ + ৩ (“org”) + ১ (শেষের 00) = ১৮ বাইট, তাই মোট ১২ + ১৮ + ৪ = ৩৪. ASCII-তে m = 6d, a = 61, i = 69, l = 6c; o = 6f, r = 72, g = 67. Slice হবে q.slice(12, 30) আর type/class q.slice(30). ID 0x0001 হলে প্রথম ৪ বাইট 00 01 01 00 — ID-র দুই বাইট, তারপর একই flag (RD = 1). (বাস্তবে ID এলোমেলো হওয়া উচিত — অংশ ৯-এর cache poisoning মনে করুন।)

  3. কমান্ড লিখুন: আপনার প্রতিষ্ঠানের example.com-এর ঠিকানা আজ বদলানো হয়েছে, কিন্তু কিছু সহকর্মী এখনো পুরোনো সার্ভারে যাচ্ছেন। Linux-এ (dig আছে) পাঁচটি কমান্ড লিখুন: (ক) নিজের resolver কী দিচ্ছে আর TTL কত বাকি; (খ) authoritative সার্ভার নিজে কী বলছে; (গ) দুটি NS-এর serial একই কি না; (ঘ) গাছ ধরে root থেকে পুরো পথ; (ঙ) নিজের যন্ত্রের systemd-resolved cache মোছা।
    dig www.example.com A                       # (ক) ANSWER-এর TTL = cache-এ বাকি সময়
    dig @ns1.example.com www.example.com A +norec   # (খ) সরাসরি authoritative; flags-এ aa থাকা উচিত
    dig @ns1.example.com example.com SOA +short; dig @ns2.example.net example.com SOA +short   # (গ) serial মেলান
    dig +trace www.example.com                  # (ঘ) root → .com → authoritative
    resolvectl flush-caches                     # (ঙ) শুধু নিজের যন্ত্রের stub cache

    (ক)-এর TTL যদি এখনো কয়েক ঘণ্টা দেখায়, তবে resolver-এ পুরোনো উত্তর আছে — অপেক্ষা ছাড়া উপায় নেই, বা resolver-এর প্রশাসক cache থেকে নামটি মুছতে পারেন। (খ) নতুন ঠিকানা দিলে authoritative ঠিক আছে; (গ)-তে serial আলাদা হলে secondary হালনাগাদ হয়নি — অর্ধেক প্রশ্ন পুরোনো উত্তর পাবে। এজন্য পরের বার বদলের আগে TTL কমিয়ে রাখার পরিকল্পনা করুন। Windows-এ (ঙ)-এর সমতুল্য ipconfig /flushdns; আর getent hosts www.example.com দেখাবে /etc/hosts-এ পুরোনো কোনো লাইন আছে কি না।

  4. হিসাব (SOA আর secondary): একটি zone-এর SOA: refresh ৭,২০০, retry ৯০০, expire ১,২০৯,৬০০, minimum ৩০০. Secondary সার্ভার শেষবার সফলভাবে primary-র সাথে মিলিয়েছে সোমবার দুপুর ১২:০০-এ, আর ঠিক তার পরেই primary স্থায়ীভাবে বন্ধ হয়ে গেল। (ক) Secondary প্রথম কখন primary-কে খুঁজবে? (খ) তারপর কত পরপর চেষ্টা করবে? (গ) কোন দিন কখন secondary zone-এর উত্তর দেওয়া বন্ধ করবে? (ঘ) এর মধ্যে কেউ অস্তিত্বহীন নাম খুঁজলে resolver সেই “নেই” কতক্ষণ মনে রাখতে পারে (SOA-র নিজের TTL ৩,৬০০ ধরে)?

    (ক) Refresh ৭,২০০ সেকেন্ড = ২ ঘণ্টা পর — সোমবার দুপুর ২:০০. (খ) ব্যর্থ হলে retry ৯০০ সেকেন্ড = প্রতি ১৫ মিনিট পরপর। (গ) Expire গোনা হয় শেষ সফল মেলানো থেকে: ১,২০৯,৬০০ সেকেন্ড = ১,২০৯,৬০০ ÷ ৮৬,৪০০ = ঠিক ১৪ দিন — দুই সপ্তাহ পরের সোমবার দুপুর ১২:০০-এ secondary zone-এর উত্তর দেওয়া বন্ধ করবে (তখন থেকে SERVFAIL). এই ১৪ দিন সে পুরোনো তথ্যই দিয়ে যাবে। (ঘ) Negative caching-এর TTL = SOA-র TTL আর minimum-এর মধ্যে ছোটটি = min(৩,৬০০, ৩০০) = ৩০০ সেকেন্ড.

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

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

ক্রমCache ফাঁকা অবস্থায় www.example.com খোঁজার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Stub resolver recursive resolver-কে RD = 1 দিয়ে প্রশ্ন পাঠায়
  2. Resolver root server-কে জিজ্ঞেস করে আর .com-এর NS তালিকা (referral) পায়
  3. Resolver .com TLD server-কে জিজ্ঞেস করে আর example.com-এর NS ও glue পায়
  4. Resolver example.com-এর authoritative server থেকে AA = 1 উত্তর পায়
  5. Resolver উত্তর cache-এ রেখে TTL-সহ stub-কে জানায়

একটি resolver-এর cache সম্পূর্ণ ফাঁকা। একটি ল্যাপটপ www.example.com খুঁজলে (root, TLD আর authoritative সবাই iterative উত্তর দেয়) ল্যাপটপ, resolver আর সার্ভারগুলোর মধ্যে মোট কয়টি DNS বার্তা আদান-প্রদান হয়?

  • ৩টি
  • ৬টি
  • ৮টি
  • ১০টি

example.com-এর NS হলো ns1.example.com. .com-এর TLD সার্ভার referral-এর সাথে ns1.example.com-এর IP ঠিকানাও additional section-এ পাঠায়। এই ঠিকানা-record-কে কী বলে, আর কেন দরকার?

  • PTR record — reverse lookup-এর জন্য
  • Glue record — NS-এর নাম delegate হওয়া zone-এর ভেতরে থাকায় চক্র ভাঙতে
  • SOA record — zone-এর মালিক চেনাতে
  • CNAME record — ডাকনাম হিসেবে

IPv4 ঠিকানা 198.51.100.25-এর PTR record খুঁজতে resolver কোন নামে প্রশ্ন করবে?

  • 198.51.100.25.in-addr.arpa
  • 25.100.51.198.ip6.arpa
  • 52.001.15.891.in-addr.arpa
  • 25.100.51.198.in-addr.arpa

একটি DNS উত্তরের header-এর flag 0x8180, আর answer-এর নামের জায়গায় দুটি বাইট c0 0c. কোন ব্যাখ্যা সঠিক?

  • এটি resolver-এর উত্তর (QR=1, RD=1, RA=1, AA=0, NOERROR); c0 0c মানে নাম offset ১২-তে, অর্থাৎ প্রশ্নের নাম
  • এটি authoritative উত্তর; c0 0c মানে ১৯২ বাইটের label
  • উত্তর কাটা পড়েছে (TC=1); c0 0c একটি ত্রুটি-কোড
  • এটি একটি প্রশ্ন; c0 0c হলো query ID

একটি ওয়েবসাইটের A record-এর TTL ৮৬,৪০০ সেকেন্ড। মালিক সকাল ৯টায় ঠিকানা বদলালেন। একজন ব্যবহারকারীর ISP-র resolver সকাল ৮টায় পুরোনো record cache করেছিল। ওই ISP-র ব্যবহারকারীরা সর্বোচ্চ কখন পর্যন্ত পুরোনো ঠিকানা পেতে পারেন (resolver TTL মানলে)?

  • সকাল ৯টা পর্যন্ত — বদল সাথে সাথে সবার কাছে পৌঁছায়
  • পরের দিন সকাল ৮টা পর্যন্ত
  • পরের দিন সকাল ৯টা পর্যন্ত
  • ৪৮ ঘণ্টা পর্যন্ত — DNS propagation-এর নিয়ম অনুযায়ী

একটি resolver একটি নামের জন্য SERVFAIL দিচ্ছে, কিন্তু একই প্রশ্নে DNSSEC যাচাই বন্ধ করার flag (CD) দিলে সঠিক ঠিকানা আসছে। সবচেয়ে সম্ভাব্য কারণ কী?

  • নামটি আসলে নেই
  • ক্লায়েন্ট থেকে resolver-এ পৌঁছানো যাচ্ছে না
  • DNSSEC যাচাই ব্যর্থ — যেমন মেয়াদোত্তীর্ণ স্বাক্ষর বা ভুল DS record
  • উত্তর ৫১২ বাইটের বেশি, তাই TC bit বসেছে

একটি কোম্পানি চায় ক্যাফের Wi-Fi-তে কেউ তাদের কর্মীদের DNS প্রশ্ন দেখতে না পারুক, আর আলাদাভাবে চায় কেউ জাল DNS উত্তর বিশ্বাস করাতে না পারুক। কোন জোড়া ঠিক?

  • গোপনীয়তায় DoT বা DoH; সত্যতায় DNSSEC
  • গোপনীয়তায় DNSSEC; সত্যতায় TTL বাড়ানো
  • গোপনীয়তায় QNAME minimisation; সত্যতায় TCP 53
  • দুটোর জন্যই round-robin DNS

শব্দকোষ

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

মনে রাখুন

  1. নামের গাছ আর delegation: root → TLD (gTLD, ccTLD যেমন .bd আর তার .com.bd) → domain; zone হলো এক প্রশাসনের অংশ, NS record দিয়ে নিচের শাখা অন্যকে দেওয়া হয়। HOSTS.TXT থেকে DNS: RFC 1034/1035, ১৯৮৭.
  2. চার ভূমিকা: stub (OS) → recursive resolver (ISP/public) → root (১৩টি নাম, বহু anycast instance) → TLD → authoritative (AA = 1). Cache ফাঁকা হলে ৮টি বার্তা; root আর TLD শুধু referral দেয়, glue চক্র ভাঙে।
  3. Caching আর TTL: প্রতিটি record মালিকের দেওয়া TTL পর্যন্ত cache-এ থাকে; NXDOMAIN-ও (SOA-র TTL আর minimum-এর ছোটটি)। “Propagation” মানে পুরোনো TTL ফুরানোর অপেক্ষা — বদলের আগে TTL কমান।
  4. Record আর বার্তা: A, AAAA, CNAME (apex-এ নয়), MX, NS, SOA (serial, refresh, retry, expire, minimum), PTR (উল্টো অক্টেট .in-addr.arpa, nibble .ip6.arpa), TXT, SRV, CAA, HTTPS. ১২ বাইটের header, চার section, c0 0c-এর মতো compression pointer; UDP 53, TC হলে বা AXFR/IXFR-এ TCP 53.
  5. নিরাপত্তা ও সমস্যা-খোঁজা: poisoning ঠেকায় এলোমেলো ID ও port, 0x20, শেষে DNSSEC (RRSIG, DNSKEY, DS); গোপনীয়তায় DoT 853, DoH 443, QNAME minimisation. NXDOMAIN = নাম নেই, SERVFAIL = resolver পারেনি, timeout = কেউ উত্তর দেয়নি। Linux-এ ক্রম ঠিক করে nsswitch.conf, তারপর /etc/hosts আর resolv.conf.

পরের পর্বে: নাম থেকে ঠিকানা পাওয়া গেল — এবার ব্রাউজার সত্যিই কথা বলবে। HTTP-র request আর response, method আর status code, header, cookie, আর REST-এর নকশা।

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

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