এই পর্বে যা শিখবেন
- Route table পড়া, target-এর ধরন চেনা আর longest-prefix match হাতে করা
- Packet-এর প্রতিটি ধাপে source address কীভাবে বদলায় তা বলতে পারা
- প্রতি AZ-এ NAT রাখার যুক্তি, ঝুঁকি আর মাসিক খরচের হিসাব
- Asymmetric path আর চারটি সাধারণ routing ভুল চেনা
- Flow log আর reachability tool দিয়ে সমস্যার জায়গা খুঁজে বের করা
১ · Route table — ডাকঘরের সর্টিং টেবিল
পর্ব ২৫-এ আপনি ঠিকানার নকশা দেখেছেন: VPC, subnet আর CIDR. কিন্তু ঠিকানা থাকলেই চিঠি পৌঁছায় না। কেউ একজনকে বলতে হয় চিঠিটি কোন পথে যাবে। Cloud-এ এই কাজটি করে route table.
একটি বড় ডাকঘরের সর্টিং টেবিল ভাবুন। দেয়ালে একটি তালিকা ঝোলানো: “রাজশাহী বিভাগ → উত্তরের বস্তা”, “রাজশাহী শহর → শহরের বস্তা”, “বাকি সব → ঢাকা সদরের বস্তা”। কর্মী চিঠি পড়েন না, শুধু ঠিকানা দেখে বস্তা বেছে নেন। Route table ঠিক এই তালিকা। প্রতিটি সারিতে একটি গন্তব্য আর একটি পরের ঠিকানা থাকে।
Table-এর প্রতিটি সারিকে route বলে। Route-এর দুটি অংশ: destination (গন্তব্যের CIDR) আর target (packet যেখানে যাবে)। নিচে একটি private subnet-এর table:
Destination Target মানে
10.0.0.0/16 local VPC-র ভেতরে, সরাসরি
0.0.0.0/0 nat-a বাকি সব, NAT gateway হয়ে
প্রথম সারিটি local route. প্রতিটি table-এ VPC-র নিজের CIDR-এর জন্য এটি নিজে থেকেই থাকে। এর ফলে VPC-র ভেতরের সব subnet একে অপরের কাছে পৌঁছাতে পারে। সাধারণত এটি মোছা যায় না। “পৌঁছাতে পারা” মানে অবশ্য “অনুমতি আছে” নয়। অনুমতির কাজ security group-এর, যা পর্ব ২৭-এ আসবে।
দ্বিতীয় সারিটি default route. 0.0.0.0/0 মানে “সব ঠিকানা”। অন্য কোনো সারি না মিললে packet এই পথে যায়। ডাকঘরের “বাকি সব” বস্তার মতো।
Subnet আর table-এর সম্পর্ক
প্রতিটি subnet একসময়ে ঠিক একটি table-এর সাথে যুক্ত থাকে। এই সংযোগকে association বলে। একটি table অনেক subnet ব্যবহার করতে পারে। যে subnet-কে আপনি কোনো table-এ যুক্ত করেননি, সে পড়ে যায় main route table-এ। এই নীরব আচরণ থেকেই অনেক ভুল জন্মায়, যা অংশ ৮-এ দেখবেন।
Instance নিজে route table পড়ে না। তার OS শুধু জানে “বাইরের সব কিছু subnet-এর router ঠিকানায় যাবে”, যেমন 10.0.11.1, মানে subnet-এর শুরুর ঠিকানা + ১. এই ঠিকানায় আছে একটি virtual router. আসল সিদ্ধান্ত নেয় cloud-এর network, table দেখে। তাই VM-এর ভেতরে ip route চালিয়ে cloud-এর table দেখা যায় না। ip route কীভাবে পড়তে হয়, তা পর্ব ১৩-এ আছে।
Target কত রকম
| Target | কোথায় যায় | কখন লাগে |
|---|---|---|
local | VPC-র ভেতরে | সব table-এ নিজে থেকেই |
| Internet gateway | ইন্টারনেট, দুই দিকে | Public subnet |
| NAT gateway | ইন্টারনেট, শুধু বাইরে শুরু হওয়া সংযোগ | Private subnet |
| Peering বা transit | অন্য VPC | পর্ব ২৮ |
| VPN বা dedicated link | অফিস বা নিজের data center | পর্ব ২৮ |
| Gateway endpoint | একই region-এর storage সার্ভিস | NAT-এর খরচ এড়াতে, পর্ব ২৮ |
| Network interface | নিজের firewall বা appliance | সব traffic পরিদর্শন করতে |
Target মুছে গেলে route থেকে যায়, কিন্তু কোথাও পৌঁছায় না। একে blackhole route বলে। AWS-এর console-এ এমন route-এর পাশে blackhole লেখা দেখা যায়।
দুই AZ-এর VPC: route table, internet gateway আর NAT
Two public and two private subnets, one internet gateway, one NAT per AZ
10.0.0.0/16 → local আছে, ছবিতে দেখানো হয়নি।২ · Longest-prefix match — সবচেয়ে নির্দিষ্ট পথ জেতে
একটি ঠিকানা একাধিক সারিতে মিলতে পারে। 0.0.0.0/0 তো সব ঠিকানাতেই মেলে। তাহলে কোনটি জিতবে? নিয়মটি একটিই: longest-prefix match. যে সারির prefix সবচেয়ে লম্বা, অর্থাৎ /-এর পরের সংখ্যা সবচেয়ে বড়, সেটিই জেতে।
“রাজশাহী শহর” লেখা চিঠি “রাজশাহী বিভাগ” আর “বাকি সব”, দুই সারিতেই মেলে। কর্মী বেছে নেন সবচেয়ে নির্দিষ্টটি, “রাজশাহী শহর”। সারিগুলো দেয়ালে কোন ক্রমে লেখা, তাতে কিছু আসে যায় না। Route table-ও তাই।
মেলানোর হিসাবটি সহজ। ধরুন গন্তব্য 10.1.5.9 আর সারি 10.1.0.0/16. /16 মানে প্রথম ১৬ bit তুলনা করতে হবে, অর্থাৎ প্রথম দুটি সংখ্যা। 10.1 আর 10.1 সমান, তাই মিলেছে। 10.1.5.0/24-এর প্রথম ২৪ bit, অর্থাৎ 10.1.5-ও মেলে। ২৪ বড়, তাই /24 জিতবে।
Prefix দৈর্ঘ্য ৮-এর গুণিতক না হলে bit দেখতে হয়। 10.0.4.0/22-এর তৃতীয় সংখ্যা 4, বাইনারিতে 00000100. /22 মানে তৃতীয় সংখ্যার প্রথম ৬ bit স্থির, তাই 4 থেকে 7 পর্যন্ত সবই এর ভেতরে। CIDR-এর পুরো হিসাব Subnetting পর্বে আছে।
নিচের সিমুলেটরে table-এর সারিগুলো ইচ্ছে করে এলোমেলো রাখা হয়েছে। প্রতিটি গন্তব্যের জন্য কোড সব সারি দেখে, আর যত সারি মেলে তার মধ্যে সবচেয়ে লম্বা prefix রাখে। Table আর গন্তব্য বদলে নিজে পরীক্ষা করুন।
// One route table. Most specific matching prefix wins; order does not matter.
const table = [
["0.0.0.0/0", "nat-a"], // default route
["10.0.0.0/16", "local"],
["10.1.0.0/16", "peering-1"],
["10.1.5.0/24", "vpn-1"],
["198.51.100.0/24", "storage-endpoint"],
];
const toInt = ip => ip.split(".").reduce((n, b) => n * 256 + Number(b), 0);
const maskOf = len => (len === 0 ? 0 : (0xFFFFFFFF << (32 - len)) >>> 0);
function lookup(dst) {
const ip = toInt(dst);
let best = null;
for (const [cidr, target] of table) {
const [net, lenText] = cidr.split("/");
const len = Number(lenText), mask = maskOf(len);
const same = ((ip & mask) >>> 0) === ((toInt(net) & mask) >>> 0);
if (same && (!best || len > best.len)) best = { cidr, target, len };
}
return best;
}
const dests = ["10.0.11.20", "10.1.5.9", "10.1.9.9", "10.2.0.1",
"198.51.100.80", "198.51.101.80", "203.0.113.50"];
for (const d of dests) {
const r = lookup(d);
console.log(d.padEnd(15) + r.cidr.padEnd(17) + "-> " + r.target);
}আউটপুট পড়ুন। 10.1.5.9 তিনটি সারিতে মেলে, জেতে 10.1.5.0/24 -> vpn-1. 10.1.9.9 ওই /24-এর বাইরে, তাই জেতে 10.1.0.0/16 -> peering-1. 10.2.0.1 VPC-র মতো দেখতে হলেও কোনো নির্দিষ্ট সারিতে নেই, তাই চলে যায় 0.0.0.0/0 -> nat-a-এ। 198.51.100.80 যায় storage-endpoint-এ, অথচ একটি সংখ্যা আলাদা 198.51.101.80 যায় NAT-এ। এই একটি নিয়মের জন্যই পরে endpoint যোগ করলে পুরোনো NAT route না মুছেও storage-এর traffic সরে আসে।
একই prefix দুবার থাকলে কী হয়? এটি provider-ভেদে আলাদা। Azure-এর নথিতে আগে longest-prefix, তারপর নিজের দেওয়া route, তারপর BGP, শেষে system route. Google Cloud-এ route-এর priority নম্বর আছে। AWS-এ static route সাধারণত শেখা route-এর আগে আসে। মূল কথা, prefix-এর দৈর্ঘ্য সবার আগে দেখা হয়।
৩ · Internet gateway — আর public subnet-এর আসল সংজ্ঞা
Internet gateway (সংক্ষেপে IGW) হলো VPC আর ইন্টারনেটের মাঝের দরজা। এটি কোনো একটি VM নয়, আর একটি AZ-এর জিনিসও নয়। Provider এটি নিজে চালান, আপনি শুধু VPC-র সাথে যুক্ত করেন। আপনার দিক থেকে এর ক্ষমতা বাড়ানোর কিছু নেই।
IGW দুটি কাজ করে। এক, route table-এর target হিসেবে ইন্টারনেটের দিকে পথ দেয়। দুই, IPv4-এর জন্য 1:1 ঠিকানা অনুবাদ করে। এখানেই বেশিরভাগ নতুন শিক্ষার্থীর ভুল ধারণা ভাঙে।
Instance-এর OS নিজের public IP জানে না। তার interface-এ থাকে শুধু private IP. Public ঠিকানাটি থাকে IGW-র খাতায়, “এই private ঠিকানা = ওই public ঠিকানা” হিসেবে। Packet বের হওয়ার সময় IGW source বদলে দেয়, ঢোকার সময় destination বদলে ফিরিয়ে আনে।
নিচের ধাপগুলোতে একটি public instance web-1-এর packet দেখুন। “পরে” চাপলে টেবিলের source আর destination বদলাবে।
- web-1
10.0.1.25public subnet - IGW
1:1অনুবাদ - Server
198.51.100.80ইন্টারনেটে
| Src | |
| Dst | |
| কোথায় |
- Packet তৈরি।
web-1নিজের ঠিকানা10.0.1.25source হিসেবে বসায়, কারণ সে এটুকুই জানে। Subnet-এর table-এ0.0.0.0/0 → igwমেলে, তাই packet IGW-র দিকে যায়। - IGW source বদলাল। খাতায় লেখা
10.0.1.25 = 203.0.113.25. Source হলো203.0.113.25:50000. Port বদলায়নি, কারণ একটি private ঠিকানার জন্য একটি পুরো public ঠিকানা আছে। এটিই 1:1. - Server দেখল public ঠিকানা।
198.51.100.80-এর log-এ203.0.113.25ওঠে। Private ঠিকানাটি VPC-র বাইরে কখনো দেখা যায়নি। - উত্তর ফিরল। Server উত্তর পাঠায়
203.0.113.25:50000-এ। ইন্টারনেটের router এই ঠিকানা চেনে, তাই packet provider-এর network হয়ে IGW-তে আসে। - IGW destination ফেরাল। Destination আবার
10.0.1.25:50000হলো, আর packetweb-1-এ পৌঁছাল। OS কখনো জানল না যে মাঝখানে অনুবাদ হয়েছে। বাইরে থেকে নতুন সংযোগও এই পথেই আসে, যদি firewall অনুমতি দেয়।
Public subnet কাকে বলে
এবার সংজ্ঞাটি পরিষ্কার। Public subnet কোনো বিশেষ ধরনের subnet নয়। Console-এ এমন কোনো টিক-বক্স নেই। একটি subnet public, যদি তার route table-এ IGW-র দিকে route থাকে। Route না থাকলে সেটি private subnet. পার্থক্যটি পুরোপুরি একটি table-এর একটি সারির।
কিন্তু route একা যথেষ্ট নয়। সরাসরি ইন্টারনেটে কথা বলতে একটি instance-এর তিনটি জিনিস লাগে:
এই সংজ্ঞা AWS-ধাঁচের। Google Cloud-এ VPC-র route subnet-ভিত্তিক নয়, আর “public subnet” বলে কোনো আনুষ্ঠানিক ধারণা নেই: বাইরের IP থাকলে VM বাইরে যেতে পারে। Azure-এ IGW নামে আলাদা কোনো জিনিস নেই, ইন্টারনেট একটি system route-এর target. ধারণা একই, নাম আর আকার আলাদা। লেখার সময়ে অনেক provider public IPv4-এর জন্যও ঘণ্টাপ্রতি টাকা নেন, তাই প্রতিটি server-এ public IP দেওয়া এখন খরচেরও প্রশ্ন।
৪ · NAT gateway — ভেতর থেকে বাইরে, উল্টো দিকে নয়
Database আর app server-কে ইন্টারনেট থেকে দেখা যাওয়া উচিত নয়, তাই এগুলো থাকে private subnet-এ। কিন্তু এদেরও বাইরে যেতে হয়: security patch নামাতে, package আনতে, বাইরের payment API ডাকতে। দরকার এমন একটি পথ, যেটি শুধু একদিকে খোলা। সেটিই NAT gateway.
একটি মেসের কথা ভাবুন। ২০ জন থাকেন, কিন্তু বাইরের জগতে ফোন নম্বর একটিই, ম্যানেজারের। কেউ খাবার অর্ডার করতে চাইলে ম্যানেজারকে বলেন। ম্যানেজার খাতায় লেখেন “৭ নম্বর অর্ডার, রুম ১২”, তারপর নিজের নম্বর থেকে ফোন করেন। ডেলিভারি এলে খাতা দেখে রুম ১২-এ পাঠান। কিন্তু অচেনা কেউ ফোন করে “রুম ১২ দিন” বললে ম্যানেজারের খাতায় মিল নেই, তাই লাইন কেটে যায়।
NAT-এর তত্ত্ব, port ব্যবহার করে অনেক ঠিকানাকে একটিতে আনার কৌশল আর খাতার গঠন Computer Networks কোর্সের NAT পর্বে বিস্তারিত আছে। এখানে দেখব cloud-এ এটি কীভাবে বসে। NAT gateway-র নিজের একটি private ঠিকানা আর একটি static public IP থাকে। এটি বসে public subnet-এ। Private subnet-এর table-এর default route একে দেখায়।
নিচের ধাপগুলো এই পর্বের কেন্দ্র। app-1 একটি apt mirror-এ যাচ্ছে। প্রতিটি ধাপে source বদলানো খেয়াল করুন। AWS-এর নথি অনুযায়ী এখানে অনুবাদ হয় দুবার: NAT-এ, তারপর IGW-তে।
- app-1
10.0.11.20private - NAT
10.0.1.5public subnet - IGW
1:1অনুবাদ - Mirror
198.51.100.80ইন্টারনেটে
| Src | |
| Dst | |
| খাতা | |
| বদল |
- app-1 পাঠাল। Source
10.0.11.20:49152, destination198.51.100.80:443. High port49152OS বেছেছে, একে ephemeral port বলে। Table-এ0.0.0.0/0 → nat-aমেলে। - NAT source বদলাল। NAT নিজের একটি খালি port বেছে নেয়,
61000. Source হয়10.0.1.5:61000, আর NAT-এর খাতায় ওঠে61000 = app-1:49152, যেখানেapp-1মানে10.0.11.20. একে SNAT বলে। - Public subnet-এর table. NAT যে subnet-এ বসে, তার table দেখে:
0.0.0.0/0 → igw. ঠিকানা বদলায় না। এই route না থাকলে packet এখানেই আটকে যেত। অংশ ৮-এর “NAT private subnet-এ” ভুলটি ঠিক এটাই। - IGW source বদলাল। NAT-এর private ঠিকানা
10.0.1.51:1 অনুবাদে হলো203.0.113.10. Port অপরিবর্তিত61000. এই বদল আগের অংশের instance-এর মতোই। - Mirror উত্তর দিল। Mirror দেখে অনুরোধ এসেছে
203.0.113.10:61000থেকে। উত্তরে source198.51.100.80:443, destination203.0.113.10:61000.app-1-এর নাম সে জানেই না। - IGW destination ফেরাল। Destination হলো
10.0.1.5:61000. Packet NAT-এ যায়। - NAT খাতা দেখল।
61000-এর সারি পাওয়া গেল। Destination হলো10.0.11.20:49152. বাইরের কেউ অকারণে203.0.113.10-এ packet পাঠালে খাতায় সারি মিলত না, আর packet বাদ পড়ত। “একমুখী” কথাটির মানে এটিই। - app-1 পেল। Packet
localroute ধরে পৌঁছাল।app-1-এর চোখে সে সরাসরি mirror-এর সাথে কথা বলছে। Source ঠিকানা পুরো পথে মোট দুবার বদলেছে, ফেরার পথে destination-ও দুবার।
NAT firewall নয়। “বাইরে থেকে ঢোকা যায় না” কথাটি খাতার পার্শ্বফল, কোনো নিরাপত্তা নীতি নয়। আর NAT শুধু সংযোগের শুরুর দিক ঠিক করে। একবার সংযোগ হলে দুই দিকেই ডেটা চলে, তাই malware-ও বাইরে ডেটা পাঠাতে পারে। Outbound নিয়ন্ত্রণের জন্য firewall লাগে।
NAT-এর একটি বাস্তব সীমাও আছে। এক public ঠিকানার port সংখ্যা সীমিত। একই destination ঠিকানা, port আর protocol-এ বহু সংযোগ খুললে port ফুরিয়ে যেতে পারে, একে port exhaustion বলে। AWS-এর নথিতে প্রতি public IP-তে একই destination-এর জন্য প্রায় ৫৫,০০০ সংযোগের কথা আছে, লেখার সময়ে। সমাধান: বেশি public IP যোগ করা, connection pool ব্যবহার, বা destination ভাগ করা।
৫ · প্রতি AZ-এ NAT, NAT instance আর IPv6-এর পথ
একটি NAT কেন যথেষ্ট নয়
AWS ও Azure-এর সাধারণ NAT gateway একটি নির্দিষ্ট availability zone-এর ভেতরে থাকে। সেই AZ-এ বড় সমস্যা হলে NAT-ও যায়। ধরুন আপনার একটিই NAT, AZ-a-তে, আর সব private subnet তাকেই দেখায়। AZ-a পড়ে গেলে AZ-b-র সুস্থ server-গুলোও বাইরে যেতে পারবে না। আপনি দুই AZ-এ server রেখে যে সুরক্ষা কিনলেন, একটি NAT তা নষ্ট করে দিল। NAT তখন একটি লুকানো single point of failure হয়ে গেল।
আরেকটি দাম আছে। AZ-b থেকে AZ-a-র NAT-এ যাওয়া প্রতি GB traffic-এ data transfer খরচ হতে পারে। তাই সাধারণ নকশা: প্রতি AZ-এ একটি NAT, আর প্রতি AZ-এর private subnet-এর জন্য আলাদা route table, ঠিক ছবি ২৬.১-এর মতো। এক AZ-এর NAT গেলে শুধু সেই AZ-এর outbound যায়, আর সেই AZ-এর server-ও তখন সমস্যায়। ব্যর্থতার সীমা AZ-এর ভেতরেই থাকে।
Google Cloud-এর Cloud NAT region-স্তরের, আর AWS-ও ২০২৫ সালের নভেম্বরে region-স্তরের NAT gateway-র বিকল্প এনেছে। আপনার provider-এর বর্তমান নথি দেখে নিন। “একটি NAT মানেই ঝুঁকি” কথাটি শুধু zone-স্তরের NAT-এর জন্য সত্য।
NAT instance বনাম managed NAT
Managed সার্ভিসের আগে মানুষ একটি Linux VM-কেই NAT বানাতেন: IP forwarding চালু, iptables-এ masquerade, আর AWS-এ source/destination check বন্ধ। এখনো এটি সম্ভব, একে NAT instance বলে।
| বিষয় | NAT instance | Managed NAT |
|---|---|---|
| Patch, reboot, মনিটর | আপনার দায়িত্ব | Provider-এর |
| ব্যর্থ হলে | নিজে failover বানাতে হয় | AZ-এর ভেতরে provider সামলান |
| গতি | VM-এর আকারে আটকে থাকে | নিজে থেকে অনেক বড় সীমা পর্যন্ত বাড়ে |
| খরচের ধরন | VM-এর ভাড়া, GB-তে আলাদা ফি সাধারণত নেই | ঘণ্টা + প্রতি GB |
| নমনীয়তা | নিজের firewall, log, proxy যোগ করা যায় | কম |
| মানায় | ছোট বাজেট, dev পরিবেশ, শেখা | Production-এর সাধারণ পছন্দ |
IPv6: অনুবাদের দরকার নেই, দরজা এখনো দরকার
IPv6-এ ঠিকানার অভাব নেই, তাই instance সরাসরি বিশ্বজুড়ে অনন্য ঠিকানা পায়। NAT-এর মূল কারণটিই তখন নেই। কিন্তু private server-কে ইন্টারনেট থেকে আড়াল করার প্রয়োজন তো থাকে। AWS-এ এই কাজ করে egress-only internet gateway: ভেতর থেকে শুরু হওয়া সংযোগ যেতে দেয়, বাইরে থেকে শুরু হওয়া সংযোগ আটকায়। ঠিকানা বদলায় না। Route দেখতে হয় এরকম: ::/0 → eigw. অন্য provider-এ একই ফল সাধারণত firewall নিয়ম দিয়ে আসে। IPv6-এর ঠিকানা-গঠন IPv6 পর্বে পাবেন।
৬ · NAT-এর বিল — ঘণ্টা, প্রতি GB আর storage endpoint
NAT gateway-র বিল অনেক দলকে অবাক করে। কারণ এর খরচ দুই ভাগে: চালু থাকার ঘণ্টা, আর ভেতর দিয়ে যাওয়া প্রতি GB. দ্বিতীয়টির নাম data processing charge. এটি egress-এর ওপরে আলাদা করে বসে, আর সাধারণত দুই দিকের ডেটাতেই লাগে।
সবচেয়ে সাধারণ অপচয় হলো একই region-এর object storage-এ যাওয়া ডেটা। Private server একটি bucket থেকে backup টানছে, আর প্রতিটি GB NAT পার হচ্ছে, অথচ গন্তব্য একই region-এর ভেতরে। এখানে gateway endpoint কাজে লাগে। এটি route table-এ storage সার্ভিসের ঠিকানা-তালিকার জন্য একটি বেশি নির্দিষ্ট route বসায়। Longest-prefix match-এর জোরে storage-এর traffic NAT এড়িয়ে যায়, default route অক্ষত থাকে। Endpoint-এর ধরন আর নিরাপত্তা পর্ব ২৮-এ আসবে।
নিচের হিসাবে সব দর অনুমিত: NAT ঘণ্টায় $০.০৫, প্রতি GB $০.০৫, ইন্টারনেট egress প্রতি GB $০.০৯, AZ পার হলে প্রতি GB $০.০২. আরও ধরে নিচ্ছি, gateway endpoint বিনা খরচে আর একই region-এর storage-এ transfer খরচ নেই। এগুলো AWS-এর gateway endpoint-এর লেখার সময়ের আচরণের সাথে মেলে, কিন্তু আপনার provider-এর pricing পাতা দেখে নিন।
// All prices are ASSUMED round numbers. Check your provider's pricing page.
const P = { natHour: 0.05, natPerGB: 0.05, egressPerGB: 0.09, crossAzPerGB: 0.02 };
const HOURS = 720; // 30-day month
const storageGB = 9000; // private servers <-> object storage, same region
const internetGB = 3000; // private servers <-> public internet
function month({ nats, endpoint, otherAzShare }) {
const viaNat = internetGB + (endpoint ? 0 : storageGB);
const hourly = nats * P.natHour * HOURS;
const process = viaNat * P.natPerGB;
const egress = internetGB * P.egressPerGB;
const crossAz = viaNat * otherAzShare * P.crossAzPerGB;
const total = hourly + process + egress + crossAz;
return { viaNat, hourly, process, egress, crossAz, total };
}
const plans = [
["2 NAT, no endpoint", { nats: 2, endpoint: false, otherAzShare: 0 }],
["2 NAT, endpoint", { nats: 2, endpoint: true, otherAzShare: 0 }],
["1 NAT, no endpoint", { nats: 1, endpoint: false, otherAzShare: 0.5 }],
["1 NAT, endpoint", { nats: 1, endpoint: true, otherAzShare: 0.5 }],
];
const f = x => x.toFixed(2).padStart(8);
console.log("plan viaNAT hour processing egress crossAZ total");
for (const [name, p] of plans) {
const m = month(p);
console.log(name.padEnd(19) + String(m.viaNat).padStart(6) + f(m.hourly) +
f(m.process).padStart(11) + f(m.egress) + f(m.crossAz) + f(m.total));
}
const save = month(plans[0][1]).total - month(plans[1][1]).total;
console.log("endpoint saves per month with 2 NAT: $" + save.toFixed(2));প্রথম সারি হাতে মেলান। ঘণ্টা: 2 × 0.05 × 720 = $72. Processing: 12,000 × 0.05 = $600. Egress: 3,000 × 0.09 = $270. মোট 942.00. Endpoint দিলে NAT দিয়ে যায় শুধু 3,000 GB, processing নামে $150-এ, মোট 492.00, আর আউটপুটের শেষ লাইন বলে $450.00 সাশ্রয়।
এবার ৩য় সারি দেখুন। “টাকা বাঁচাতে” একটি NAT রাখলে ঘণ্টার খরচ অর্ধেক হয়, কিন্তু অর্ধেক traffic AZ পার হয়, তাই মোট 1026.00, দুই NAT-এর চেয়েও বেশি। আর ৪র্থ সারিতে 486.00, মানে এই অনুমিত সংখ্যায় দুই NAT-এর চেয়ে মাত্র $6 কম। অর্থাৎ $6-এ পুরো একটি AZ-এর স্বাধীনতা কেনা যাচ্ছে। সিদ্ধান্তের আগে এই হিসাব করে নিন, কারণ সংখ্যা আপনার traffic-এর ওপর নির্ভর করে।
বিল কমানোর ক্রমটি মনে রাখুন: আগে দেখুন কোন গন্তব্য সবচেয়ে বেশি GB নিচ্ছে (flow log দিয়ে, অংশ ৯)। তারপর storage-এ endpoint, container image-এর জন্য একই region-এর registry, আর নিজের সার্ভিসগুলোর জন্য VPC-র ভেতরের পথ। শেষে অপ্রয়োজনীয় সংখ্যক NAT আছে কি না দেখুন। Cloud-এর বিলের বড় ছবি পর্ব ৭২-এ আসবে।
৭ · পথের উল্টো দিক — asymmetric path
এতক্ষণ যাওয়ার পথ দেখলাম। কিন্তু route table শুধু এক দিকের কথা বলে। উত্তরের packet-এর জন্য উল্টো দিকের table আলাদাভাবে কাজ করে। যাওয়া আর আসার পথ আলাদা হলে তাকে asymmetric path বলে।
Router-এর জন্য এটি সমস্যা নয়। ইন্টারনেটে এমন প্রায়ই হয়, কারণ router প্রতিটি packet আলাদাভাবে বিচার করে, কিছু মনে রাখে না। সমস্যা হয় যন্ত্রটি stateful হলে, অর্থাৎ যে নিজের খাতায় সংযোগ মনে রাখে: NAT আর firewall. যে পথে সংযোগ শুরু হয়নি, সেই পথের যন্ত্রের খাতায় সারিই নেই।
| ঘটনা | কী হয় | ফল |
|---|---|---|
| Private subnet-এর instance-কে public IP দেওয়া হলো, table-এর default route NAT-এ | অনুরোধ IGW দিয়ে ঢোকে, উত্তর NAT দিয়ে বের হয়, source বদলে যায় | Client অচেনা ঠিকানা থেকে উত্তর পেয়ে ফেলে দেয়, সংযোগ timeout |
| Firewall appliance দুই AZ-এ, যাওয়া একটিতে, আসা অন্যটিতে | দ্বিতীয় firewall-এর খাতায় এই সংযোগ নেই | উত্তর বাদ পড়ে |
| দুটি network interface-এর VM, দুই subnet-এ | এক interface-এ অনুরোধ, অন্যটি দিয়ে উত্তর | Security group বা OS-এর reverse-path যাচাইয়ে আটকায় |
লক্ষণটি চেনা দরকার: একদিকের packet দেখা যায়, অন্যদিকের নয়, আর TCP handshake শেষ হয় না। সমাধানের নিয়ম সহজ: একটি সংযোগের দুই দিক একই stateful যন্ত্র দিয়ে যাবে। প্রথম উদাহরণে instance-কে সত্যিই public করতে চাইলে public subnet-এ আনুন। না চাইলে public IP সরিয়ে load balancer ব্যবহার করুন (পর্ব ১৮)।
৮ · পথের চারটি সাধারণ ভুল — আর সমস্যা খোঁজার ধারা
“Private server ইন্টারনেট পাচ্ছে না” এই অভিযোগের বেশিরভাগ উত্তর চারটি ঘরের মধ্যে পড়ে:
| ভুল | কীভাবে ঘটে | ঠিক করার পথ |
|---|---|---|
| Route নেই | Table-এ শুধু local, অথবা target মুছে যাওয়ায় blackhole | Default route যোগ বা বদল |
| ভুল table | নতুন subnet কোনো table-এ যুক্ত হয়নি, তাই main table পেয়েছে | Association ঠিক করা |
| NAT private subnet-এ | NAT বানানোর সময় ভুল subnet বাছাই, তার নিজের ইন্টারনেট পথ নেই | Public subnet-এ নতুন NAT, পুরোনোটি মোছা |
| Public IP নেই | Public subnet-এর instance, কিন্তু auto-assign বন্ধ | Static public IP যুক্ত করা, অথবা NAT-এর পেছনে রাখা |
এই চিন্তাটিই একটি প্রোগ্রাম হিসেবে নিচে আছে। Path tracer instance থেকে শুরু করে subnet, table, NAT আর IGW পর্যন্ত এগোয়, আর প্রথম ভুলটিতে থেমে যায়। প্রকৃত reachability tool-ও মূলত এভাবেই configuration বিশ্লেষণ করে।
// Walk from an instance towards the internet. Return the first fault.
function trace(c) {
const hops = [c.vm.name], stop = why => ({ hops, why });
const tableOf = s => c.assoc[s] || "main"; // no link = main table
const next = s => c.tables[tableOf(s)]["0.0.0.0/0"];
hops.push(c.vm.subnet + ":" + tableOf(c.vm.subnet));
const t1 = next(c.vm.subnet);
if (!t1) return stop("NO DEFAULT ROUTE in table " + tableOf(c.vm.subnet));
if (t1 === "igw") {
hops.push("igw");
return stop(c.vm.publicIp ? "OK" : "NO PUBLIC IP: igw has nothing to translate to");
}
const nat = c.nats[t1];
if (!nat) return stop("BLACKHOLE: target " + t1 + " does not exist");
hops.push(t1, nat.subnet + ":" + tableOf(nat.subnet));
if (next(nat.subnet) !== "igw") return stop("NAT IN PRIVATE SUBNET: " + nat.subnet + " has no igw route");
hops.push("igw"); return stop("OK");
}
const tables = { main: {}, "rt-pub": { "0.0.0.0/0": "igw" },
"rt-prv": { "0.0.0.0/0": "nat-a" }, "rt-old": { "0.0.0.0/0": "nat-x" } };
const base = { tables, nats: { "nat-a": { subnet: "pub-a" } },
assoc: { "pub-a": "rt-pub", "app-a": "rt-prv" } };
const app = { name: "app-1", subnet: "app-a" }, web = { name: "web-1", subnet: "pub-a" };
const cases = [
["healthy private", { ...base, vm: app }],
["wrong table", { ...base, vm: app, assoc: { "pub-a": "rt-pub" } }],
["old NAT deleted", { ...base, vm: app, assoc: { "pub-a": "rt-pub", "app-a": "rt-old" } }],
["NAT misplaced", { ...base, vm: app, nats: { "nat-a": { subnet: "app-a" } } }],
["no public IP", { ...base, vm: web }],
["healthy public", { ...base, vm: { ...web, publicIp: "203.0.113.25" } }],
];
for (const [name, cfg] of cases) {
const r = trace(cfg);
console.log(name.padEnd(16) + r.why + "\n path: " + r.hops.join(" > "));
}healthy private-এর পথ পুরো: app-1 > app-a:rt-prv > nat-a > pub-a:rt-pub > igw. wrong table-এ association না থাকায় subnet পড়েছে main table-এ, আর আউটপুট NO DEFAULT ROUTE in table main. NAT misplaced-এ পথ NAT পর্যন্ত গিয়ে আবার app-a:rt-prv-তে ফিরেছে, মানে NAT নিজেই বাইরে যেতে পারছে না। no public IP-এ route ঠিক থাকা সত্ত্বেও থামে, কারণ IGW-র অনুবাদের জন্য কোনো ঠিকানা নেই। বাস্তব tool আরও অনেক কিছু দেখে, যেমন firewall নিয়ম। কিন্তু মূল ধারণা এটুকুই: packet-এর পথ ধরে এগোনো, আর প্রথম ভাঙা জায়গায় থামা।
একটি বাস্তব ঘটনা, ধাপে ধাপে
একটি কাল্পনিক অনলাইন বাজার অ্যাপের app-1-এ security patch দিতে গিয়ে apt-get update আটকে গেছে। নিচের ধাপগুলো সেই খোঁজ। সব আউটপুট নমুনা, version-ভেদে আলাদা হতে পারে, আর সব id কাল্পনিক।
$ sudo apt-get update
Err:1 https://mirror.example.com/ubuntu noble InRelease
Could not connect to mirror.example.com:443
(198.51.100.80), connection timed out
$ dig +short mirror.example.com
198.51.100.80
$ curl -sS -m 5 -o /dev/null https://mirror.example.com
curl: (28) Failed to connect to mirror.example.com
port 443 after 5001 ms: Timeout was reached
$ ip route default via 10.0.11.1 dev ens5 10.0.11.0/24 dev ens5 proto kernel scope link src 10.0.11.20 # OS ঠিক আছে। বাকি সিদ্ধান্ত cloud-এর table-এ।
$ aws ec2 describe-route-tables \
--filters Name=association.subnet-id,Values=subnet-0app \
--query "RouteTables[].Routes[]" --output text
10.0.0.0/16 local active
0.0.0.0/0 nat-0aaa active
$ aws ec2 describe-nat-gateways --nat-gateway-ids nat-0aaa \
--query "NatGateways[].[State,SubnetId]" --output text
available subnet-0app
# NAT বসে আছে app-এর নিজের private subnet-এ!
10.0.11.20 198.51.100.80 49152 443 6 ... ACCEPT OK # বাইরে যাওয়ার কোনো রেকর্ড নেই, ফিরতি রেকর্ডও নেই। # ACCEPT মানে firewall আটকায়নি, পৌঁছেছে এমন নয়।
$ aws ec2 create-nat-gateway --subnet-id subnet-0pub \
--allocation-id eipalloc-0bbb
$ aws ec2 replace-route --route-table-id rtb-0app \
--destination-cidr-block 0.0.0.0/0 --nat-gateway-id nat-0bbb
$ sudo apt-get update # app-1 থেকে যাচাই
$ aws ec2 delete-nat-gateway --nat-gateway-id nat-0aaa
- লক্ষণ পড়ুন। মেসেজে IP দেখা যাচ্ছে, মানে নাম খুঁজে পাওয়া গেছে। আর শব্দটি
timed out,refusedনয়। Refused মানে কেউ উত্তর দিয়ে না বলেছে। Timeout মানে packet হারিয়ে গেছে বা উত্তর ফেরেনি। - DNS বাদ দিন।
digঠিকানা দিয়েছে।curl-ও timeout দিচ্ছে, তাই সমস্যা apt-এর নয়, পথের। - OS দেখুন। Default route আছে, virtual router
10.0.11.1-এ যাচ্ছে। OS-এর কাজ এখানেই শেষ। এখান থেকে VM-এর ভেতরের কোনো কমান্ড আর কিছু দেখাবে না। - Subnet-এর table দেখুন। OS নয়, cloud-এর API.
0.0.0.0/0 → nat-0aaaআছে, আরactive. Blackhole নয়। সাধারণ প্রথম সন্দেহ বাদ গেল। Filter কিছু না ফেরালে বুঝতেন subnet main table-এ পড়ে আছে। - পরের ধাপে যান: NAT. অবস্থা
available, কিন্তু তার subnetsubnet-0app, অর্থাৎ যে subnet থেকে packet আসছে, সেটিই। NAT-এর নিজের table-এর default route তাকেই দেখায়, IGW-কে নয়। প্রথম ভাঙা জায়গা পাওয়া গেল। - প্রমাণ মেলান। Flow log-এ instance থেকে আসা packet
ACCEPT, কিন্তু NAT থেকে বাইরে যাওয়ার রেকর্ড নেই। ফলে তত্ত্বটি মিলে গেল। Reachability tool চালালেও একই জায়গা দেখাত। - ঠিক করুন, যাচাই করুন। NAT-কে অন্য subnet-এ সরানো যায় না, তাই public subnet-এ নতুন NAT, তারপর route বদল।
apt-get updateচলার পরই পুরোনো NAT মুছুন। নতুন NAT দাঁড়াতে কয়েক মিনিট লাগতে পারে, তাই route আগে বদলাবেন না।
৯ · Flow log আর reachability tool — প্রমাণ জোগাড়
পথ কেমন হওয়া উচিত, তা বলে configuration. আসলে কী ঘটছে, তা বলে flow log. প্রতিটি network interface-এর জন্য এটি সংক্ষিপ্ত রেকর্ড রাখে: কে, কাকে, কোন port, কত packet, আর সিদ্ধান্ত ACCEPT না REJECT. ভেতরের ডেটা এতে থাকে না। রেলস্টেশনের রেজিস্টার ভাবুন: কে এলো গেল লেখা আছে, ব্যাগের ভেতর কী, তা নয়।
নিচের Bash block-এ AWS-এর ডিফল্ট ধাঁচের ১৪টি ঘরের নমুনা log আছে, প্রথম সারিতে ঘরগুলোর নাম। ঠিকানাগুলো নমুনা। awk আগে দেখেছেন পর্ব ৯-এ। আমরা খুঁজব কোন flow আটকে গেছে।
set -euo pipefail
# Flow log sample in the common space-separated default layout.
log=$(mktemp); trap 'rm -f "$log"' EXIT
cat > "$log" <<'LOG'
version account eni src dst srcport dstport proto packets bytes start end action status
2 123456789012 eni-0app 10.0.11.20 203.0.113.80 49152 443 6 6 480 1760000000 1760000060 ACCEPT OK
2 123456789012 eni-0app 203.0.113.80 10.0.11.20 443 49152 6 5 3120 1760000000 1760000060 REJECT OK
2 123456789012 eni-0app 10.0.11.20 203.0.113.80 49153 443 6 6 480 1760000060 1760000120 ACCEPT OK
2 123456789012 eni-0app 203.0.113.80 10.0.11.20 443 49153 6 5 3120 1760000060 1760000120 REJECT OK
2 123456789012 eni-0app 10.0.11.20 10.0.21.5 41000 5432 6 12 2100 1760000000 1760000060 ACCEPT OK
2 123456789012 eni-0db 10.0.12.30 10.0.21.5 41222 5432 6 3 180 1760000000 1760000060 REJECT OK
2 123456789012 eni-0db 10.0.12.30 10.0.21.5 41223 5432 6 3 180 1760000060 1760000120 REJECT OK
2 123456789012 eni-0db 10.0.12.30 10.0.21.5 41224 5432 6 3 180 1760000120 1760000180 REJECT OK
2 123456789012 eni-0web 198.51.100.7 10.0.1.25 53211 22 6 1 60 1760000000 1760000060 REJECT OK
2 123456789012 eni-0web 198.51.100.7 10.0.1.25 53212 3389 6 1 60 1760000000 1760000060 REJECT OK
2 123456789012 eni-0web 203.0.113.9 10.0.1.25 55000 443 6 9 1400 1760000000 1760000060 ACCEPT OK
2 123456789012 eni-0idle - - - - - - - 1760000000 1760000060 - NODATA
LOG
echo "== records by action =="
awk 'NR>1 && $14=="OK" {print $13}' "$log" | sort | uniq -c
echo "== rejected: src -> dst:dstport, by count =="
awk 'NR>1 && $13=="REJECT" {print $4, "->", $5":"$7}' "$log" |
sort | uniq -c | sort -k1,1nr -k2,2
echo "== rejected replies (server port to high port) =="
awk 'NR>1 && $13=="REJECT" && $6<1024 && $7>=1024 {
print $4":"$6, "->", $5":"$7, "pkts="$9 }' "$log"প্রথম সারণি বলে 4 ACCEPT আর 7 REJECT. NODATA সারিটি বাদ গেছে, কারণ সেই সময়ে ওই interface-এ কোনো traffic ছিল না। দ্বিতীয় সারণির শীর্ষে 3 10.0.12.30 -> 10.0.21.5:5432: একটি app server বারবার database-এ ঢুকতে গিয়ে আটকাচ্ছে, যা সম্ভবত security group-এর নিয়ম। 198.51.100.7-এর :22 আর :3389 ইন্টারনেট থেকে আসা সাধারণ port খোঁজা, ঠিকভাবেই আটকেছে।
তৃতীয় সারণিটি সবচেয়ে মজার: 203.0.113.80:443 -> 10.0.11.20:49152 pkts=5. যাওয়ার packet ACCEPT, কিন্তু উত্তর REJECT. Stateful security group ফিরতি traffic নিজে থেকেই ছাড়ে। তাই সন্দেহ যায় stateless network ACL-এর দিকে, যেখানে high port-এ ফেরার অনুমতি নেই। পর্ব ২৭-এ এটি বিস্তারিত দেখবেন।
Flow log পড়ার তিনটি সতর্কতা। এক, ACCEPT মানে firewall আটকায়নি, packet গন্তব্যে পৌঁছেছে এমন নয়। Route না থাকলে log-এ ACCEPT দেখেও সংযোগ না হতে পারে। দুই, রেকর্ড আসে কয়েক মিনিট দেরিতে আর কিছু traffic থাকে না, যেমন DNS বা metadata-র কিছু অংশ, provider-ভেদে। তিন, log রাখারও খরচ আছে। আর ব্যস্ত VPC-তে পুরো flow log সবসময় চালু রাখার আগে হিসাব করে নিন।
প্রমাণের চারটি স্তর
| হাতিয়ার | কী বলে | কী বলে না |
|---|---|---|
| Route table পড়া | Configuration-এ কী লেখা আছে | Packet আসলে গেল কি না |
| Reachability tool | Configuration ধরে দুই বিন্দুর পথ, আর প্রথম বাধা | OS-এর firewall, app শুনছে কি না |
| Flow log | Interface-এ আসলে কী গেল, firewall-এর সিদ্ধান্ত | ডেটার ভেতরের কথা, তাৎক্ষণিক ছবি |
Packet capture (tcpdump) | এই interface-এর আসল packet, flag সহ | VM-এর বাইরে কী ঘটল |
তিন provider-এ একই ধারণা
| ধারণা | AWS | Azure | Google Cloud |
|---|---|---|---|
| Route | Route table, subnet-ভিত্তিক | System route + route table (UDR) | VPC-স্তরের route |
| ইন্টারনেটের পথ | Internet gateway | System route-এর Internet target | Default internet gateway (next hop) |
| Managed NAT | NAT gateway | NAT Gateway | Cloud NAT |
| Storage-এর ভেতরের পথ | Gateway endpoint | Service endpoint, Private Endpoint | Private Google Access |
| Flow রেকর্ড | VPC Flow Logs | VNet flow logs | VPC Flow Logs |
| পথ বিশ্লেষণ | Reachability Analyzer | Network Watcher | Connectivity Tests |
নামগুলো লেখার সময়ের, আর আচরণে সূক্ষ্ম পার্থক্য আছে। এসব tool কিছু ক্ষেত্রে বিশ্লেষণ-প্রতি টাকা নিতে পারে।
আরও গভীরে: VPC-র route table কোনো একটি router-এ থাকে না। প্রতিটি host-এর virtual switch বা network card প্রয়োজনীয় route আর ঠিকানার মানচিত্র জেনে নেয়, আর packet-কে encapsulate করে সরাসরি গন্তব্য host-এ পাঠায়। এই চিন্তার প্রকাশিত উদাহরণ Google-এর Andromeda (NSDI ২০১৮)। CIDR-এর নিয়ম RFC 4632 (২০০৬)-এ, আর NAT-এর আচরণ RFC 3022 (২০০১)-এ আছে। পুরো ভিত্তিটি SDN পর্বে পাবেন।
পরীক্ষা ও ইন্টারভিউতে:
- Public আর private subnet-এর পার্থক্য? Route table-এ IGW-র route আছে কি না। অন্য কিছু নয়।
- NAT gateway কোন subnet-এ বসে? Public subnet-এ, কারণ তার নিজের ইন্টারনেট পথ লাগে।
10.1.5.9-এর জন্য/16আর/24দুটোই মিললে?/24জেতে, longest-prefix match.- IGW আর NAT-এর অনুবাদের পার্থক্য? IGW 1:1, দুই দিকে শুরু হতে পারে। NAT অনেকে-থেকে-একে, শুধু ভেতর থেকে শুরু।
- NAT-এর বিল কমাবেন কীভাবে? Flow log দেখে বড় গন্তব্য খুঁজে storage endpoint বসান।
১০ · AI-এর যুগে routing যাচাই
AI কয়েক সেকেন্ডে পুরো VPC-র Terraform লিখে দিতে পারে। চলতেও পারে। কিন্তু routing-এর ভুল প্রায়ই সাথে সাথে ধরা পড়ে না: database public হয়ে যায়, অথবা NAT-এর বিল মাস শেষে চমকে দেয়। Terraform-এর বিস্তারিত পর্ব ৫২-তে আসবে। আপাতত নিচের AWS-ধাঁচের ছোট অংশটি পড়তে পারাই লক্ষ্য। এখানে একটি AZ-এর private subnet-এর পথ বাঁধা হয়েছে।
resource "aws_nat_gateway" "a" {
allocation_id = aws_eip.nat_a.id
subnet_id = aws_subnet.public_a.id # public subnet, not private
depends_on = [aws_internet_gateway.main]
}
resource "aws_route_table" "private_a" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.a.id # NAT in the same AZ
}
}
resource "aws_route_table_association" "private_a" {
subnet_id = aws_subnet.private_a.id
route_table_id = aws_route_table.private_a.id
}AI সাধারণত যেসব ভুল করে
| AI-এর ভুল | বিপদ | কী দেখবেন |
|---|---|---|
Private subnet-এর table-এ 0.0.0.0/0 → igw | Private আর private থাকে না | প্রতিটি table-এর target |
| সব subnet-এ public IP auto-assign চালু | Database সরাসরি ইন্টারনেটে যেতে পারে | Subnet-এর setting |
| NAT private subnet-এ, বা একটিই NAT | পথ নেই, বা AZ-এর ঝুঁকি | subnet_id আর NAT-এর সংখ্যা |
| Storage endpoint বাদ, খরচের কথা নেই | মাসের শেষে বড় বিল | Traffic-এর হিসাব, budget alert |
Firewall-এ 0.0.0.0/0 খোলা “চালু করার জন্য” | আসল সমস্যা ঢাকা পড়ে, ঝুঁকি বাড়ে | আগে route, পরে নিয়ম |
| নেই এমন attribute বা ভুল flag | Plan ব্যর্থ, বা অন্য কিছু ঘটে | Provider-এর নথি |
| পুরোনো NAT আগে মুছতে বলা | চলতি outbound কেটে যায় | ক্রম: নতুন বানানো, বদল, যাচাই, মোছা |
সমস্যায় পড়লে AI-কে পুরো তথ্য দিন, কিন্তু আসল account id বা কোনো secret নয়। শেষ অনুরোধটি খেয়াল করুন: সে কারণটি প্রমাণসহ বলবে, শুধু সমাধান নয়।
AI-এর লেখা network config হাতে পেলে
নিজে হাতে পরীক্ষা ঐচ্ছিক, এই পর্বের জন্য account লাগবে না। করতে চাইলে মনে রাখুন, NAT gateway কোনো traffic ছাড়াও ঘণ্টা ধরে টাকা নেয়, আর public IP আর flow log-এরও খরচ থাকতে পারে। শেষে পরিষ্কার করুন: NAT মুছুন, তার public IP ছেড়ে দিন, flow log আর তার log জমার জায়গা মুছুন, তারপর VPC মুছুন। আর আগে থেকে পর্ব ৬-এর মতো budget alert বসান।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।
প্র ০১NAT gateway নিয়ে cloud-এর দলগুলোর এত অভিযোগ কেন? এটি কি সত্যিই অন্যায্য দাম, নাকি নকশার ভুল?
দুটোরই কিছুটা। ২০১৫ সালে AWS managed NAT gateway আনার আগে দলগুলো নিজের NAT instance চালাত। সেটি ছিল একটি VM: patch দিতে হতো, পড়ে গেলে failover বানাতে হতো, আর গতি আটকে থাকত VM-এর আকারে। Managed NAT এই ঝামেলা সরিয়ে দিল। বিনিময়ে এলো ঘণ্টার ফি আর প্রতি GB-র processing ফি।
ঘণ্টার ফি নিয়ে অভিযোগ কম। সমস্যা প্রতি GB-র ফি। কারণ এর বৃদ্ধি চোখে পড়ে না। একটি Kubernetes cluster বারবার বড় image টানে, একটি log agent সব কিছু বাইরের সার্ভিসে পাঠায়, একটি backup job রাতভর একই region-এর bucket-এ লেখে। কোডে এর কোনো চিহ্ন নেই। আর এই ফি egress-এর ওপরে বসে, তাই একটি GB-র জন্য দুবার টাকা দেওয়ার অনুভূতি হয়।
কিন্তু পুরোটা provider-এর দোষ নয়। বহু ক্ষেত্রে নকশাই ভুল: যে traffic-এর NAT দিয়ে যাওয়ারই কথা নয়, তা যাচ্ছে। Storage endpoint, একই region-এর registry, VPC-র ভেতরের পথ দিয়ে এর বড় অংশ সরে যায়। অংশ ৬-এর অনুমিত হিসাবে একটি route-এই $450 কমেছে।
আরেকটি প্রশ্ন, NAT instance-এ ফিরে যাওয়া কি যুক্তিসঙ্গত? অনুমিত দরে, NAT gateway-র processing $০.০৫ হলে ২,০০০ GB-তে $১০০। একটি ছোট VM-এর ভাড়া হয়তো এর চেয়ে কম। কিন্তু হিসাবে মানুষের সময় যোগ করুন: patch, পর্যবেক্ষণ, রাত ৩টার failover. ছোট dev পরিবেশে এটি লাভজনক হতে পারে, production-এ অনেক সময় নয়। কিছু দল ঠিক এই হিসাব থেকে নিজের NAT চালায়, অনেকে চালায় না।
মূল উপলব্ধি: Cloud-এর খরচ প্রায়ই নকশার প্রতিবিম্ব। বিল দেখে দর নিয়ে ক্ষোভের আগে জিজ্ঞেস করুন, এই ডেটা এই পথে যাচ্ছে কেন? আর মাপুন আগে, কাটুন পরে।
প্র ০২IPv6-এ ঠিকানার অভাব নেই। তাহলে কি NAT মরে যাবে? NAT-এর “নিরাপত্তা” না থাকলে কী হবে?
NAT জন্মেছিল ঠিকানার অভাব থেকে। ১৯৯৪ সালের RFC 1631 এটিকে স্বল্পমেয়াদি সমাধান হিসেবে দেখেছিল। সেই সাময়িক ব্যবস্থাই কয়েক দশক ধরে ইন্টারনেটের অংশ হয়ে গেল। IPv6-এর ১২৮ bit ঠিকানায় প্রতিটি যন্ত্র বিশ্বজুড়ে অনন্য ঠিকানা পেতে পারে, তাই তত্ত্বে NAT-এর দরকার নেই।
কিন্তু মানুষ ভেবেছিল NAT নিরাপত্তাও দেয়। IETF এই প্রশ্নে সরাসরি উত্তর দেয় RFC 4864 (২০০৭)-এ: NAT থেকে পাওয়া সুবিধাগুলো অনুবাদ ছাড়াই পাওয়া যায়। আসল সুরক্ষা আসে stateful firewall থেকে, যে শুধু ভেতর থেকে শুরু হওয়া সংযোগের উত্তর ঢুকতে দেয়। ঠিক এই আচরণই AWS-এর egress-only internet gateway দেয়: ঠিকানা বদলায় না, তবু বাইরে থেকে শুরু হওয়া সংযোগ ঢোকে না।
তাহলে NAT শেষ হচ্ছে না কেন? কারণ পৃথিবী এখনো মিশ্র। বহু বাইরের সার্ভিস শুধু IPv4-এ চলে। তাই dual-stack VPC-তে IPv4-এর জন্য NAT থেকেই যায়। শুধু-IPv6 নেটওয়ার্কের জন্য NAT64 (RFC 6146) আর DNS64 (RFC 6147), দুটোই ২০১১ সালের, IPv4 গন্তব্যে পৌঁছানোর পথ দেয়। অর্থাৎ NAT রূপ বদলে টিকে আছে।
অর্থনীতিও এখন ভূমিকা রাখছে। AWS ২০২৪ সাল থেকে public IPv4 ঠিকানার জন্য ঘণ্টাপ্রতি ফি নেয়, যা আগে চলমান instance-এ সাধারণত আলাদা ছিল না। এটি দুর্লভ সম্পদের দাম দেখিয়ে দিল। ফলে দলগুলো হিসাব করছে, কোন সার্ভিসে সত্যিই public IPv4 লাগে।
একটি সূক্ষ্ম কথা: IPv6-এ ভুল করার জায়গা অন্য রকম। IPv4-এ private server বাইরে থেকে পৌঁছানো যেত না ঠিকানার কারণেই। IPv6-এ ঠিকানা বিশ্বব্যাপী, তাই একটি ভুল route বা firewall নিয়মের পর সেটি সরাসরি পৌঁছানো যেতে পারে। সুরক্ষাটি তখন শুধু আপনার নিয়মের ওপর নির্ভর করে।
মূল উপলব্ধি: ঠিকানা-অনুবাদ আর নিরাপত্তা দুটি আলাদা ধারণা, যা IPv4-এর যুগে একসাথে জড়িয়ে গিয়েছিল। ভালো নকশায় দুটিকে আলাদা করে ভাবতে হয়।
প্র ০৩Cloud-এর route table VM-এর ভেতর থেকে দেখা যায় না, আর traceroute-এও NAT বা IGW প্রায়ই ধরা পড়ে না। কেন?
কারণ VPC একটি কল্পিত network, বা overlay. আসল data center-এর network-এর ওপরে এটি software দিয়ে তৈরি। আপনার VM ভাবে সে একটি সাধারণ LAN-এ আছে, যেখানে 10.0.11.1-এ একটি router বসে। বাস্তবে সেখানে কোনো আলাদা বাক্স নেই। Host-এর virtual switch বা বিশেষ network card আপনার packet ধরে, route আর ঠিকানার মানচিত্র দেখে, তাকে আরেকটি packet-এর ভেতরে ভরে (encapsulation) সরাসরি অন্য host-এ পাঠায়।
এই নকশার প্রকাশিত বিবরণ আছে Google-এর Andromeda পেপারে (NSDI ২০১৮)। ধারণার মূল পাওয়া যায় Microsoft-এর VL2 (SIGCOMM ২০০৯)-এ, যেখানে ঠিকানা আর আসল অবস্থান আলাদা করার কথা ছিল। AWS-ও নিজের network-এর ধারণা বিভিন্ন বক্তৃতায় ব্যাখ্যা করেছে, যদিও সব বিবরণ প্রকাশিত নয়।
এর ফলগুলো বাস্তব। প্রথমত, route table VM-এর OS-এ নেই, আছে provider-এর control plane-এ, আর সেখান থেকে data plane-এ ছড়ায়। তাই route দেখতে হয় API দিয়ে। দ্বিতীয়ত, overlay-র ভেতরের হপগুলো সাধারণ router-এর মতো TTL কমিয়ে উত্তর না-ও দিতে পারে। ফলে traceroute-এ অনেক সময় তারকাচিহ্ন দেখা যায়, বা মাঝের হপ দেখাই যায় না। “Traceroute-এ NAT দেখা যাচ্ছে না” মানে NAT নেই, এমন নয়।
তৃতীয়ত, VM-এর ভেতরে tcpdump শুধু VM-এর interface দেখায়। সেখান থেকে packet বের হয়ে গেলে আপনি অন্ধ। তাই provider-রা flow log, traffic mirroring আর reachability tool দেন। এগুলো সেই কল্পিত network-এর জানালা। অন-প্রিমাইজে যে ইঞ্জিনিয়ার router-এ লগইন করে দেখতেন, cloud-এ তিনি API আর log দিয়ে দেখেন।
মূল উপলব্ধি: Cloud-এর network-কে পুরোনো যন্ত্রের মতো “ভেতরে ঢুকে” দেখা যায় না। প্রতিটি হাতিয়ার কোন স্তর দেখে, তা জানাই এখানে আসল দক্ষতা।
প্র ০৪এক AZ-এর NAT পড়ে গেলে একটি script দিয়ে route অন্য NAT-এ সরিয়ে দিলেই তো হয়। প্রতি AZ-এ NAT রাখা কি বাড়তি খরচ নয়?
Script-এর ধারণা যুক্তিসঙ্গত শোনায়, আর আগে NAT instance-এর দিনে মানুষ ঠিক এটিই করতেন। কিন্তু এর ভেতরে একটি সূক্ষ্ম ঝুঁকি আছে, যা static stability ধারণা দিয়ে বোঝা যায়। Amazon Builders' Library-র “Static stability using Availability Zones” লেখাটি এই চিন্তাকে পরিষ্কার করে: কোনো AZ পড়ে গেলে সুস্থ অংশগুলোর যেন নতুন কিছু করতে না হয়।
Script-ভিত্তিক failover-কে কী কী করতে হয়? সমস্যা ধরতে হবে, যা নিজেই একটি পর্যবেক্ষণ ব্যবস্থার ওপর নির্ভরশীল। তারপর route table বদলের API ডাকতে হবে। অর্থাৎ control plane-কে সুস্থ থাকতে হবে, ঠিক সেই মুহূর্তে, যখন একটি AZ-এ বড় ঘটনা চলছে। এমন সময়ে API-র চাপ বেশি থাকা স্বাভাবিক, কারণ সবাই একসাথে একই কাজ করতে চাইছে। পর্ব ৫-এ দেখেছেন, data plane সাধারণত control plane-এর চেয়ে বেশি নির্ভরযোগ্য।
প্রতি AZ-এ NAT থাকলে কিছুই করতে হয় না। AZ-b-র server আগের মতোই AZ-b-র NAT দিয়ে যায়। এই পথ আগে থেকেই চালু আর পরীক্ষিত। ব্যর্থতার মুহূর্তে কোনো পরিবর্তন লাগে না।
খরচের দিক থেকেও “বাড়তি” কথাটি পুরো সত্য নয়। অংশ ৬-এর অনুমিত হিসাবে একটি NAT রাখলে ঘণ্টার $36 বাঁচে, কিন্তু AZ-পারের traffic-এ $30 থেকে $120 খরচ হয়। Traffic বেশি হলে দুই NAT উল্টো সস্তাও হতে পারে। আর যে পরিবেশে outbound কয়েক ঘণ্টা বন্ধ থাকলে ক্ষতি নেই, যেমন dev, সেখানে একটি NAT রাখা পুরোপুরি যুক্তিসঙ্গত সিদ্ধান্ত।
আরেকটি প্রশ্ন, আপনার সিস্টেম কি আদৌ outbound-নির্ভর? App-এর সব কাজ VPC-র ভেতরের database-এই সীমিত হলে NAT-এর সমস্যায় চলতি সেবা ভাঙার সম্ভাবনা কম। বাইরের payment API ডাকতে হলে অবশ্য ভাঙবে।
মূল উপলব্ধি: Failover script হলো ব্যর্থতার সময়ে নতুন কিছু করার পরিকল্পনা। ভালো নকশা চেষ্টা করে এমন অবস্থা তৈরি করতে, যেখানে ব্যর্থতার সময়ে কিছুই করতে হয় না। দামটি পরিবেশ দেখে ঠিক করুন, সব জায়গায় একই নিয়মে নয়।
প্র ০৫ইন্টারনেট নিজেই asymmetric পথে চলে, তবু কাজ করে। তাহলে cloud-এর ভেতরে asymmetric path এত সমস্যা করে কেন?
ইন্টারনেটে যাওয়া আর আসার পথ আলাদা হওয়া খুবই স্বাভাবিক। প্রতিটি নেটওয়ার্ক BGP দিয়ে নিজের নীতি অনুযায়ী পথ বেছে নেয়। অনেকে “hot potato” ধরনের নীতি মানে: packet যত তাড়াতাড়ি সম্ভব অন্যের network-এ পাঠিয়ে দেয়। ফলে দুই দিকের পথ আলাদা হয়। এতে কিছু ভাঙে না, কারণ মাঝের router-গুলো stateless: প্রতিটি packet নিজের গন্তব্য দেখে এগিয়ে যায়, কোনো সংযোগ মনে রাখে না। ইন্টারনেটের নকশার মূল চিন্তা ছিল, বুদ্ধি থাকবে দুই প্রান্তে, মাঝখানে নয়।
সমস্যা শুরু হয় যখন মাঝখানে কোনো যন্ত্র সংযোগ মনে রাখে। NAT-এর খাতা, stateful firewall-এর connection table, এগুলো থাকে নির্দিষ্ট একটি যন্ত্রে। যাওয়ার packet firewall A-তে সারি তৈরি করল, আর উত্তর এলো firewall B-তে। B-র কাছে এটি কোনো শুরু না হওয়া সংযোগের মাঝখানের packet, তাই বাদ।
Cloud-এ এই ঝুঁকি বেশি, কারণ route একটি সারি বদলেই বদলানো যায়। সাথে থাকে একাধিক AZ, একাধিক NAT, inspection-এর জন্য firewall appliance. আর ভুলটি অদ্ভুতভাবে দেখা দেয়: কিছু সংযোগ চলে, কিছু চলে না, flow hash-এর ওপর নির্ভর করে।
সমাধান এসেছে কয়েক দিক থেকে। প্রথমত, পথ ইচ্ছে করে সমান রাখা: প্রতি AZ-এ আলাদা table আর একই AZ-এর firewall. দ্বিতীয়ত, AWS-এর Gateway Load Balancer (২০২০) একটি flow-কে একই appliance-এ রাখে, আর GENEVE (RFC 8926, ২০২০) দিয়ে packet মুড়ে পাঠায়। Transit-এর ক্ষেত্রেও “appliance mode” ধরনের setting আছে, যা দুই দিকের পথ একই AZ-এ রাখে। তৃতীয়ত, Linux-এ reverse-path filtering (RFC 3704-এর ধারণা) দুটি interface-এর VM-এ এমন packet ফেলে দিতে পারে, তাই policy routing লাগতে পারে।
মূল উপলব্ধি: প্রশ্নটি “পথ সমান কি না” নয়। প্রশ্ন হলো, “পথে কোনো যন্ত্র কিছু মনে রাখছে কি না।” যেখানেই state, সেখানেই দুই দিকের পথ একই যন্ত্র দিয়ে যেতে হবে।
অনুশীলন
হিসাব, নকশা-সমালোচনা, ফল অনুমান আর একটি কমান্ড। কোনোটির জন্যই cloud account লাগবে না।
-
খরচের হিসাব: একটি সিস্টেমে ৩টি NAT gateway, মাসে ১৫,০০০ GB NAT দিয়ে যায়, যার ১১,০০০ GB একই region-এর object storage-এর। অনুমিত দর: ঘণ্টায় $০.০৪, প্রতি GB processing $০.০৪, মাস ৭২০ ঘণ্টা। Egress বাদ দিয়ে NAT-এর মাসিক খরচ কত? Gateway endpoint-এর পর কত?
ঘণ্টা: 3 × 0.04 × 720 = $86.40. আগে processing: 15,000 × 0.04 = $600, মোট $686.40.
Endpoint-এর পর NAT দিয়ে যায় 15,000 − 11,000 = 4,000 GB. Processing: 4,000 × 0.04 = $160, মোট $246.40. সাশ্রয় $440, প্রায় ৬৪%. ঘণ্টার ফি একই থাকে, কারণ NAT-এর সংখ্যা বদলায়নি।
-
নকশা সমালোচনা: একটি দলের VPC-তে তিন AZ. একটিই NAT, AZ-a-র public subnet-এ। সব private subnet একটি table ব্যবহার করে। Database subnet-ও সেই table-এ, আর সব subnet-এ public IP auto-assign চালু। কী কী সমস্যা, আর আপনি কী বদলাবেন?
- NAT-এর ঝুঁকি: AZ-a পড়লে তিন AZ-এরই outbound যায়। Production হলে প্রতি AZ-এ NAT, আর প্রতি AZ-এ আলাদা table.
- AZ-পারের খরচ: AZ-b আর AZ-c-র সব outbound AZ পার হচ্ছে।
- Public IP: Private subnet-এ public IP-র দরকার নেই, আর ফিরতি পথ NAT-এ থাকায় তা asymmetric সমস্যাও তৈরি করতে পারে। Auto-assign বন্ধ করুন।
- Database: আলাদা table দিন, সেখানে default route না থাকাই ভালো। Patch দরকার হলে managed database-এ provider সামলান। পর্ব ২২ দেখুন।
- Endpoint: Storage-এর traffic আছে কি না মেপে gateway endpoint যোগ করুন।
-
ফল অনুমান করুন: VPC-তে main table-এ শুধু
local. Subnet A যুক্তrtb-pub-এ (0.0.0.0/0 → igw), Subnet C যুক্তrtb-prv-এ (0.0.0.0/0 → nat), Subnet B কোনো table-এ যুক্ত নয়। এবার একজন ভুলে এই কমান্ডটি চালালেন:aws ec2 create-route --route-table-id rtb-main --destination-cidr-block 0.0.0.0/0 --gateway-id igw-0aaa. প্রতিটি subnet-এর অবস্থা এখন কী?A: আগের মতোই public. C: আগের মতোই private, কারণ তার নিজের table আছে। B: কেউ কিছু বদলাননি, অথচ সে এখন public, কারণ main table-ই তার table, আর সেখানে IGW-র route এসেছে। B-র কোনো instance-এ public IP থাকলে সে ইন্টারনেটের সাথে সরাসরি যুক্ত হয়ে গেল, firewall যতটুকু দেয় ততটুকু ছাড়া।
এজন্যই ভালো অভ্যাস হলো main table-কে শুধু
localসহ ফাঁকা রাখা, আর প্রতিটি subnet-কে স্পষ্টভাবে একটি table-এ যুক্ত করা। -
কমান্ড লিখুন:
flow_rejects.sh-এর log-এ প্রতিটি destination ঠিকানার জন্যREJECTহওয়া মোট byte বের করে বড় থেকে ছোট সাজান। এটি block-এর শেষে যোগ করে চালান। সবচেয়ে ওপরে কী আসবে?awk 'NR>1 && $13=="REJECT" {b[$5]+=$10} END {for (d in b) print b[d], d}' "$log" | sort -nrআউটপুট হবে
6240 10.0.11.20, তারপর540 10.0.21.5, তারপর120 10.0.1.25. প্রথমটি 3120 + 3120, অর্থাৎ বাইরের server-এর আটকে যাওয়া উত্তর। Byte-এর হিসাব দেখায় সবচেয়ে বেশি ডেটা ঠিক কোথায় আটকাচ্ছে, যা সারি গুনে বোঝা যায় না।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমPrivate instance থেকে ইন্টারনেটে যাওয়া packet-এর ধাপগুলো সাজান (▲▼ চেপে সরান)
- Instance নিজের private ঠিকানা source রেখে packet পাঠায়
- Private subnet-এর table-এর default route packet-কে NAT-এ নেয়
- NAT source বদলে নিজের ঠিকানা আর port বসায়, খাতায় লেখে
- Public subnet-এর table packet-কে IGW-তে নেয়
- IGW private ঠিকানাকে public ঠিকানায় অনুবাদ করে ইন্টারনেটে পাঠায়
একটি route table-এ আছে: 0.0.0.0/0 → nat, 10.0.0.0/16 → local, 10.0.4.0/22 → fw, 10.0.5.0/24 → vpn. 10.0.6.9-এর packet কোথায় যাবে?
- nat
- local
- fw
- vpn
Cloud VPC-তে কোন বৈশিষ্ট্যটি একটি subnet-কে “public” বানায়?
- Subnet-এর নামে public লেখা থাকা
- তার route table-এ internet gateway-র দিকে route থাকা
- তার route table-এ NAT gateway-র দিকে route থাকা
- তার ভেতরের একটি instance-এ public IP থাকা
Private instance 10.0.11.20 একটি NAT gateway-র পেছনে আছে, যার public ঠিকানা 203.0.113.10. ইন্টারনেটের server-এর log-এ source হিসেবে কোন ঠিকানা উঠবে?
- 10.0.11.20
- 10.0.11.1
- NAT-এর private ঠিকানা
- 203.0.113.10
দুই AZ-এ server আছে, কিন্তু একটিই NAT gateway, AZ-a-তে। AZ-a পুরো বিকল হলে AZ-b-র server-এর কী হবে?
- VPC-র ভেতরে চলবে, কিন্তু ইন্টারনেটে যাওয়া বন্ধ হবে
- স্বয়ংক্রিয়ভাবে অন্য NAT-এ চলে যাবে
- VPC-র ভেতরেও কোনো কথা বলতে পারবে না
- সরাসরি internet gateway দিয়ে যেতে শুরু করবে
একই region-এর object storage-এ মাসে বহু TB ডেটা NAT gateway দিয়ে যাচ্ছে। Default route না সরিয়ে খরচ কমানোর সবচেয়ে সরাসরি উপায় কোনটি?
- আরও NAT gateway যোগ করা
- সব instance-কে public subnet-এ সরানো
- Storage-এর জন্য gateway endpoint যোগ করা
- Flow log চালু করা
Flow log-এ দেখা গেল, 10.0.11.20 থেকে 203.0.113.80:443-এ যাওয়া সারি ACCEPT, কিন্তু 203.0.113.80:443 থেকে 10.0.11.20:49152-এ ফেরা সারি REJECT. সবচেয়ে সম্ভাব্য কারণ কী?
- Route table-এ default route নেই
- Stateless network ACL-এ high port-এ ফেরার অনুমতি নেই
- DNS কাজ করছে না
- Destination server বন্ধ
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- প্রতিটি subnet একটি route table-এ যুক্ত, আর সংযোগ না থাকলে main table-এ পড়ে।
- একাধিক route মিললে সবচেয়ে লম্বা prefix জেতে, ক্রম নয়।
- Public subnet মানে table-এ IGW-র route. Instance-এর public IP-র অনুবাদ করে IGW, 1:1.
- NAT gateway public subnet-এ বসে, প্রতি AZ-এ একটি। প্রতি GB-র বিল দেখুন, storage-এ endpoint দিন।
- সমস্যায় packet-এর পথ ধরে এগোন: OS, subnet-এর table, NAT, তার table, IGW. Flow log-এর ACCEPT মানে পৌঁছানো নয়।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ২৭ · Security group আর network ACL — stateful বনাম stateless firewallপরবর্তী পর্বRoute ঠিক থাকলেও packet আটকে যেতে পারে: দুই স্তরের firewall আর তাদের নিয়ম।
- ক্লাউড কম্পিউটিং ও DevOps · কোর্স হোম৮১টি পর্বপুরো কোর্সের রোডম্যাপ। পরের পর্ব ২৭ · Security group আর network ACL.
- Computer Networks · NAT আর PATতত্ত্বPort অনুবাদের খাতা, NAT-এর ধরন আর CGNAT.
- Computer Networks · Routing-এর ভিত্তিগভীরে যানRouter কীভাবে সিদ্ধান্ত নেয়, forwarding table আর longest-prefix match.
- Computer Networks · Cloud আর container নেটওয়ার্কিংপাশের ট্র্যাকVPC থেকে Docker আর Kubernetes-এর network পর্যন্ত।