প্রোডাকশন DNS ডিজাইন ও বড় আউটেজ
মাল্টি-প্রোভাইডার authoritative, TTL পলিসি, DNS as code, মনিটরিং, নিজের resolver, আর Dyn, Facebook, Slack ও Cloudflare-এর আউটেজ থেকে শেখা।
গল্পে বুঝি
চট্টগ্রাম বন্দরে প্রতিদিন বিশাল জাহাজ ঢোকে। কর্ণফুলীর মোহনায় চর আর স্রোত এত জটিল যে বাইরের কোনো ক্যাপ্টেন নিজে জাহাজ ভেতরে আনেন না; বন্দরের একজন পাইলট নৌকায় করে গিয়ে জাহাজে ওঠেন, আর টাগবোট টেনে জেটিতে ভেড়ায়। বন্দরের দায়িত্বে থাকা হাইসাম একসময় সব কাজ একটাই পাইলট কোম্পানিকে দিয়েছিলেন। এক বর্ষায় সেই কোম্পানির সব নৌকা একসাথে ইঞ্জিন বিকল, আর তিন দিন ধরে বহির্নোঙরে চল্লিশটা জাহাজ দাঁড়িয়ে, মাল পচছে। জাহাজগুলো ঠিক ছিল, জেটি খালি ছিল, শুধু পথ দেখানোর কেউ ছিল না।
এরপর হাইসাম নিয়ম বদলান। এখন দুইটা আলাদা কোম্পানি পাইলট দেয়, আলাদা নৌকা, আলাদা ঘাট, আলাদা জ্বালানির উৎস, কিন্তু একই চ্যানেল-ম্যাপ মেনে চলে। চ্যানেলের ম্যাপ একটাই খাতায় থাকে, আর প্রতিটা পরিবর্তন দুই কোম্পানির কাছে একসাথে যায়, মরিয়ম সই করার আগে আরেকজন মিলিয়ে দেখেন। প্রতি ঘণ্টায় একটা ছোট নৌকা চ্যানেলের শেষ মাথা থেকে পরীক্ষা করে আসে বয়াগুলো ঠিক জায়গায় আছে কিনা। আর হাইসাম শিখেছেন: বয়া সরানোর নোটিশ জাহাজগুলোর কাছে পৌঁছাতে সময় লাগে, তাই বড় পরিবর্তন আগে ঘোষণা দিয়ে, ধাপে ধাপে।
মিলিয়ে নিই: জাহাজ হলো ইউজারের রিকোয়েস্ট, জেটি আপনার সার্ভার, পাইলট কোম্পানি হলো authoritative DNS প্রোভাইডার। এক কোম্পানির সব নৌকা বিকল মানে single-provider আউটেজ, যেখানে সার্ভার ঠিক থাকলেও কেউ পৌঁছাতে পারে না। দুই কোম্পানি একই ম্যাপে হলো মাল্টি-প্রোভাইডার authoritative, একটা খাতা আর মিলিয়ে সই হলো DNS as code ও code review, প্রতি ঘণ্টার পরীক্ষা নৌকা synthetic monitoring, আর নোটিশ পৌঁছাতে সময় লাগা হলো TTL। বাস্তবে বড় কোম্পানিগুলো ঠিক এভাবেই DNS চালায়, কারণ ইতিহাস বারবার দেখিয়েছে DNS ডুবলে বাকি সব ঠিক থাকলেও কিছুই চলে না।
DNS কেন সবচেয়ে উঁচু-ঝুঁকির নির্ভরতা
আপনার আর্কিটেকচারে প্রায় সবকিছুর আগে DNS বসে:
- প্রতিটা ইউজারের প্রথম রিকোয়েস্ট
- প্রতিটা সার্ভিসের অন্য সার্ভিসকে ডাকা (ডেটাবেস হোস্টনেম, কিউ, থার্ড-পার্টি API)
- ইমেইল (MX), সার্টিফিকেট ইস্যু (CAA, DNS-01), ডোমেইন ভেরিফিকেশন
- এমনকি আপনার ইনসিডেন্ট টুল: স্ট্যাটাস পেজ, চ্যাট, VPN, SSO
তাই DNS আউটেজের blast radius প্রায় সবসময় সবকিছু। আর DNS-এর ভুল ক্যাশে বেঁচে থাকে: ঠিক করার পরও TTL শেষ না হওয়া পর্যন্ত ভুল উত্তর চলতে থাকে। এই দুইটা বৈশিষ্ট্য মিলিয়ে প্রোডাকশন DNS-এর ডিজাইন নীতি চারটা:
- কোনো single point of failure নেই — প্রোভাইডার, নেটওয়ার্ক, অ্যাকাউন্ট, কোনোটাই এক না।
- প্রতিটা পরিবর্তন রিভিউ হয় আর রোলব্যাক করা যায় — কারণ ভুলের দাম TTL দিয়ে গুণ হয়।
- বাইরের চোখে মনিটর করা হয় — নিজের নেটওয়ার্ক থেকে সব ঠিক দেখালেও দুনিয়া ভিন্ন দেখতে পারে।
- রিকভারির পথ DNS-এর উপর নির্ভর করে না — ইনসিডেন্টে যে টুল লাগবে, সেটা যেন একই DNS-এ আটকে না থাকে।
মাল্টি-প্রোভাইডার authoritative
কাঠামো
দুইটা (বা বেশি) স্বাধীন DNS প্রোভাইডার, প্রত্যেকে একই zone সার্ভ করে, আর রেজিস্ট্রারে দুই প্রোভাইডারের nameserver একসাথে দেওয়া থাকে:
baytalhikma.org. 172800 IN NS ns1.provider-a.example.
baytalhikma.org. 172800 IN NS ns2.provider-a.example.
baytalhikma.org. 172800 IN NS ns1.provider-b.example.
baytalhikma.org. 172800 IN NS ns2.provider-b.example. resolver একটা NS-এ উত্তর না পেলে আরেকটায় চেষ্টা করে, আর বেশিরভাগ resolver দ্রুত উত্তর দেওয়া সার্ভারকে পছন্দ করে। তাই এক প্রোভাইডার পুরো ডুবলে ইউজার দেখে কিছুটা ধীরতা, আউটেজ না।
দুই প্রোভাইডার এক রাখার দুইটা উপায়:
| উপায় | কীভাবে | সুবিধা / অসুবিধা |
|---|---|---|
| Primary/secondary (AXFR) | একটা primary, অন্য প্রোভাইডার zone transfer দিয়ে secondary | স্ট্যান্ডার্ড আর সহজ; কিন্তু প্রোভাইডারের বিশেষ ফিচার (GeoDNS, ALIAS) transfer হয় না |
| দুই প্রোভাইডারে API দিয়ে লেখা | DNS as code টুল দুই প্রোভাইডারের API-তে একই রেকর্ড লেখে | দুই দিকেই “primary”; কিন্তু শুধু দুই প্রোভাইডারের সাধারণ ফিচারই ব্যবহার করতে পারবেন |
যেটাই নিন, একটা নিয়ম ভাঙবেন না: শুধু দুই প্রোভাইডার যে ফিচার একইভাবে সাপোর্ট করে, সেটাই ব্যবহার করুন। একজনের ALIAS আর অন্যজনের ভিন্ন আচরণ মানে অর্ধেক ইউজার ভিন্ন উত্তর পাবে, আর সেটা ঠিক সেই “মাঝে মাঝে ভাঙে” সমস্যা যেটা ডিবাগ করা সবচেয়ে কঠিন (চ্যাপ্টার ১৪)।
DNSSEC-এর জটিলতা: multi-signer
DNSSEC চালু থাকলে মাল্টি-প্রোভাইডার কঠিন হয়ে যায়। প্রতিটা প্রোভাইডার নিজের কী দিয়ে zone সাইন করে। কিন্তু একটা resolver হয়তো DNSKEY নিয়েছে প্রোভাইডার A থেকে আর A রেকর্ডের সিগনেচার পেয়েছে প্রোভাইডার B থেকে; B-এর কী A-এর DNSKEY সেটে না থাকলে validation ব্যর্থ, SERVFAIL।
তিনটা পথ:
- একজন সাইন করে, বাকিরা শুধু সার্ভ করে। primary সাইন করে, secondary-রা AXFR-এ সাইন-করা zone হুবহু নেয়। সবচেয়ে সরল; কিন্তু সাইনার প্রোভাইডারের উপর নির্ভরতা থাকে (তার সাইনিং বন্ধ হলে সিগনেচার একসময় মেয়াদোত্তীর্ণ)।
- Multi-signer (RFC 8901)। প্রতিটা প্রোভাইডার নিজের কী দিয়ে সাইন করে, কিন্তু প্রত্যেকের DNSKEY সেটে সবার ZSK থাকে, আর parent-এ সবার KSK-এর DS। ফলে যেকোনো প্রোভাইডারের সিগনেচার যেকোনো প্রোভাইডারের DNSKEY দিয়ে যাচাই হয়। এর জন্য দুই প্রোভাইডারেরই অন্যের কী ইমপোর্ট করার সুবিধা লাগে, আর কী রোলওভার দুই দিকে সমন্বয় করতে হয়। কোন প্রোভাইডার এটা সাপোর্ট করে, সেটা দ্রুত বদলাচ্ছে; তাদের বর্তমান ডকুমেন্টেশনে দেখুন।
- নিজে সাইন করুন (hidden primary)। নিজের একটা সার্ভার (যেটা ইন্টারনেটে NS হিসেবে তালিকায় নেই) zone সাইন করে আর দুই প্রোভাইডারকে AXFR দেয়। কী আপনার হাতে, প্রোভাইডাররা শুধু বিতরণ করে। সবচেয়ে বেশি নিয়ন্ত্রণ, সবচেয়ে বেশি দায়িত্ব।
DNSSEC আর মাল্টি-প্রোভাইডার একসাথে চালু করার আগে একটা আলাদা টেস্ট ডোমেইনে পুরো সেটআপ চালান, DNSViz দিয়ে প্রতিটা প্রোভাইডারের উত্তর দেখুন, আর প্রোভাইডার বদলের রিহার্সাল করুন। ভুল DS প্রোডাকশন ডোমেইনকে parent-এর DS TTL (প্রায়ই এক দিন) পর্যন্ত SERVFAIL করে রাখতে পারে।
TTL পলিসি
TTL হলো “ভুল হলে কতক্ষণ ভুগব” আর “প্রতিদিন কত প্রশ্ন আর কত ধীরতা” এর মধ্যে ট্রেড-অফ (চ্যাপ্টার ৪)। প্রতিটা রেকর্ডে আলাদা করে না ভেবে টিমের একটা লিখিত পলিসি রাখুন:
| রেকর্ডের ধরন | পরামর্শিত TTL | কেন |
|---|---|---|
| NS (zone-এর ভেতরে) ও parent delegation | ১ থেকে ২ দিন | কমই বদলায়; parent-এর TTL আপনার হাতে নেই |
| MX | ১ ঘণ্টা থেকে ১ দিন | মেইল প্রোভাইডার কমই বদলায়, আর মেইল নিজে রিট্রাই করে |
| SPF / DKIM / DMARC TXT | ১ ঘণ্টা | মাঝে মাঝে বদলাতে হয়, দ্রুত ঠিক করা দরকার |
| CDN বা লোড ব্যালান্সারের দিকে CNAME | ৫ মিনিট থেকে ১ ঘণ্টা | টার্গেট প্রোভাইডার নিজের TTL নিয়ন্ত্রণ করে |
| সাধারণ A/AAAA (স্থির সার্ভার) | ৫ মিনিট থেকে ১ ঘণ্টা | মাইগ্রেশনের নমনীয়তা বনাম প্রশ্নের সংখ্যা |
| DNS ফেইলওভার করা রেকর্ড | ৩০ থেকে ৬০ সেকেন্ড | ফেইলওভার শুধু TTL-এর গতিতেই কাজ করে |
| ACME challenge TXT | ১ থেকে ৫ মিনিট | সাময়িক, দ্রুত বদলায় |
| Negative TTL (SOA-র শেষ ফিল্ড) | ৫ মিনিট থেকে ১ ঘণ্টা | নতুন নাম তৈরির পর ভুল NXDOMAIN কতক্ষণ থাকবে |
এগুলো শুরু করার জায়গা, আইন না। দুইটা জিনিস মনে রাখুন: কিছু resolver খুব ছোট TTL বাড়িয়ে নিজের ন্যূনতমে নিয়ে যায়, তাই ৩০ সেকেন্ডের TTL বাস্তবে সবার জন্য ৩০ সেকেন্ড না। আর বড় পরিবর্তনের আগে TTL কমানোর কাজটা পুরনো TTL-এর সমান সময় আগে করতে হয়।
DNS as code
ড্যাশবোর্ডে হাতে রেকর্ড এডিট করলে তিনটা সমস্যা: কেউ রিভিউ করে না, ইতিহাস থাকে না (কে, কখন, কেন), আর দুই প্রোভাইডার একসাথে রাখা অসম্ভব। সমাধান হলো zone-কে Git-এ কোড হিসেবে রাখা, আর CI থেকে প্রোভাইডারে প্রয়োগ করা।
প্রচলিত টুল (২০২৬ সালের অক্টোবর অনুযায়ী দুটোই সক্রিয়ভাবে রক্ষণাবেক্ষণ হচ্ছে; বর্তমান ভার্সন আর প্রোভাইডার তালিকা তাদের রিপোজিটরিতে দেখুন):
| টুল | ভাষা / কনফিগ | বৈশিষ্ট্য |
|---|---|---|
| octoDNS | Python, YAML-এ রেকর্ড | একই zone অনেক প্রোভাইডারে সিঙ্ক করার জন্য তৈরি; প্রোভাইডার প্লাগইন আলাদা প্যাকেজে |
| DNSControl | Go বাইনারি, JavaScript-এ কনফিগ | preview দিয়ে ডিফ, তারপর push; অনেক প্রোভাইডার আর রেজিস্ট্রার সাপোর্ট |
| Terraform / OpenTofu | HCL, প্রোভাইডার-ভিত্তিক রিসোর্স | বাকি ইনফ্রা যদি এতেই থাকে; তবে প্রতিটা প্রোভাইডারের রিসোর্স আলাদা, তাই মাল্টি-প্রোভাইডারে একই রেকর্ড দুবার লিখতে হয় |
একটা DNSControl কনফিগের উদাহরণ (প্রোভাইডারের নাম আর ক্রেডেনশিয়াল আপনার creds.json অনুযায়ী):
// dnsconfig.js
var REG = NewRegistrar("registrar");
var PROVIDER_A = NewDnsProvider("provider_a");
var PROVIDER_B = NewDnsProvider("provider_b");
D("baytalhikma.org", REG,
DnsProvider(PROVIDER_A),
DnsProvider(PROVIDER_B),
DefaultTTL(3600),
A("@", "203.0.113.20"),
AAAA("@", "2001:db8:10::20"),
CNAME("www", "baytalhikma.org."),
A("api", "203.0.113.30", TTL(300)),
MX("@", 10, "mx1.baytalhikma.org."),
TXT("@", "v=spf1 mx include:_spf.mailer.example -all"),
TXT("_dmarc", "v=DMARC1; p=reject; rua=mailto:dmarc@baytalhikma.org"),
CAA("@", "issue", "letsencrypt.org"),
CAA("@", "iodef", "mailto:security@baytalhikma.org")
); আর CI-তে প্রবাহ:
pull request -> dnscontrol check (syntax)
-> dnscontrol preview (diff posted as a PR comment)
-> human review (second engineer approves)
merge to main -> dnscontrol push (applies to both providers)
-> post-deploy check (query every NS, compare to config) শেষ ধাপটা প্রায়ই বাদ পড়ে, কিন্তু সবচেয়ে জরুরি: প্রোভাইডারের API “OK” বলেছে মানেই প্রতিটা nameserver নতুন রেকর্ড দিচ্ছে না। চ্যাপ্টার ১৪-এর হেলথ-চেক স্ক্রিপ্ট এখানে বসিয়ে দিন।
DNS as code-এর একটা লুকানো লাভ: zone-এ যে রেকর্ড কোডে নেই, টুল সেটা মুছে দেয় (বা অন্তত ডিফে দেখায়)। এতে dangling রেকর্ড (চ্যাপ্টার ১৩) জমতে পারে না, আর কেউ ড্যাশবোর্ডে চুপিচুপি যোগ করলে পরের রানেই ধরা পড়ে। প্রথমবার চালানোর আগে প্রোভাইডার থেকে বর্তমান zone ইমপোর্ট করে নিন, নইলে প্রথম push সত্যিই সব মুছে দিতে পারে।
পরিবর্তনের নিয়ম: রিভিউ ও ধাপে ধাপে রোলআউট
DNS-এর ভুল ফেরত নেওয়া যায়, কিন্তু ক্যাশ থেকে না। তাই ঝুঁকি অনুযায়ী পরিবর্তনকে তিন ভাগে ভাগ করুন:
| ঝুঁকি | উদাহরণ | প্রক্রিয়া |
|---|---|---|
| কম | নতুন সাবডোমেইন, নতুন TXT | PR রিভিউ, সরাসরি প্রয়োগ |
| মাঝারি | চলমান A/AAAA/CNAME বদল, MX বদল, SPF বদল | আগে TTL কমানো, পুরনো TTL পার হওয়া পর্যন্ত অপেক্ষা, ব্যস্ততা কম এমন সময়ে বদল, রোলব্যাক প্রস্তুত |
| উচ্চ | NS বা প্রোভাইডার বদল, DNSSEC চালু/বন্ধ, DS বা KSK রোলওভার, রেজিস্ট্রার ট্রান্সফার | লিখিত রানবুক, টেস্ট ডোমেইনে রিহার্সাল, parent-এর TTL হিসাব, দুই প্রোভাইডারে একসাথে চলার সময়কাল, ইনসিডেন্ট চ্যানেল খোলা |
উচ্চ-ঝুঁকির পরিবর্তনে canary করার একটা কৌশল: প্রথমে কম গুরুত্বের একটা ডোমেইনে (যেমন baytalhikma.dev বা একটা অভ্যন্তরীণ ডোমেইন) একই পরিবর্তন, কয়েক দিন পর্যবেক্ষণ, তারপর প্রধান ডোমেইন। DNSSEC বা প্রোভাইডার বদলের ক্ষেত্রে zone-এর গঠন (wildcard, অ্যাপেক্সে বিশেষ রেকর্ড, অনেক বড় TXT) প্রধান ডোমেইনের সাথে মেলানো জরুরি, নইলে canary কিছুই প্রমাণ করে না। Slack-এর ঘটনা (নিচে) ঠিক এই ফাঁকের উদাহরণ।
মনিটরিং
নিজের অফিস থেকে dig চালিয়ে সবুজ দেখা মানে প্রায় কিছুই না। প্রোডাকশন DNS মনিটরিংয়ে যা দেখতে হয়:
| কী মনিটর করবেন | কীভাবে | অ্যালার্ট কখন |
|---|---|---|
| প্রতিটা authoritative NS উত্তর দেয় কিনা | প্রতি মিনিটে +norecurse SOA প্রতিটা NS-এ, UDP আর TCP | কোনো NS টানা কয়েকবার ব্যর্থ |
| SOA serial সব NS-এ এক কিনা | একই চেকে serial তুলনা | serial কয়েক মিনিটের বেশি ভিন্ন |
| মূল রেকর্ডের উত্তর প্রত্যাশিত কিনা | কনফিগ থেকে প্রত্যাশিত মান, প্রতিটা NS-এ তুলনা | অমিল |
| parent delegation বদলায়নি | TLD সার্ভারে +norecurse NS | যেকোনো পরিবর্তন (হাইজ্যাকিংয়ের লক্ষণ, চ্যাপ্টার ১৩) |
| DNSSEC স্বাস্থ্য | DS বনাম DNSKEY, RRSIG-এর মেয়াদ শেষের তারিখ, validating resolver-এ status | মেয়াদ শেষের কয়েক দিন আগে; যেকোনো SERVFAIL |
| ডোমেইনের মেয়াদ | RDAP-এ expiration তারিখ | ৩০ দিন আগে |
| বাইরের অনেক জায়গা থেকে resolution | বিভিন্ন দেশের প্রোব বা synthetic চেক সার্ভিস | কোনো অঞ্চলে ব্যর্থতা বা ধীরতা |
| প্রশ্নের হার ও NXDOMAIN অনুপাত | authoritative প্রোভাইডারের মেট্রিক্স বা নিজের সার্ভারের লগ | হঠাৎ বিস্ফোরণ (আক্রমণ বা ভুল কনফিগ) |
বাইরের দৃষ্টিভঙ্গির জন্য RIPE Atlas একটা কমিউনিটি নেটওয়ার্ক যেখানে সারা বিশ্বের হাজারো প্রোব থেকে DNS প্রশ্ন চালানো যায়; প্রোব হোস্ট করলে ক্রেডিট পাওয়া যায়। ডোমেইনের মেয়াদ দেখার উদাহরণ (RDAP হলো WHOIS-এর আধুনিক JSON বিকল্প; .org-এর জন্য সঠিক RDAP সার্ভার IANA-র bootstrap ফাইলে):
curl -s https://rdap.org/domain/baytalhikma.org |
python3 -c 'import json,sys; d=json.load(sys.stdin); print([e["eventDate"] for e in d["events"] if e["eventAction"]=="expiration"])' ['2027-03-14T09:12:44Z'] RRSIG মেয়াদ চেক:
# Print the expiry timestamp of the signature over the SOA, per nameserver
for ns in $(dig +short NS baytalhikma.org); do
printf '%-26s ' "$ns"
dig +norecurse +dnssec SOA baytalhikma.org @"$ns" | awk '$4 == "RRSIG" {print $9; exit}'
done ; illustrative: YYYYMMDDHHMMSS, one server's signatures are about to lapse
ns1.baytalhikma.org. 20261106000000
ns2.baytalhikma.org. 20261106000000
ns1.provider-b.example. 20261024030000 মনিটরিং নিজেই DNS-এর উপর নির্ভর করে। অ্যালার্ট পাঠানোর পথ (পেজিং সার্ভিস, চ্যাট) যদি একই ডোমেইনে বা একই DNS প্রোভাইডারে থাকে, তাহলে আউটেজের সময়েই অ্যালার্ট আসবে না। অ্যালার্টিং আলাদা ডোমেইন আর আলাদা প্রোভাইডারে রাখুন, আর মনিটরিং চেক প্রোভাইডারের IP সরাসরি দিয়েও চালান।
ভেতরের আর বাইরের DNS: split-horizon
অনেক প্রতিষ্ঠান ভেতরের নেটওয়ার্কে এক উত্তর আর বাইরে আরেক উত্তর দেয় (split-horizon): git.baytalhikma.org ভেতরে 10.0.4.12, বাইরে হয় নেই নয়তো VPN গেটওয়ে। এটা কাজের, কিন্তু চারটা ফাঁদ আছে:
- দুইটা zone আলাদা হয়ে যায়। বাইরের zone-এ নতুন রেকর্ড যোগ হলো, ভেতরেরটায় হলো না; এখন অফিসের ভেতর থেকে নতুন সাইট খোলে না (ভেতরের zone authoritative, তাই NXDOMAIN)। সমাধান: দুই zone একই কোড থেকে তৈরি, শুধু পার্থক্যগুলো আলাদা ফাইলে।
- ল্যাপটপ ঘুরে বেড়ায়। অফিসে ক্যাশ হওয়া ভেতরের IP বাসায় গিয়েও ক্যাশে থাকে। ভেতরের রেকর্ডের TTL ছোট রাখুন।
- বাইরের DoH ভেতরের নাম ভাঙে। ব্রাউজার নিজের DoH ব্যবহার করলে ভেতরের resolver-কে এড়িয়ে যায়। ব্যবস্থাপিত ডিভাইসে পলিসি দিয়ে নিয়ন্ত্রণ করুন; অনেক ব্রাউজার একটা “canary domain” চেক করে বোঝে নেটওয়ার্ক DoH বন্ধ রাখতে চায় কিনা (ব্রাউজারের বর্তমান আচরণ তাদের ডকুমেন্টেশনে দেখুন)।
- ভেতরের নাম বাইরে ফাঁস হয়। অভ্যন্তরীণ হোস্টনেম পাবলিক zone-এ রাখলে আক্রমণকারী আপনার নেটওয়ার্কের মানচিত্র পায়, আর পাবলিক সার্টিফিকেট নিলে নামগুলো Certificate Transparency লগেও যায়।
ভেতরের নামের জন্য পাবলিক ডোমেইনের একটা সাবডোমেইন (internal.baytalhikma.org) ব্যবহার করুন, বানানো TLD (.local, .corp, .lan) না: .local mDNS-এর জন্য সংরক্ষিত, আর বানানো TLD যেকোনোদিন সত্যিকারের TLD হয়ে যেতে পারে। ভেতরের ব্যবহারের জন্য .internal TLD সংরক্ষণের সিদ্ধান্ত ICANN ২০২৪ সালে নিয়েছিল; আপনার পরিবেশে এটা ব্যবহারের আগে বর্তমান অবস্থা যাচাই করুন।
নিজের ফ্লিটের জন্য resolver চালানো
শত শত সার্ভার যদি সবাই সরাসরি ক্লাউড প্রোভাইডারের বা পাবলিক resolver-এ যায়, তাহলে তাদের rate limit, আউটেজ আর ধীরতা আপনার সমস্যা হয়ে যায়। অনেক টিম প্রতিটা হোস্টে বা প্রতিটা নেটওয়ার্কে একটা লোকাল ক্যাশিং resolver চালায়। Unbound এর জন্য ছোট, দ্রুত, আর DNSSEC validation ডিফল্টে প্রস্তুত:
# /etc/unbound/unbound.conf.d/fleet.conf
server:
interface: 127.0.0.1
interface: ::1
access-control: 127.0.0.0/8 allow
access-control: ::1/128 allow
# cache and resilience
msg-cache-size: 64m
rrset-cache-size: 128m
prefetch: yes # refresh popular entries before they expire
serve-expired: yes # answer from stale cache if upstream is down
serve-expired-ttl: 3600 # but not with data older than an hour past expiry
# privacy and hardening
qname-minimisation: yes
hide-identity: yes
hide-version: yes
harden-glue: yes
harden-dnssec-stripped: yes
# internal zone served by your own authoritative servers
private-domain: "internal.baytalhikma.org"
domain-insecure: "internal.baytalhikma.org"
stub-zone:
name: "internal.baytalhikma.org"
stub-addr: 10.0.0.53
stub-addr: 10.0.1.53 unbound-checkconf && sudo systemctl restart unbound
dig @127.0.0.1 www.baytalhikma.org +short
unbound-control stats_noreset | grep -E 'total.num.(queries|cachehits|cachemiss)' serve-expired (RFC 8767-এর “serve stale” ধারণা) প্রোডাকশনে খুব কাজের: authoritative সার্ভার কিছুক্ষণের জন্য অপ্রাপ্য হলে resolver মেয়াদোত্তীর্ণ কিন্তু সম্ভবত-ঠিক উত্তর দিয়ে যায়, আউটেজকে ধীরতায় বদলে দেয়। ট্রেড-অফ: ইচ্ছাকৃত পরিবর্তনও সামান্য দেরিতে পৌঁছাতে পারে।
বড় আউটেজ থেকে শিক্ষা
প্রতিটা ঘটনা একই ছাঁচে: কী ঘটেছিল, DNS কেন ক্ষতি বাড়িয়ে দিল, আর শিক্ষা কী। তথ্যগুলো প্রতিটা প্রতিষ্ঠানের নিজের প্রকাশিত বিবরণ থেকে; বিস্তারিত সেখানেই পড়ুন।
Dyn, ২১ অক্টোবর ২০১৬
কী ঘটেছিল: Dyn ছিল বহু বড় সাইটের managed DNS প্রোভাইডার। সেদিন Mirai botnet-সংক্রমিত IoT ডিভাইস (ক্যামেরা, রাউটার) থেকে বিশাল DDoS তাদের authoritative নেটওয়ার্কে আঘাত করে, দুইটা বড় ঢেউয়ে (Dyn-এর বিশ্লেষণে মোটামুটি ১১:১০ থেকে ১৩:২০ UTC, আর ১৫:৫০ থেকে ১৭:০০ UTC)। Dyn জানিয়েছিল আক্রমণে কয়েক কোটি IP জড়িত ছিল, আর ট্রাফিক ছিল port 53-এ TCP ও UDP। যুক্তরাষ্ট্র আর ইউরোপের বহু ইউজার নামকরা সাইটে পৌঁছাতে পারেনি।
DNS কেন ক্ষতি বাড়াল: সাইটগুলোর সার্ভার পুরো সময় ঠিক ছিল। কিন্তু অনেকের একমাত্র DNS প্রোভাইডার ছিল Dyn। Dyn-এর বিশ্লেষণ অনুযায়ী, আক্রমণ resolver-দের রিট্রাই ট্রাফিক বাড়িয়ে দিয়েছিল: বৈধ resolver-রা উত্তর না পেয়ে বারবার প্রশ্ন করছিল, যা চাপ আরও বাড়াল।
শিক্ষা: একটা DNS প্রোভাইডার একটা single point of failure। এই ঘটনার পর অনেক বড় কোম্পানি মাল্টি-প্রোভাইডার authoritative নিয়ে আসে। আর বড় TTL এখানে সাহায্য করত: যাদের রেকর্ড বেশি সময় ক্যাশে ছিল, তাদের ইউজাররা কম ভুগেছে।
Facebook (Meta), ৪ অক্টোবর ২০২১
কী ঘটেছিল: Meta-র ইঞ্জিনিয়ারিং ব্লগের বিবরণ অনুযায়ী, রুটিন রক্ষণাবেক্ষণের সময় গ্লোবাল ব্যাকবোন ক্যাপাসিটি যাচাই করতে একটা কমান্ড চালানো হয়, যেটা ভুলবশত ব্যাকবোনের সব সংযোগ বিচ্ছিন্ন করে দেয়। যে অডিট টুলের এটা আটকানোর কথা, তার একটা বাগ ছিল। Facebook, Instagram, WhatsApp কয়েক ঘণ্টা বিশ্বজুড়ে অচল।
DNS কেন ক্ষতি বাড়াল: Meta-র authoritative DNS সার্ভারগুলো BGP দিয়ে নিজেদের IP ঘোষণা করে, আর ডিজাইন অনুযায়ী ডেটা সেন্টারে পৌঁছাতে না পারলে সেই ঘোষণা তুলে নেয় (ধরে নেয় নেটওয়ার্ক অসুস্থ, তাই ট্রাফিক অন্য জায়গায় যাক)। ব্যাকবোন ডাউন হওয়ায় সব DNS সার্ভার একসাথে তাই করল, যদিও সার্ভারগুলো নিজেরা চালু ছিল। ফলে পুরো ইন্টারনেট Meta-র নামগুলো আর resolve করতে পারল না। আর DNS না থাকায় Meta-র নিজের অভ্যন্তরীণ ডায়াগনস্টিক টুলও কাজ করছিল না; ইঞ্জিনিয়ারদের সশরীরে ডেটা সেন্টারে যেতে হয়েছিল।
শিক্ষা: একটা স্থানীয়ভাবে যুক্তিসঙ্গত স্বাস্থ্য-নিয়ম (“অসুস্থ হলে নিজেকে সরিয়ে নাও”) যখন সব নোডে একসাথে ট্রিগার হয়, তখন সেটা গ্লোবাল আউটেজ। ফেইলওভার লজিকে একটা “সবাই একসাথে সরে যাচ্ছে কিনা” সীমা থাকা দরকার। আর রিকভারির টুল আর আউট-অফ-ব্যান্ড অ্যাক্সেস প্রোডাকশন DNS আর নেটওয়ার্কের উপর নির্ভর করা চলবে না।
Slack, ৩০ সেপ্টেম্বর ২০২১ (DNSSEC)
কী ঘটেছিল: Slack-এর ইঞ্জিনিয়ারিং ব্লগের পোস্টমর্টেম অনুযায়ী, এটা ছিল slack.com-এ DNSSEC চালু করার তৃতীয় চেষ্টা। zone সাইন করে রেজিস্ট্রারে DS প্রকাশ করার পর কিছু ইউজার ERR_NAME_NOT_RESOLVED দেখতে শুরু করেন। প্রায় ২৪ ঘণ্টা ধরে চলেছিল, অনলাইন ইউজারের ১%-এরও কম আক্রান্ত হয়েছিলেন।
মূল কারণ: তাদের DNS প্রোভাইডার (Route 53) wildcard রেকর্ডের জন্য অসম্পূর্ণ NSEC উত্তর তৈরি করছিল। *.slack.com-এর অধীনের একটা নামে AAAA প্রশ্নের সাইন-করা “এই টাইপ নেই” উত্তরে যে টাইপগুলো আছে সেগুলোর তালিকা ঠিকমতো ছিল না। কিছু validating resolver (Google Public DNS-এর কিছু অংশসহ) এটাকে পড়ল “এই নামে কোনো রেকর্ডই নেই”, ক্যাশ করল, আর পরের A প্রশ্নও ব্যর্থ হলো। AWS পরে বাগটা ঠিক করে।
DNS কেন ক্ষতি বাড়াল: টিম ধরে নিয়েছিল DS সরালে দ্রুত ঠিক হবে। কিন্তু .com zone DS রেকর্ড ২৪ ঘণ্টা ক্যাশ করতে বলে, আর এই TTL zone-এর মালিকের হাতে নেই। DS সরানোর পর সাইনিং বন্ধ করায় অবস্থা আরও খারাপ হলো: যে resolver-দের ক্যাশে তখনও পুরনো DS ছিল, তারা এখন সাইন-ছাড়া zone পেয়ে পুরো slack.com-এর জন্য SERVFAIL দিতে লাগল। ক্যাশ ফ্লাশ করাতে ISP আর resolver অপারেটরদের সাথে যোগাযোগ করতে হয়েছিল।
শিক্ষা: DNSSEC চালুর আগে zone-এর প্রতিটা বৈশিষ্ট্য (বিশেষ করে wildcard) একই প্রোভাইডারে টেস্ট করুন। রোলব্যাকের পথের TTL আগে হিসাব করুন, বিশেষত parent-এর TTL যেটা আপনি বদলাতে পারবেন না। আর রোলব্যাকের ধাপের ক্রম গুরুত্বপূর্ণ: আগে DS সরিয়ে parent-এর TTL পার হওয়া পর্যন্ত অপেক্ষা, তারপর সাইনিং বন্ধ।
Cloudflare 1.1.1.1, ১৪ জুলাই ২০২৫
কী ঘটেছিল: Cloudflare-এর ব্লগের পোস্টমর্টেম অনুযায়ী, তাদের পাবলিক resolver 1.1.1.1 প্রায় ৬২ মিনিট (২১:৫২ থেকে ২২:৫৪ UTC) বিশ্বজুড়ে বেশিরভাগ ইউজারের কাছে অপ্রাপ্য ছিল। কারণ বাইরের আক্রমণ না, একটা অভ্যন্তরীণ কনফিগারেশন ভুল। ৬ জুন একটা তখনো-চালু-না-হওয়া সার্ভিসের কনফিগে ভুলবশত 1.1.1.1-এর IP prefix যুক্ত হয়েছিল; তাতে তখন কোনো প্রভাব পড়েনি, ভুলটা ঘুমিয়ে ছিল। ১৪ জুলাই সেই সার্ভিসে একটা অফলাইন টেস্ট লোকেশন যোগ করার পরিবর্তন একটা গ্লোবাল কনফিগ রিফ্রেশ ট্রিগার করে, আর resolver-এর prefix সারা বিশ্ব থেকে তুলে নেওয়া হয়।
DNS কেন ক্ষতি বাড়াল: যাদের ডিভাইস বা রাউটারে শুধু 1.1.1.1 (আর 1.0.0.1) সেট করা ছিল, তাদের কাছে পুরো ইন্টারনেট “ডাউন” মনে হয়েছিল, যদিও সব সাইট চালু ছিল। মজার ব্যাপার, DoH ট্রাফিক মোটামুটি স্থির ছিল, কারণ DoH ক্লায়েন্টরা বেশিরভাগ cloudflare-dns.com নাম দিয়ে আলাদা IP-তে যায়।
শিক্ষা: ক্লায়েন্ট বা রাউটারে দুইটা ভিন্ন প্রতিষ্ঠানের resolver রাখুন (যেমন একটা 1.1.1.1, একটা 9.9.9.9), একই প্রতিষ্ঠানের দুই IP না। আর অপারেটরের দিক থেকে: ঘুমিয়ে থাকা কনফিগ ভুল ধাপে ধাপে রোলআউট আর canary ছাড়া একবারে গ্লোবাল হয়ে যায়; Cloudflare নিজেও পুরনো, ধাপে-ধাপে-রোলআউট-ছাড়া টুলিংকে কারণ হিসেবে চিহ্নিত করেছিল।
সব ঘটনার মিল
| ঘটনা | প্রথম ধাক্কা | DNS কী করল | যা আটকাত |
|---|---|---|---|
| Dyn ২০১৬ | বাইরের DDoS | একমাত্র প্রোভাইডার, তাই সব গ্রাহক একসাথে ডাউন | মাল্টি-প্রোভাইডার, বড় TTL |
| Meta ২০২১ | ব্যাকবোন কনফিগ কমান্ড | সব DNS নোড একসাথে নিজেদের সরিয়ে নিল | গ্লোবাল সীমাসহ ফেইলওভার, স্বাধীন রিকভারি পথ |
| Slack ২০২১ | প্রোভাইডারের NSEC বাগ | parent-এর ২৪ ঘণ্টার DS ক্যাশ রোলব্যাক আটকাল | wildcard-সহ রিহার্সাল, রোলব্যাকের TTL পরিকল্পনা |
| Cloudflare ২০২৫ | ঘুমন্ত কনফিগ ভুল | একটা resolver-নির্ভর ক্লায়েন্ট সব হারাল | ধাপে ধাপে রোলআউট, ভিন্ন প্রতিষ্ঠানের দ্বিতীয় resolver |
প্রতিটা ক্ষেত্রেই প্রথম ধাক্কা DNS-এর বাইরে বা DNS-এর এক কোণে ছিল। DNS সেটাকে “সবকিছু ডাউন” বানিয়েছে, কারণ সবকিছু DNS-এর উপর দাঁড়িয়ে, আর ক্যাশ ভুলকে দীর্ঘায়িত করে।
মাস্টারি চেকলিস্ট
নিজের প্রোডাকশন ডোমেইনের জন্য প্রতিটা প্রশ্নের উত্তর “হ্যাঁ” হওয়া পর্যন্ত কাজ বাকি:
মালিকানা ও রেজিস্ট্রার
- রেজিস্ট্রার অ্যাকাউন্টে hardware key বা TOTP 2FA, শেয়ার্ড টিম vault-এ, একজনের ব্যক্তিগত ইমেইলে না
- auto-renew চালু, পেমেন্ট বৈধ, মেয়াদের ৩০ দিন আগে অ্যালার্ট
- transfer lock চালু; প্রধান ডোমেইনে registry lock বিবেচিত
- রিকভারি ইমেইল এমন ডোমেইনে যেটা এই ডোমেইনের উপর নির্ভর করে না
Authoritative
- অন্তত দুইটা স্বাধীন প্রোভাইডার (বা আলাদা নেটওয়ার্কে নিজের সার্ভার), দুজনেই parent-এর NS তালিকায়
- শুধু দুই প্রোভাইডারের সাধারণ ফিচার ব্যবহার
- প্রতিটা NS UDP আর TCP দুটোতেই উত্তর দেয়, EDNS বাফার ১২৩২
- DNSSEC থাকলে: সাইনিং মডেল লিখিত (single-signer, multi-signer, hidden primary), রোলওভার রানবুক রিহার্সাল করা
পরিবর্তন
- zone Git-এ, প্রতিটা পরিবর্তন PR আর দ্বিতীয় জনের রিভিউ
- CI-তে preview ডিফ আর প্রয়োগের পর প্রতিটা NS-এ যাচাই
- লিখিত TTL পলিসি, আর উচ্চ-ঝুঁকির পরিবর্তনের রানবুক
- রিসোর্স মোছার আগে রেকর্ড মোছা, নিয়মিত dangling অডিট
মনিটরিং
- প্রতিটা NS-এর স্বাস্থ্য, serial মিল, প্রত্যাশিত উত্তর, বাইরের একাধিক জায়গা থেকে
- delegation বা NS পরিবর্তনে অ্যালার্ট
- RRSIG মেয়াদ আর DS-DNSKEY মিল
- অ্যালার্টিং পথ আলাদা ডোমেইন আর প্রোভাইডারে
ক্লায়েন্ট দিক
- সার্ভার ফ্লিটে লোকাল ক্যাশিং resolver, serve-stale সহ
- upstream হিসেবে ভিন্ন প্রতিষ্ঠানের resolver
- Kubernetes-এ
ndotsআর NodeLocal DNSCache বিবেচিত (চ্যাপ্টার ১৪) - ভেতরের নাম পাবলিক ডোমেইনের সাবডোমেইনে, বানানো TLD-তে না
ইমেইল ও সার্টিফিকেট
- SPF, DKIM, DMARC (শেষে
p=reject), PTR সঠিক (চ্যাপ্টার ৯) - CAA শুধু যে CA ব্যবহার করেন তাদের অনুমতি দেয়
- যে ডোমেইন থেকে মেইল যায় না, সেখানে
v=spf1 -allআর DMARCp=reject
ডিবাগিং: এই চ্যাপ্টারের সমস্যাগুলো
লক্ষণ: মাল্টি-প্রোভাইডার চালুর পর কিছু ইউজার পুরনো বা ভিন্ন উত্তর পাচ্ছে। নিশ্চিত করুন: চ্যাপ্টার ১৪-এর হেলথ-চেক স্ক্রিপ্ট; প্রতিটা প্রোভাইডারের NS আলাদা উত্তর দিচ্ছে কিনা, serial এক কিনা (API-ভিত্তিক সিঙ্কে serial আলাদা হতে পারে, তখন রেকর্ড-বাই-রেকর্ড তুলনা করুন)। ঠিক করুন: DNS as code টুল দিয়ে দুই প্রোভাইডারে আবার প্রয়োগ; প্রোভাইডার-নির্দিষ্ট ফিচার (ALIAS, GeoDNS) এক দিকে থাকলে সরান।
লক্ষণ: দ্বিতীয় প্রোভাইডার যোগ করার পর validating resolver-এ মাঝে মাঝে SERVFAIL। নিশ্চিত করুন: প্রতিটা প্রোভাইডারের NS থেকে আলাদা করে dig +dnssec DNSKEY নিন; দুই সেট এক কিনা, আর প্রতিটা প্রোভাইডারের RRSIG-এর key tag অন্য প্রোভাইডারের DNSKEY সেটে আছে কিনা। DNSViz-এ প্রতিটা NS আলাদা রঙে দেখায়।
ঠিক করুন: multi-signer কী বিনিময় সম্পূর্ণ করুন (RFC 8901), অথবা একজন সাইনার আর বাকিরা AXFR-এ সাইন-করা zone নেওয়ার মডেলে যান।
লক্ষণ: DNS as code-এর প্রথম push অনেক রেকর্ড মুছে ফেলতে চাইছে। নিশ্চিত করুন: preview ডিফ পড়ুন; এগুলো ড্যাশবোর্ডে হাতে বানানো রেকর্ড যা কোডে নেই।
ঠিক করুন: প্রয়োগ করবেন না। প্রোভাইডার থেকে বর্তমান zone ইমপোর্ট করে কোডে আনুন, প্রতিটা রেকর্ডের মালিক খুঁজুন, তারপর ইচ্ছাকৃতভাবে মুছুন।
লক্ষণ: মনিটরিং সব সবুজ, কিন্তু একটা দেশের ইউজার সাইট পাচ্ছে না। নিশ্চিত করুন: সেই অঞ্চলের প্রোব (RIPE Atlas) থেকে resolution আর anycast নোড (+nsid) দেখুন; GeoDNS থাকলে সেই অঞ্চলের subnet দিয়ে ECS প্রশ্ন (চ্যাপ্টার ১৪)।
ঠিক করুন: প্রোভাইডারের সেই অঞ্চলের নোডের সমস্যা হলে তাদের জানান; আর মনিটরিংয়ে সেই অঞ্চল যোগ করুন।
লক্ষণ: authoritative প্রোভাইডার ডাউন, আর আপনার অ্যালার্টও আসছে না। নিশ্চিত করুন: অ্যালার্টিং সার্ভিসের ডোমেইন কোন DNS প্রোভাইডারে। ঠিক করুন: ইনসিডেন্টের পরে, অ্যালার্টিং আর স্ট্যাটাস পেজ আলাদা ডোমেইন আর প্রোভাইডারে সরান, আর মনিটরিং প্রোভাইডারের IP সরাসরি দিয়েও চেক করুক।
লক্ষণ: ফ্লিটের resolver ঠিক থাকার পরও upstream আউটেজে সব সার্ভিস ধীর। নিশ্চিত করুন: unbound-control stats_noreset-এ cache miss আর upstream টাইমআউট।
ঠিক করুন: serve-expired আর prefetch চালু, upstream-এ ভিন্ন প্রতিষ্ঠানের resolver, অথবা upstream ছাড়াই সরাসরি root থেকে recursion।
মূল শিক্ষা
- DNS ডুবলে সব ডোবে — blast radius প্রায় সবসময় পুরো সিস্টেম, আর ক্যাশ ভুলকে TTL পর্যন্ত বাঁচিয়ে রাখে।
- একটা প্রোভাইডার একটা single point of failure — দুই স্বাধীন প্রোভাইডার, দুজনেই parent-এর NS-এ, শুধু সাধারণ ফিচার ব্যবহার করে।
- DNSSEC মাল্টি-প্রোভাইডারকে কঠিন করে — single-signer, multi-signer (RFC 8901), বা hidden primary, যেকোনো একটা ইচ্ছাকৃতভাবে বেছে নিন আর রিহার্সাল করুন।
- DNS কোড, ড্যাশবোর্ড না — Git, রিভিউ, preview ডিফ, আর প্রয়োগের পর প্রতিটা NS-এ যাচাই।
- TTL একটা লিখিত পলিসি — রেকর্ডের ধরন অনুযায়ী, আর বড় পরিবর্তনের আগে কমানো।
- বাইরের চোখে মনিটর করুন, আর অ্যালার্ট অন্য পথে পাঠান — নিজের নেটওয়ার্কের সবুজ মানে দুনিয়ার সবুজ না।
- ইতিহাসের প্রতিটা বড় DNS আউটেজের মিল একটাই — প্রথম ধাক্কা ছোট, DNS আর ক্যাশ সেটাকে “সবকিছু ডাউন” বানায়; রিকভারির পথ তাই DNS-এর উপর নির্ভর করবে না।