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

CDN, WAF আর DDoS সুরক্ষা — certificate আর edge-এর কাজ

CDN, WAF and DDoS Protection — Certificates and the Work of the Edge

Taught in Bangla, this lesson shows what the edge does: CDN distributions, origins, behaviours and cache keys, hit ratio maths for origin load and monthly bills, Cache-Control, versioned files and invalidation, protecting the origin and keeping managed certificates renewing, moving WAF rules from count to block, token bucket rate limits, three layers of DDoS and attack-time costs, plus edge functions and logs, with a bill simulator and worked examples.

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

  • CDN সাজানো: distribution, origin, behaviour আর cache key
  • Hit ratio থেকে origin-এর ভার আর মাসের বিল হিসাব করা
  • Cache-Control, versioned file আর invalidation দিয়ে নিরাপদে নতুন CSS ছাড়া
  • Origin রক্ষা করা আর managed certificate-এর নবায়ন সচল রাখা
  • WAF rule count থেকে block-এ নেওয়া, token bucket-এ rate limit করা
  • DDoS-এর তিন স্তর, কে কোনটি সামলায়, আক্রমণের সময় autoscaling-এর খরচ, edge function আর log

১ · Edge কী — আপনার server-এর সামনের প্রথম দরজা

একটি কাল্পনিক অনলাইন বাজার অ্যাপ ধরুন। নাম দিই “বাজারঘর”। Server আছে একটি region-এ, আর ক্রেতা সারা দেশে। ঈদের আগে রাত ১২টায় ছাড় শুরু হবে। আগের অভিজ্ঞতা বলে তিনটি ঝামেলা হয়। পাতা ধীর হয়। Server একই ব্যানার ছবি লাখবার পাঠাতে গিয়ে হাঁপিয়ে ওঠে। আর কিছু script লগইন পাতায় অনবরত অনুরোধ পাঠায়।

তিনটি সমস্যার সমাধান এক জায়গায় বসে। সেই জায়গার নাম edge. এটি ব্যবহারকারীর কাছাকাছি provider-এর ছোট ঘাঁটি। পর্ব ৫-এ (Cloud-এর ভৌগোলিক কাঠামো) এর পরিচয় পেয়েছেন। এই পর্বে দেখবেন, সেখানে আসলে কী কী কাজ হয়, আর সেই কাজ কে সাজায়।

লঞ্চঘাটের কথা ভাবুন। ঘাটের গেটেই টিকিট দেখা হয় (TLS আর WAF). সন্দেহজনক মালপত্র গেটেই আটকায়। একসাথে অনেক মানুষ এলে গেটে লাইন করানো হয় (rate limit). আর পাশের দোকানে জনপ্রিয় জিনিস আগে থেকেই থাকে, তাই কাউকে সদরঘাটের গুদাম পর্যন্ত যেতে হয় না (cache). গুদামটি আপনার origin: যেখানে আসল জিনিস থাকে।

CDN-এর তত্ত্ব এই সাইটে আগেই আছে। কেন CDN, Zipf জনপ্রিয়তা আর push বনাম pull পাবেন System Design-এর CDN আর edge পর্বে। HTTP caching-এর নিয়ম, ETag আর 304 পাবেন Computer Networks-এর Web caching আর CDN পর্বে। এখানে আমরা অপারেশনের দিক দেখব: কীভাবে সাজাবেন, চালাবেন, রক্ষা করবেন আর বিল মেলাবেন।

একটি অনুরোধের পথ

User → Edge (TLS, WAF, cache) → Origin shield → Origin

User থেকে edge, origin shield হয়ে origin পর্যন্ত অনুরোধের পথ ব্যবহারকারী DNS · HTTPS Edge · ব্যবহারকারীর কাছে TLS শেষ · managed certificate WAF · rate limit Cache BLOCK: 403 / 429 HIT: এখানেই উত্তর বেশিরভাগ অনুরোধ এখানেই শেষ হওয়ার কথা MISS · নতুন HTTPS Origin shield সব edge-এর miss এক জায়গায় জমে MISS · গোপন header Origin · আপনার region Load balancer তারপর app Private bucket public access বন্ধ Firewall: শুধু CDN ঢুকতে পারে
ছবি ৩০.১ — অনুরোধ যত আগে শেষ হয়, আপনার server তত কম খাটে। ওপরে আটকানোই লক্ষ্য।

ছবিতে ক্রমটি খেয়াল করুন। TLS প্রথমে শেষ হয়, তাই WAF অনুরোধের ভেতরটা পড়তে পারে। অনেক CDN-এ WAF cache-এর আগে বসে, তবে ক্রম provider-ভেদে আলাদা হতে পারে। তাই আপনার provider-এর docs মিলিয়ে নিন।

২ · CDN সাজানো — distribution, origin, behaviour আর cache key

CDN চালু করা মানে চারটি প্রশ্নের উত্তর দেওয়া। কোন নামে আসবে? আসল জিনিস কোথায়? কোন পথের সাথে কেমন আচরণ হবে? আর দুটি অনুরোধ “একই” কখন?

Distribution

Distribution হলো পুরো CDN সেটআপের একটি একক। এর একটি নিজস্ব domain থাকে। আপনার shop.example.com DNS-এ এর দিকে দেখায়।

DNS: পর্ব ২৯

Origin

আসল জিনিসের ঠিকানা। একটি distribution-এ একাধিক origin থাকতে পারে: ছবির জন্য bucket, API-র জন্য load balancer.

পর্ব ১৮, পর্ব ২১

Behaviour

Cache behaviour হলো path অনুযায়ী নিয়ম। /assets/* দীর্ঘদিন cache হবে, /api/* হবে না।

পথ ধরে নিয়ম

Cache key

Cache key ঠিক করে দুটি অনুরোধ একই উত্তর পাবে কি না। সাধারণত host আর path, আর আপনি যা যোগ করেন।

Hit ratio-র চাবি

Cache key-ই সবচেয়ে বেশি ভুল হয়। Key-তে বেশি জিনিস রাখলে একই ফাইলের অনেক কপি জমে, hit কমে। কম জিনিস রাখলে এক জনের উত্তর আরেকজন পেতে পারে। এই দ্বিতীয়টি নিরাপত্তার ভুল। নিয়মটি এক লাইনে: উত্তর যা দিয়ে বদলায়, key-তে শুধু তাই থাকবে।

জিনিসKey-তে রাখবেন?কারণ
?utm_source=fbনাTracking-এর জন্য। উত্তর বদলায় না, অথচ প্রতিটি মান আলাদা কপি বানায়
?page=2, ?size=mহ্যাঁ, নাম ধরে allow-list করেউত্তর সত্যিই বদলায়
Session cookieনা, এমন পাতা cache-ই করবেন নাপ্রতিটি ব্যবহারকারীর আলাদা কপি হয়, hit প্রায় শূন্যে নামে
Accept-Encodingসাধারণত CDN নিজে সামলায়gzip আর Brotli কপি আলাদা রাখতে হয়
Accept-Languageদরকার হলে স্বাভাবিক করেকাঁচা মানের হাজারো রূপ আছে, তাই bn আর en-এ নামিয়ে আনুন

নিচে Terraform-এ বাজারঘরের সেটআপের মূল অংশ দেখুন। AWS-এর উদাহরণ, তবে ধারণা তিন provider-এই এক। Terraform পরে শিখবেন (পর্ব ৫২), এখন শুধু গঠন পড়ুন।

# উদাহরণ: চালানোর জন্য নয়। আসল cloud-এ চালালে খরচ হতে পারে।
resource "aws_cloudfront_distribution" "shop" {
  enabled = true
  aliases = ["shop.example.com"]

  origin {                    # static files: private bucket
    origin_id                = "assets"
    domain_name              = "example-bucket.s3.ap-southeast-1.amazonaws.com"
    origin_access_control_id = aws_cloudfront_origin_access_control.assets.id
  }
  origin {                    # API: load balancer
    origin_id   = "api"
    domain_name = "origin.shop.example.com"
    custom_origin_config {
      http_port              = 80
      https_port             = 443
      origin_protocol_policy = "https-only"
      origin_ssl_protocols   = ["TLSv1.2"]
    }
  }

  ordered_cache_behavior {    # hashed files: cache for a long time
    path_pattern           = "/assets/*"
    target_origin_id       = "assets"
    viewer_protocol_policy = "redirect-to-https"
    allowed_methods        = ["GET", "HEAD"]
    cached_methods         = ["GET", "HEAD"]
    cache_policy_id        = var.long_cache_policy_id
  }
  default_cache_behavior {    # everything else: do not cache
    target_origin_id         = "api"
    viewer_protocol_policy   = "redirect-to-https"
    allowed_methods          = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods           = ["GET", "HEAD"]
    cache_policy_id          = var.no_cache_policy_id
    origin_request_policy_id = var.forward_all_policy_id
  }

  restrictions {
    geo_restriction { restriction_type = "none" }
  }
  viewer_certificate {
    acm_certificate_arn      = var.certificate_arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }
}

ordered_cache_behavior-গুলো ক্রমে মেলানো হয়, আর কিছু না মিললে default_cache_behavior. ডিফল্টটি ইচ্ছা করেই “cache করবেন না” রাখা হয়েছে। নতুন কোনো path ভুলে গেলে সেটি ধীর হবে, কিন্তু কারও ব্যক্তিগত তথ্য অন্যের কাছে যাবে না। var. দিয়ে লেখা policy id-গুলো আসলে cache policy-র পরিচয়। Cache key আর TTL সেখানেই লেখা থাকে।

তিন provider-এর নাম

ধারণাAWSAzureGoogle Cloud
CDNCloudFrontFront DoorCloud CDN (Application LB-র সাথে)
Path-এর নিয়মCache behavior, cache policyRoute, rule setURL map, cache mode, cache key policy
CertificateACMFront Door managed certificateGoogle-managed certificate, Certificate Manager
WAFAWS WAFAzure WAFCloud Armor
শুধু লিখে রাখার মোডCount actionDetection modePreview mode
DDoS সুরক্ষাAWS ShieldAzure DDoS ProtectionCloud Armor-এর DDoS সুরক্ষা

নাম আর ভাগ সময়ের সাথে বদলায়, তাই লেখার সময়ের ছবি হিসেবে নিন। Cloudflare, Akamai আর Fastly-র মতো স্বাধীন CDN-ও বহুল ব্যবহৃত, আর এগুলো যেকোনো cloud-এর origin-এর সামনে বসতে পারে।

প্রথম অনুরোধ বনাম দ্বিতীয় অনুরোধ

Edge-এ cache থাকলে উত্তরকে বলে hit, না থাকলে miss. নিচে একই CSS ফাইলের দুটি অনুরোধ দেখুন। সময়গুলো হিসাবের সুবিধার জন্য ধরে নেওয়া: ব্যবহারকারী থেকে edge ১৫ ms, edge থেকে shield ৬০ ms, shield থেকে origin ৪০ ms, origin-এর নিজের কাজ ২৫ ms (প্রতিটিই যাওয়া-আসা মিলিয়ে)।

  1. ব্যবহারকারীGET app.css
  2. Edgecache key
  3. Shieldদ্বিতীয় cache
  4. Origin200 OK
অবস্থা
Edge cache
Shield cache
Origin-এ অনুরোধ
মোট সময়
  1. ধাপ ১ — অনুরোধ রওনা। ফাইলটি এইমাত্র প্রকাশিত, তাই কোনো cache-এ নেই। DNS ব্যবহারকারীকে কাছের edge-এ পাঠায়। TLS সেখানেই শেষ হয়।
  2. ধাপ ২ — Edge দেখে। WAF আপত্তি করেনি। Edge host আর path থেকে cache key বানিয়ে খোঁজে। পায় না। এটি miss.
  3. ধাপ ৩ — Shield দেখে। Edge সরাসরি origin-এ যায় না, আগে shield-কে জিজ্ঞেস করে। সেখানেও নেই। Origin-এ অনুরোধ এখনো ০।
  4. ধাপ ৪ — Origin উত্তর দেয়। এই প্রথম origin খাটল, অনুরোধের সংখ্যা হলো ১। উত্তরের সাথে Cache-Control বলে দিল এক বছর রাখা যাবে।
  5. ধাপ ৫ — ফিরতি পথে জমা। Shield আর edge দুটিই ফাইল রাখে। ব্যবহারকারীর মোট সময় ১৫ + ৬০ + ৪০ + ২৫ = ১৪০ ms.
  6. ধাপ ৬ — দ্বিতীয় অনুরোধ। ১২ সেকেন্ড পরে একই edge-এ আরেকজন এলেন। উত্তর edge থেকেই এলো, সময় ১৫ ms. Origin-এ অনুরোধ তখনো ১। age: 12 মানে কপিটির বয়স ১২ সেকেন্ড।

আপনার সাইটে hit না miss, তা নিজেই দেখতে পারেন। Header-এর নাম CDN-ভেদে আলাদা।

# উদাহরণ: নিজের site-এ চালান। নিচের উত্তর নমুনা, CDN-ভেদে আলাদা হবে।
curl -sI https://shop.example.com/assets/app.3f9a1c.css

HTTP/2 200
content-type: text/css
cache-control: public, max-age=31536000, immutable
age: 12
x-cache: Hit from cloudfront

নমুনা আউটপুট, version-ভেদে আলাদা হতে পারে। age ০-এর বেশি আর x-cache-এ Hit মানে উত্তর cache থেকে এসেছে। অন্য CDN-এ একই তথ্য অন্য নামে আসে, যেমন cf-cache-status: HIT. দু-তিনবার চালান। প্রথমবার Miss, পরে Hit এলে cache কাজ করছে।

৩ · Hit ratio-র অঙ্ক — origin-এর ভার আর মাসের বিল

Cache hit ratio ৯০% শুনতে ভালো লাগে। কিন্তু origin-এর কাছে গুরুত্বপূর্ণ সংখ্যাটি হলো miss. কারণ origin-এর ভার miss-এর সমানুপাতিক:

origin-এর অনুরোধ = মোট অনুরোধ × (1 − h)
h = hit ratio

ধরুন peak-এ সেকেন্ডে ১,০০০ অনুরোধ।

hMissOrigin-এ (req/s)মন্তব্য
৯০%১০%১০০মাঝারি
৯৫%৫%৫০মাত্র ৫ পয়েন্টে ভার অর্ধেক
৯৯%১%১০৯০%-এর দশ ভাগের এক ভাগ

এজন্যই শেষের কয়েক পয়েন্টের দাম এত বেশি। ৫০% থেকে ৫৫% হলে ভার কমে ১০ ভাগের ১ ভাগ। ৯০% থেকে ৯৫% হলে কমে অর্ধেক।

মাসের বিল — একটি সিমুলেটর

নিচের কোডে সব দাম ধরে নেওয়া গোল সংখ্যা। আসল দাম region, আয়তন আর চুক্তিতে বদলায়, তাই provider-এর pricing পাতা দেখে PRICE বদলে আবার চালান। মাস ৩০ দিনের, গড়ে ১০০ req/s, peak ১,০০০ req/s, গড় উত্তর ১০০ KB. Origin-এ অন্তত ২টি server থাকবে, কারণ একটিতে নিরাপত্তা নেই (পর্ব ১৭-এর শিক্ষা)।

// A month of traffic through a CDN. All prices are ASSUMED round numbers.
const RPS_AVG = 100, RPS_PEAK = 1000;       // requests per second
const KB_PER_REQ = 100;                     // average response size
const SEC_MONTH = 30 * 24 * 3600, HOURS = 720;

const PRICE = {
  directEgressGB: 0.09,   // origin straight to users
  cdnEgressGB: 0.06,      // CDN to users
  cdnPerMillion: 1.00,    // CDN request fee
  fillGB: 0.02,           // origin to CDN (set 0 if your provider gives it free)
  serverHour: 0.10,       // one origin server
};
const SERVER_RPS = 250, MIN_SERVERS = 2;

const millions = RPS_AVG * SEC_MONTH / 1e6;
const totalGB = millions * 1e6 * KB_PER_REQ * 1000 / 1e9;
const servers = (peak) => Math.max(MIN_SERVERS, Math.ceil(peak / SERVER_RPS));
const usd = (x) => ('$' + x.toFixed(0)).padStart(7);

console.log(`month: ${millions.toFixed(1)} million requests, ${totalGB} GB`);
const directBill = totalGB * PRICE.directEgressGB + servers(RPS_PEAK) * PRICE.serverHour * HOURS;
console.log(`no CDN: ${servers(RPS_PEAK)} servers, bill ${usd(directBill).trim()}`);
console.log('hit%  originRPS(peak)  servers  originGB   CDN   fill  server   total');

for (const hit of [0, 0.5, 0.8, 0.9, 0.95, 0.99]) {
  const peak = RPS_PEAK * (1 - hit), fillGB = totalGB * (1 - hit), n = servers(peak);
  const cdn = totalGB * PRICE.cdnEgressGB + millions * PRICE.cdnPerMillion;
  const fill = fillGB * PRICE.fillGB, srv = n * PRICE.serverHour * HOURS;
  console.log(`${String(hit * 100).padStart(3)}%  ${peak.toFixed(0).padStart(15)}  ${String(n).padStart(7)}` +
    `  ${fillGB.toFixed(0).padStart(8)} ${usd(cdn)} ${usd(fill).slice(1)} ${usd(srv)} ${usd(cdn + fill + srv)}`);
}

আউটপুটের শুরু:

month: 259.2 million requests, 25920 GB
no CDN: 4 servers, bill $2621
hit%  originRPS(peak)  servers  originGB   CDN   fill  server   total
  0%             1000        4     25920   $1814   $518    $288   $2621
 50%              500        2     12960   $1814   $259    $144   $2218
 90%              100        2      2592   $1814    $52    $144   $2010
 99%               10        2       259   $1814     $5    $144   $1964

৮০% আর ৯৫%-এর সারি এখানে বাদ রাখা হয়েছে। তিনটি জিনিস দেখুন। এক: hit ০% হলে এই ধরে নেওয়া দামে CDN-এর বিল সরাসরি পাঠানোর সমান, লাভ নেই। দুই: ৯০% থেকে ৯৯%-এ origin-এর চাপ ১০০ থেকে ১০-এ নামল, অথচ বিল কমল মাত্র ৪৬ ডলার। কারণ server আগেই ২-এ ঠেকেছে। তিন: এই ধরে নেওয়া দামে CDN-এর আসল লাভ বিলে নয়। লাভ হলো কম latency, origin-এর স্বস্তি আর peak-এ টিকে থাকা। CDN-এর দাম origin-এর egress-এর কাছাকাছি হলে হিসাবও বদলাবে।

দুই রকম hit ratio আছে। অনুরোধ ধরে মাপা hit ratio ৯৯% হতে পারে, অথচ byte ধরে মাপলে ৭০%, যদি বড় ভিডিওগুলো miss হয়। Origin-এর CPU চলে অনুরোধে, bandwidth বিল চলে byte-এ। Dashboard-এ দুটিই দেখুন। পর্ব ৯-এর কায়দায় log থেকে দুটি হিসাব করা দেখবেন অংশ ৯-এ।

Origin shield — miss-কেও এক জায়গায় জমানো

ধরুন ২০টি edge, ৫,০০০টি জনপ্রিয় ফাইল, আর প্রতিটির TTL ১ ঘণ্টা। প্রতিটি edge আলাদাভাবে ফাইল আনলে দিনে origin-এ যায় ৫,০০০ × ২০ × ২৪ = ২৪,০০,০০০ অনুরোধ। মাঝখানে একটি origin shield বসালে সব edge আগে সেখানে আসে। তখন origin-এ যায় ৫,০০০ × ২৪ = ১,২০,০০০ অনুরোধ, অর্থাৎ ২০ ভাগের ১ ভাগ।

Shield আরেকটি কাজ করে। একই ফাইলের অনেক miss একসাথে এলে সে একটিই origin-এ পাঠায়, বাকিরা অপেক্ষা করে। একে বলে request collapsing. পর্ব ২৩-এর cache stampede-এর ওষুধ এটিই।

AWS-এ এর নাম Origin Shield. অন্য CDN-এ tiered cache-এর মতো নামে একই ধারণা পাবেন। Shield-এর নিজের খরচ আছে, আর একটি বাড়তি hop যোগ হয়। ফাইল কম হলে বা ব্যবহারকারী এক অঞ্চলে হলে লাভ কম। Shield সেই region-এ রাখুন যেটি origin-এর সবচেয়ে কাছে।

৪ · Cache-Control আর versioned file — পুরোনো জিনিস ভোলানোর দুই পথ

Cache-এর সবচেয়ে কঠিন প্রশ্ন হলো, জিনিস বদলালে কী হবে? আগে দেখুন, origin কীভাবে নির্দেশ দেয়। Cache-Control header-এর পূর্ণ নিয়ম RFC 9111 (২০২২)-এ আছে। কাজের মানগুলো এই:

মানঅর্থকোথায়
public, max-age=31536000, immutableএক বছর রাখুন, যাচাইও লাগবে নানামে hash-ওয়ালা CSS, JS, ছবি
no-cacheরাখা যাবে, তবে ব্যবহারের আগে origin-কে জিজ্ঞেস করতে হবেHTML
no-storeকোথাও রাখা যাবে নাব্যক্তিগত পাতা, লেনদেন
privateশুধু ব্যবহারকারীর browser রাখবে, CDN নয়লগইন-করা ব্যবহারকারীর পাতা
s-maxage=60CDN-এর মতো shared cache-এর জন্য আলাদা আয়ুজনপ্রিয় API-র উত্তর
stale-while-revalidate=30মেয়াদ ফুরালেও ৩০ সেকেন্ড পুরোনো কপি দিন, পেছনে নতুন আনুনধীর origin-এর সামনে

no-cache নামটি বিভ্রান্তিকর। এর অর্থ “cache করবেন না” নয়, বরং “যাচাই না করে ব্যবহার করবেন না”। সত্যিই রাখতে না চাইলে no-store. আরেকটি কথা: অনেক CDN-এ নিজের নিয়ম header-কে ছাপিয়ে যেতে পারে, যেমন minimum TTL. তাই header আর CDN-এর সেটিং দুটোই দেখুন। stale-while-revalidate-র নিয়ম RFC 5861 (২০১০)-এ, তবে সমর্থন CDN-ভেদে আলাদা।

ফাইল বদলালে পুরোনো কপি সরানোর পথ দুটি।

Invalidation

Invalidation বা purge মানে CDN-কে বলা, “এই path-এর কপি ফেলে দিন।” যেন প্রতিটি দোকানে ফোন করে পুরোনো মাল নামাতে বলা। Browser-এর কপিতে এর কোনো প্রভাব নেই।

HTML, ভুল করে ছাড়া ফাইল

Versioned file name

Hash-সহ নাম মানে app.3f9a1c.css. বিষয়বস্তু বদলালে নামও বদলায়। পুরোনো মাল নামাতে হয় না, নতুন নামের মাল তাকে ওঠে।

CSS, JS, ছবি

প্রতি deploy-এ /* invalidation সবচেয়ে সহজ, আর সবচেয়ে বিপজ্জনক। সব edge একসাথে খালি হয়, অর্থাৎ cold cache. সেকেন্ডে ১,০০০ অনুরোধের সাইটে h ৯৫% থাকলে origin পেত ৫০টি। Purge-এর ঠিক পরে প্রায় ১,০০০টি পেতে পারে, অর্থাৎ ২০ গুণ। তার ওপর অনেক provider নির্দিষ্ট সংখ্যার বেশি invalidation-এ টাকা নেন।

নিচে নিরাপদ পথটি দেখুন। Build tool নতুন CSS বানিয়েছে: app.7d2e40.css. HTML সবসময় ঠিক করে কোন CSS চলবে, তাই HTML-এর আয়ু ছোট, আর CSS-এর আয়ু লম্বা। এখানে ধরে নিচ্ছি HTML-ও bucket থেকে আসে, নিজের একটি behaviour-এ ৬০ সেকেন্ডের TTL নিয়ে।

কোথায় কী আছে
Bucket-এ CSS
Bucket-এর HTML চায়
Edge-এর HTML চায়
নতুন ব্যবহারকারী
আগে থেকে খোলা tab
  1. ধাপ ১ — শুরুর অবস্থা। সবাই পুরোনো 3f9a1c পাচ্ছেন। Build শেষ, নতুন ফাইল তৈরি, কিন্তু কিছুই upload হয়নি।
  2. ধাপ ২ — আগে CSS. নতুন ফাইল bucket-এ ওঠে। কেউ এখনো একে চায় না, তাই ব্যবহারকারীর কিছু বদলায়নি। পুরোনো ফাইল মোছা হয়নি।
  3. ধাপ ৩ — তারপর HTML. Bucket-এর HTML এখন নতুন CSS চায়। কিন্তু edge-এর জমানো পুরোনো HTML-এর আয়ু না ফুরানো পর্যন্ত সেটিই যাবে। ক্ষতি নেই, কারণ পুরোনো CSS-ও আছে।
  4. ধাপ ৪ — শুধু HTML purge. একটিমাত্র path. Purge না করলেও ৬০ সেকেন্ডে এমনিই বদলাত। এবার নতুন ব্যবহারকারী নতুন HTML পান। খোলা tab পুরোনো HTML আর পুরোনো CSS নিয়ে ঠিকই চলে, কারণ দুটোই মিলে আছে।
  5. ধাপ ৫ — নতুন CSS-এর প্রথম অনুরোধ। প্রথম অনুরোধে miss, তারপর hit. একটি ছোট ফাইলের miss, পুরো সাইটের নয়। সমস্যা হলে HTML-কে আগের CSS-এ ফেরালেই rollback.
  6. ধাপ ৬ — পরে পরিষ্কার। পুরোনো CSS-কে আর কেউ চায় না নিশ্চিত হলে ৩০ দিন পরে সরানো হলো, script বা lifecycle rule দিয়ে। Lifecycle rule শুধু ফাইলের বয়স দেখে, তাই সেটিকে শুধু বাতিল ফাইলের tag-এ সীমিত করুন, নইলে এখনো চালু CSS-ও মুছে যাবে। ৩০ দিন এখানে উদাহরণ। আসল সংখ্যা ঠিক করুন আপনার ব্যবহারকারীর tab আর rollback-এর দরকার মেপে।
# উদাহরণ: চালানোর জন্য নয়। ক্রমটিই আসল কথা।
# 1) assets first. No --delete here: old files must stay.
aws s3 sync dist/assets s3://example-bucket/assets \
  --cache-control "public, max-age=31536000, immutable"

# 2) then the HTML
aws s3 cp dist/index.html s3://example-bucket/index.html \
  --cache-control "public, max-age=60"

# 3) purge one path, not /*
aws cloudfront create-invalidation \
  --distribution-id E123EXAMPLE --paths "/index.html"

Azure-এ একই কাজ az afd endpoint purge, Google-এ gcloud compute url-maps invalidate-cdn-cache দিয়ে হয়। ফ্ল্যাগগুলো docs মিলিয়ে নিন। ক্রম উল্টে আগে HTML ছাড়লে কী হয়? কিছুক্ষণের জন্য HTML এমন CSS চায় যা তখনো নেই। Origin 404 দেয়, আর কিছু CDN সেই 404-ও অল্প সময় cache করে। একে বলে negative caching. ফলে ফাইল উঠে যাওয়ার পরও কিছুক্ষণ সাজহীন পাতা দেখা যায়।

৫ · Origin রক্ষা আর certificate — দরজা একটিই রাখা

CDN-এর সব নিয়ম তখনই কাজ করে, যখন সবাই CDN দিয়েই আসেন। Origin-এর ঠিকানা সরাসরি খোলা থাকলে যে কেউ WAF আর cache-কে পাশ কাটিয়ে যেতে পারে। বাড়ির সামনে দারোয়ান রেখে পেছনের দরজা খোলা রাখার মতো।

Bucket origin — public করবেন না

পর্ব ২১-এ (Object storage চালানো) দেখেছেন, bucket public রাখা সবচেয়ে পরিচিত দুর্ঘটনা। AWS-এ origin access control CDN-কে নিজের পরিচয়ে bucket পড়তে দেয়। Bucket policy বলে দেয়, শুধু এই একটি distribution পড়তে পারবে।

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "AllowOneDistributionToRead",
    "Effect": "Allow",
    "Principal": { "Service": "cloudfront.amazonaws.com" },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::example-bucket/*",
    "Condition": {
      "StringEquals": {
        "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E123EXAMPLE"
      }
    }
  }]
}

Condition অংশটি বাদ দেবেন না। ওটি ছাড়া যেকোনো CloudFront distribution, এমনকি অন্য কারও, এই bucket পড়তে পারে। অনুমতি নিয়ে বিস্তারিত পর্ব ৩১ ও ৩২-এ।

Load balancer origin — তিনটি স্তর

  1. ঠিকানায় সীমা: Security group-এ শুধু CDN-এর IP range-কে ঢুকতে দিন (পর্ব ২৭)। AWS-এ এর জন্য তৈরি একটি managed prefix list আছে।
  2. গোপন header: ওপরের list-এ সব গ্রাহকের CDN আছে। অন্য কারও distribution-ও আপনার origin-এ আসতে পারে। তাই CDN অনুরোধে একটি গোপন header জোড়ে, আর LB-র rule সেটি না পেলে ফিরিয়ে দেয়। Header-এর মান secret manager-এ রাখুন আর পালা করে বদলান (পর্ব ৩৩)।
  3. Private origin: সম্ভব হলে origin-কে public ঠিকানাই দেবেন না। CloudFront-এর VPC origin, Azure Front Door-এর Private Link-এর মতো ব্যবস্থা এজন্যই। সমর্থন আর দাম provider-ভেদে আলাদা।
# উদাহরণ: চালানোর জন্য নয়। id-গুলো নমুনা।
aws ec2 describe-managed-prefix-lists --filters \
  Name=prefix-list-name,Values=com.amazonaws.global.cloudfront.origin-facing

aws ec2 authorize-security-group-ingress \
  --group-id sg-0123456789abcdef0 \
  --ip-permissions 'IpProtocol=tcp,FromPort=443,ToPort=443,PrefixListIds=[{PrefixListId=pl-0123456789abcdef0}]'

Azure-এ একই কাজের জন্য AzureFrontDoor.Backend service tag আছে, আর app-কে X-Azure-FDID header মিলিয়ে দেখতে হয়। Google-এর external Application LB নিজেই proxy, তাই backend-এর firewall-এ Google-এর নির্ধারিত range রাখা হয়। Range-গুলো docs থেকে নিন, মুখস্থ বা AI-এর স্মৃতি থেকে নয়।

পুরোনো ঠিকানা ফাঁস হতে পারে। CDN বসানোর আগে origin-এর IP public DNS-এ ছিল। DNS-এর ইতিহাস, পুরোনো subdomain বা origin থেকে পাঠানো mail সেই IP দেখিয়ে দিতে পারে। তাই CDN বসানোর সময় origin-এর জন্য নতুন ঠিকানা নিন, আর সেখানে শুরু থেকেই firewall-এ শুধু CDN-কে ঢুকতে দিন। DNS CDN-এ সরিয়ে পুরোনো cache শেষ হলে পুরোনো ঠিকানা ছেড়ে দিন।

Certificate — দুই ভাগের TLS

CDN থাকলে TLS সংযোগ দুটি। একটি ব্যবহারকারী থেকে edge, আরেকটি edge থেকে origin. দুটিতেই TLS certificate লাগে। দ্বিতীয়টি বাদ দিলে, অর্থাৎ edge থেকে origin-এ সাধারণ HTTP পাঠালে, browser-এ তালা দেখালেও পথের অর্ধেক খোলা থাকে।

Managed certificate হলে নেওয়া, রাখা আর নবায়নের কাজ provider করে। পর্ব ১৪-তে certbot দিয়ে যা হাতে করেছিলেন, এখানে সেটি সেবা। Private key সাধারণত আপনার হাতে আসে না, তাই আপনার দিক থেকে ফাঁসের সুযোগও কমে। তিনটি বিষয়ে তবু নজর রাখুন:

  • DNS validation-এর record রেখে দিন। নবায়নের সময় provider সেই record দেখেই মালিকানা যাচাই করে। কেউ “অদরকারি” ভেবে মুছলে নবায়ন আটকে যেতে পারে। পর্ব ১৪-এর dns-01 ধারণাই এখানে কাজ করে।
  • Region-এর নিয়ম দেখুন। লেখার সময়ে CloudFront-এর জন্য ACM certificate us-east-1-এ নিতে হয়, app যেখানেই থাকুক। এমন নিয়ম provider-ভেদে আলাদা।
  • Origin-এর নাম মিলতে হবে। Edge origin-এর certificate যাচাই করে। নাম না মিললে বা মেয়াদ ফুরালে ব্যবহারকারী 502-জাতীয় error দেখেন, অথচ edge-এর certificate ঠিকই থাকে।

Managed হলেও মেয়াদের alert রাখুন। Certificate-এর মেয়াদ কমার ধারা আগেই পর্ব ১৪-এ দেখেছেন। CA/Browser Forum-এর ২০২৫ সালের সিদ্ধান্তে সর্বোচ্চ মেয়াদ ধাপে ধাপে কমে ২০২৯ সালে ৪৭ দিনে নামার কথা। হাতে নবায়ন তখন আর চলবে না।

৬ · WAF — count আগে, block পরে

WAF মানে Web Application Firewall. Security group দেখে IP আর port. WAF অনুরোধের ভেতরটা পড়ে: path, header, query আর body-র প্রথম অংশ। মেট্রো স্টেশনের ব্যাগ স্ক্যানারের সাথে তুলনা করুন। গেটম্যান শুধু টিকিট দেখেন, স্ক্যানার ব্যাগের ভেতরটা দেখে। ফলে স্ক্যানার মাঝেমধ্যে নিরীহ জিনিসেও আপত্তি করে।

Rule-গুলো ক্রমে চলে। প্রতিটির একটি action থাকে: allow, block, count বা CAPTCHA-র মতো challenge. প্রধান ধরনগুলো এই:

ধরনকী করেমনে রাখবেন
Managed rule setProvider বা বিক্রেতার রক্ষণাবেক্ষণ করা rule-এর দল, যা SQL injection-এর মতো পরিচিত ধরন চেনেশুরুর সেরা পথ। OWASP Core Rule Set এর একটি খোলা উদাহরণ
Rate-based ruleএকটি IP বা key থেকে নির্দিষ্ট সময়ে সীমার বেশি অনুরোধ আটকায়Login-এর মতো path-এ আলাদা, কড়া সীমা দিন
Custom ruleআপনার লেখা শর্ত, যেমন /admin শুধু অফিসের ঠিকানা থেকেনিজের অ্যাপ সবচেয়ে ভালো আপনিই চেনেন
IP বা দেশের তালিকানির্দিষ্ট ঠিকানা ঠেকানো বা অনুমতি দেওয়াVPN আর ভাগ করা IP-তে ভুল হয়, তাই ভেবে দিন

নিচের JSON-এ AWS WAF-এর দুটি rule আছে। প্রথমটি managed rule set, যার ফল আপাতত শুধু গোনা হবে (Count). দ্বিতীয়টি ৫ মিনিটে একটি IP থেকে ২,০০০-এর বেশি অনুরোধ আটকাবে।

[
  {
    "Name": "managed-common",
    "Priority": 10,
    "Statement": {
      "ManagedRuleGroupStatement": {
        "VendorName": "AWS",
        "Name": "AWSManagedRulesCommonRuleSet"
      }
    },
    "OverrideAction": { "Count": {} },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "managed-common"
    }
  },
  {
    "Name": "per-ip-limit",
    "Priority": 20,
    "Statement": {
      "RateBasedStatement": {
        "Limit": 2000,
        "EvaluationWindowSec": 300,
        "AggregateKeyType": "IP"
      }
    },
    "Action": { "Block": {} },
    "VisibilityConfig": {
      "SampledRequestsEnabled": true,
      "CloudWatchMetricsEnabled": true,
      "MetricName": "per-ip-limit"
    }
  }
]

Managed rule set-এ OverrideAction, সাধারণ rule-এ Action বসে। দুটি গুলিয়ে ফেলা একটি পরিচিত ভুল। Azure-এ একই ধারণা WAF policy-র Detection আর Prevention mode, আর Cloud Armor-এ rule-এর --preview flag. সীমার সংখ্যা উদাহরণ মাত্র। আপনার নিজের স্বাভাবিক traffic মেপে সীমা ঠিক করুন।

Count বনাম block — একটি ছোট evaluator

Count mode-এ rule মিললে শুধু log হয়, অনুরোধ এগিয়ে যায়। Block-এ অনুরোধ সেখানেই শেষ। নিচের খেলনা WAF একই পাঁচটি অনুরোধ তিনভাবে চালায়। Rule-টি ইচ্ছা করেই স্থূল: body-তে “select” আর তার পরে “from” থাকলেই সন্দেহ করে। আসল rule অনেক সূক্ষ্ম, তবে ভুলের ধরন একই। কোডের good ঘরটি জানায় অনুরোধটি আসলে ভালো কি না। আসল WAF তা জানে না, আমরা রেখেছি শুধু ভুল মাপার জন্য।

// A toy WAF. Rules run in priority order: count only notes a match, block stops.
const R = (id, path, ip, body, good) => ({ id, path, ip, body, good });
const requests = [
  R(1, '/api/search', '198.51.100.8', 'select from eid offers', true),
  R(2, '/api/search', '198.51.100.9', 'select shoes from dhaka', true),
  R(3, '/api/login', '203.0.113.50', 'select ... from ... probe', false),
  R(4, '/admin', '203.0.113.50', '', false),
  R(5, '/admin', '192.0.2.10', '', true),
];
const makeRules = (mode, narrow) => [
  { name: 'sql-words', mode, test: (r) => /select.*from/.test(r.body) && !(narrow && r.path === '/api/search') },
  { name: 'admin-office-only', mode, test: (r) => r.path === '/admin' && r.ip !== '192.0.2.10' },
];
function evaluate(req, rules) {
  const counted = [];
  for (const rule of rules) {
    if (!rule.test(req)) continue;
    if (rule.mode === 'block') return { action: 'BLOCK', by: rule.name, counted };
    counted.push(rule.name);                     // count: note it, keep going
  }
  return { action: 'ALLOW', by: '-', counted };
}
function run(title, rules) {
  console.log(`--- ${title}`);
  const tally = { badBlocked: 0, goodBlocked: 0, badPassed: 0 };
  for (const r of requests) {
    const d = evaluate(r, rules), note = d.counted.length ? ' count:' + d.counted.join(',') : '';
    console.log(`#${r.id} ${r.path.padEnd(11)} ${d.action.padEnd(5)} ${d.by}${note}`);
    if (d.action === 'BLOCK') tally[r.good ? 'goodBlocked' : 'badBlocked']++; else if (!r.good) tally.badPassed++;
  }
  console.log(JSON.stringify(tally));
}
run('A: count mode', makeRules('count', false));
run('B: block mode, rule as shipped', makeRules('block', false));
run('C: block mode, /api/search excluded', makeRules('block', true));

আউটপুটের মূল অংশ:

--- A: count mode
#1 /api/search ALLOW - count:sql-words
#3 /api/login  ALLOW - count:sql-words
{"badBlocked":0,"goodBlocked":0,"badPassed":2}
--- B: block mode, rule as shipped
#1 /api/search BLOCK sql-words
{"badBlocked":2,"goodBlocked":2,"badPassed":0}
--- C: block mode, /api/search excluded
#1 /api/search ALLOW -
{"badBlocked":2,"goodBlocked":0,"badPassed":0}

A-তে কেউ আটকায়নি, কিন্তু log বলছে কী কী আটকাত। B-তে দুটি খারাপ অনুরোধ আটকেছে, সাথে দুজন আসল ক্রেতাও, যাঁরা শুধু “select” শব্দ লিখে পণ্য খুঁজছিলেন। এই ভুলের নাম false positive. C-তে শুধু একটি path-এর জন্য rule-টিকে ছাড় দেওয়া হয়েছে। পুরো rule বন্ধ করা হয়নি। তাই খারাপ দুটি আটকেছে, ভালো কেউ আটকায়নি।

Rule ছাড়ার নিরাপদ পথ

ধরুন বাজারঘরে দিনে ১০,০০,০০০ অনুরোধ আসে। নতুন managed rule set বসাবেন। নিচের সংখ্যাগুলো উদাহরণ।

Rollout-এর হিসাব
দিন
মোড
দিনে ম্যাচ
Block হলে আসল ক্রেতা আটকাতেন
এখন সত্যিই আটকাচ্ছে
  1. ধাপ ১ — Count-এ বসানো। Rule set যোগ হলো Count-এ। WAF log চালু করে এক জায়গায় পাঠানো হলো। ব্যবহারকারীর জন্য কিছু বদলায়নি।
  2. ধাপ ২ — স্বাভাবিক traffic জমানো। কয়েক দিন দেখা, যাতে সাধারণ দিন আর ব্যস্ত সময় দুটোই ধরা পড়ে। দিনে ১,২৪০টি ম্যাচ। সংখ্যাটি ছোট, কিন্তু কারা এঁরা তা এখনো অজানা।
  3. ধাপ ৩ — Log পড়া। ১,০০০টি এসেছে কয়েকটি স্ক্যানার থেকে। ২৪০টি /api/search-এ লগইন-করা ক্রেতাদের। মোট ম্যাচের ২৪০ ÷ ১,২৪০ = ১৯.৪% false positive.
  4. ধাপ ৪ — সরু ছাড়। শুধু ওই একটি rule-কে শুধু ওই path-এ ছাড় দেওয়া হলো। আবার তিন দিন Count. ম্যাচ ১,০০০, নমুনায় আসল ক্রেতা ০। ছাড়ের ফলে ওই path-এ ঝুঁকি বাড়ে, তাই সেখানে app-এর ভেতরের সুরক্ষা (parameterized query) নিশ্চিত করা হলো।
  5. ধাপ ৫ — Block. আগে staging-এ, তারপর production-এ বদল। এবার দিনে ১,০০০টি অনুরোধ সত্যিই আটকাচ্ছে। Checkout-এর সাফল্যের হার আর 403-এর সংখ্যা পাশাপাশি দেখা হচ্ছে।
  6. ধাপ ৬ — ফেরার পথ। 403 হঠাৎ বাড়লে alert বাজে। Rule-টি এক ধাপে Count-এ ফেরানো যায়, আর সেই বদল IaC-তে লেখা থাকে। Managed rule set-এর নতুন version-ও একই পথে আসে।

০.০২৪% ভুল খুব ছোট শোনায়। কিন্তু দিনে ২৪০ জন আসল ক্রেতা, আর ঈদের ভিড়ে সেটি কয়েক গুণ হতে পারে। তাঁরা error দেখে অভিযোগ করেন না, সাধারণত অন্য দোকানে চলে যান।

WAF কোড ঠিক করে না। SQL injection-এর আসল প্রতিরোধ হলো parameterized query. WAF হলো বাড়তি স্তর। নতুন দুর্বলতা জানাজানি হলে WAF rule দিয়ে সাময়িক আড়াল দেওয়া যায়, একে বলে virtual patch. ২০২১ সালের ডিসেম্বরে Log4Shell-এর সময় বহু দল তাই করেছিল। তবে নতুন রূপ দ্রুত বেরোয়, তাই patch তবু লাগে। মনে রাখবেন, অনেক WAF body-র শুধু প্রথম অংশ পড়ে। সীমাটি provider-ভেদে আলাদা।

৭ · Edge-এ rate limit — token bucket আর bot

WAF-এর rule চেনে অনুরোধের চেহারা। Rate limit দেখে অনুরোধের পরিমাণ। বৈধ চেহারার অনুরোধও অতিরিক্ত হলে ক্ষতি করে।

ঈদের আগে বাসের কাউন্টারে একটি বাটিতে কুপন রাখা। প্রতি সেকেন্ডে ২টি নতুন কুপন পড়ে, তবে বাটিতে ১০টির বেশি ধরে না। কুপন পেলে কাউন্টারে যাবেন, না পেলে ফিরে যাবেন। কেউ অনেকক্ষণ না এলে বাটি ভরে থাকে, তাই হঠাৎ ক’জন এলেও সবাই পান। কিন্তু লম্বা সময় ধরে কুপন পড়ার চেয়ে দ্রুত আসা যায় না। এটিই token bucket.

দুটি সংখ্যা। Capacity ঠিক করে একবারে সর্বোচ্চ কত বড় ঝাঁক যাবে। Rate ঠিক করে দীর্ঘ সময়ের গড় গতি। T সেকেন্ডে সর্বোচ্চ capacity + rate × T সংখ্যক অনুরোধ যেতে পারে।

// A token bucket on a simulated clock: one tick = one second.
// capacity = the largest burst; rate = tokens added per second.
function tokenBucket(capacity, rate, arrivals) {
  let tokens = capacity, passed = 0, refused = 0;
  const rows = [];
  arrivals.forEach((want, sec) => {
    if (sec > 0) tokens = Math.min(capacity, tokens + rate);   // refill first
    const ok = Math.min(want, tokens);
    tokens -= ok;
    passed += ok;
    refused += want - ok;
    rows.push(`${String(sec).padStart(2)}  want ${String(want).padStart(3)}  ok ${String(ok).padStart(3)}` +
              `  429 ${String(want - ok).padStart(3)}  tokens left ${tokens}`);
  });
  return { rows, passed, refused };
}

function show(title, capacity, rate, arrivals) {
  const r = tokenBucket(capacity, rate, arrivals);
  console.log(`--- ${title} (capacity ${capacity}, rate ${rate}/s)`);
  r.rows.forEach((x) => console.log(x));
  const total = r.passed + r.refused;
  console.log(`passed ${r.passed}/${total} (${(100 * r.passed / total).toFixed(0)}%), refused ${r.refused}`);
}

// One shopper opens a page: a quick burst of 8 calls, then normal clicks.
show('one shopper', 10, 2, [8, 1, 0, 0, 1, 0]);
// A script calling the login endpoint without pause.
show('script', 10, 2, [20, 20, 20, 20, 20, 20]);
// 30 shoppers behind one shared public IP (CGNAT), 1 call each per second.
show('30 shoppers, one shared IP', 10, 2, [30, 30, 30, 30, 30, 30]);

আউটপুটের সারাংশ লাইনগুলো:

--- one shopper (capacity 10, rate 2/s)
 0  want   8  ok   8  429   0  tokens left 2
 1  want   1  ok   1  429   0  tokens left 3
passed 10/10 (100%), refused 0
--- script (capacity 10, rate 2/s)
 1  want  20  ok   2  429  18  tokens left 0
passed 20/120 (17%), refused 100
--- 30 shoppers, one shared IP (capacity 10, rate 2/s)
passed 20/180 (11%), refused 160

ক্রেতার ৮টি অনুরোধের ঝাঁক পুরোটাই গেছে, কারণ বাটি ভরা ছিল। Script শুরুতে ১০টি পেয়েছে, তারপর সেকেন্ডে ২টি: ১০ + ২ × ৫ = ২০. কিন্তু তৃতীয় সারিটি দেখুন। ৩০ জন ভালো ক্রেতা একটি public IP ভাগ করলে ৮৯% অনুরোধ ফিরে গেছে। Bucket চিনেছে শুধু IP-কে।

শেষ সারিটি কাল্পনিক নয়। মোবাইল operator-রা প্রায়ই CGNAT ব্যবহার করেন, যেখানে বহু গ্রাহক একই public IP-র পেছনে থাকেন। বাংলাদেশের মোবাইল ইন্টারনেটেও এমন হওয়া স্বাভাবিক, যদিও ঠিক কত জন একটি IP ভাগ করেন তা operator-ভেদে আলাদা। তাই সীমা ঠিক করুন ভেবে:

  • সম্ভব হলে key হিসেবে IP নয়, লগইন-করা user id বা API key নিন।
  • Path ধরে আলাদা সীমা দিন। /api/login আর OTP পাঠানোর path কড়া, ছবির path শিথিল।
  • Block-এর আগে count করুন। সীমার ঠিক নিচে কারা আছেন, log থেকে দেখুন।
  • ঠিক উত্তর দিন। 429 Too Many Requests, সাথে Retry-After header (RFC 6585, ২০১২). ভালো client তাহলে অপেক্ষা করে আবার চেষ্টা করে।

Token bucket এখানে ধারণা বোঝানোর জন্য। Cloud-এর rate-based rule প্রায়ই নির্দিষ্ট সময়-জানালায় অনুরোধ গোনে, আর সিদ্ধান্ত নিতে কিছুটা দেরি হয়। AWS WAF-এ লেখার সময়ে জানালা ১ থেকে ১০ মিনিটের। তাই অল্প সময়ের ঝাঁক সেখানে অনেক সময় ধরা পড়ে না। API gateway আর Nginx-এর limit_req (leaky bucket) আরও সূক্ষ্মভাবে থামাতে পারে। পূর্ণ সুরক্ষায় edge আর app দুই জায়গাতেই সীমা রাখুন।

Bot — সব bot শত্রু নয়

Traffic-এর একটি বড় অংশ মানুষের নয়। Search engine-এর crawler আপনার দরকার। দাম-তুলনার bot নিয়ে মত ভিন্ন হতে পারে। চুরি যাওয়া password নিয়ে লগইন-চেষ্টা বা ছাড়ের পণ্য লুটে নেওয়া bot ক্ষতিকর। Bot management সেবাগুলো এদের আলাদা করতে চায়। ব্যবহার করে আচরণ, TLS-এর ধরন, JavaScript challenge আর পরিচিত bot-এর তালিকা। AWS WAF Bot Control, Azure-এর bot rule আর Cloud Armor-এর reCAPTCHA সংযোগ এর উদাহরণ।

দুটি সতর্কতা। robots.txt শুধু অনুরোধ, প্রহরী নয়। আর CAPTCHA প্রতিবন্ধী ব্যবহারকারী আর ধীর network-এ ভোগায়, তাই শুধু সন্দেহজনক অনুরোধে দিন। Bot ঠেকানোর সবচেয়ে কাজের সঙ্গী সেবাটি নিজে নয়, বরং ব্যবসার যুক্তি: এক অ্যাকাউন্টে কতগুলো ছাড়ের পণ্য, আর একটি নম্বরে কতগুলো OTP.

৮ · DDoS — তিন স্তর, আর কে কোনটি সামলায়

DDoS মানে Distributed Denial of Service: বহু উৎস থেকে একসাথে এত চাপ, যাতে আসল ব্যবহারকারী সেবা না পান। এখানে আমরা শুধু প্রতিরক্ষার দিক দেখব। মূল প্রশ্ন একটিই: চাপটি কোন জায়গা ভরে ফেলতে চায়?

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

স্তরকী ভরেকে শোষণ করেআপনার কাজ
Volumetric (L3/L4)Network-এর পথ, মাপা হয় Gbps বা Tbps-এProvider-এর বিশাল network, anycast আর scrubbingOrigin-এর IP আড়ালে রাখা, সব traffic edge দিয়ে আনা
Protocol (L3/L4)Connection-এর টেবিল, মাপা হয় packet per second-এEdge আর managed LB, যারা সংযোগ নিজেরাই শেষ করেServer-কে সরাসরি খোলা না রাখা, SYN cookie-র মতো সুরক্ষা চালু রাখা
Application (L7)CPU, database, মাপা হয় request per second-এWAF, rate limit, challenge, cacheঅনেকটাই আপনার: rule সাজানো, দামি path চেনা, cache বাড়ানো

লক্ষ করুন, ওপর থেকে নিচে নামলে দায় provider থেকে আপনার দিকে সরে। এটিই shared responsibility. L7-এর অনুরোধ দেখতে বৈধ, তাই আপনার অ্যাপের কোন path দামি, তা provider জানে না।

তিন provider-এ লেখার সময়ের ছবি মোটামুটি এই। AWS Shield Standard L3/L4 সুরক্ষা স্বয়ংক্রিয়ভাবে দেয়, আর Shield Advanced একটি paid স্তর, যাতে বাড়তি সাহায্য ও খরচ-সুরক্ষার সুবিধা আছে। Azure DDoS Protection-এর ভিত্তি-সুরক্ষার ওপরে paid স্তরে VNet-এর public IP-র জন্য বাড়তি নীতি আর মাপজোখ মেলে। L7-এর জন্য Azure WAF লাগে। Google Cloud Armor external Application LB-র সামনে L3/L4 সুরক্ষা দেয়, আর নিরাপত্তা নীতিতে L7-এর rule চলে। শর্ত আর দাম বদলায়, তাই docs মিলিয়ে নিন।

আক্রমণের সময় autoscaling — বিলের হিসাব

পর্ব ১৭-এ দেখেছেন, চাপ বাড়লে autoscaling server বাড়ায়। L7 চাপেও সে তাই করবে। সে তো ভালো-মন্দ চেনে না। ধরুন cache না হওয়া একটি search path-এ ৬ ঘণ্টা ধরে সেকেন্ডে ৫,০০০ অনুরোধ এলো। প্রতিটি server ১০০ req/s নেয়, স্বাভাবিক সময়ে ৪টি চলে, উত্তর ২০০ KB. ধরে নেওয়া দাম: server ঘণ্টায় $০.১০, egress GB-তে $০.০৮, WAF-এর পরীক্ষা ১০ লাখে $০.৫০।

খাতহিসাবEdge-এ না থামালেEdge-এ ৯৮% থামালে
Server৫,০০০ ÷ ১০০ = ৫০, অর্থাৎ ৪৬টি বাড়তি × ৬ × $০.১০$২৭.৬০$০ (origin-এ ১০০ req/s)
Egress৫,০০০ × ২০০ KB × ২১,৬০০ s = ২১,৬০০ GB × $০.০৮$১,৭২৮$৩৪.৫৬ (৪৩২ GB)
WAF১০.৮ কোটি অনুরোধ × $০.৫০ প্রতি ১০ লাখে$৫৪$৫৪
মোট$১,৮০৯.৬০$৮৮.৫৬

দুটি শিক্ষা। প্রথমত, এখানে বিলের বড় অংশ server নয়, bandwidth. দ্বিতীয়ত, WAF-এর পরীক্ষার টাকা থেকেই যায়, কারণ আটকাতেও পড়তে হয়। এই ধরনের ক্ষতির একটি নাম আছে: economic denial of sustainability. সেবা বন্ধ হয় না, কিন্তু বিল সহ্যের বাইরে চলে যায়।

  • Autoscaling-এর max রাখুন। এটি বিলের ছাদ, তবে ছাদে পৌঁছালে সেবা ধীর হবে। ব্যবসার সাথে কথা বলে সংখ্যাটি ঠিক করুন।
  • Serverless-এ concurrency-র সীমা রাখুন। প্রতিটি call-এ টাকা, তাই সীমা না থাকলে খরচও সীমাহীন (পর্ব ৬৯)।
  • Budget alert খরচ থামায় না। শুধু জানায়। তাই request rate আর egress-এর আলাদা alert রাখুন।
  • আগেই অনুশীলন করুন। Runbook-এ লিখুন: কে সিদ্ধান্ত নেবেন, কোন rule আগে কড়া হবে, cached পাতা দেখানো যাবে কি না, provider-এর সাহায্য কীভাবে চাইবেন। আপনার সিস্টেমে চাপ পরীক্ষা করতে চাইলে provider-এর নিয়ম মানুন। অন্যের সিস্টেমে কখনোই নয়।

৯ · Edge function, log আর খরচ

Edge function — এবং তার সীমা

Edge function হলো edge-এ চলা ছোট প্রোগ্রাম। Edge computing-এর এটিই সবচেয়ে পরিচিত রূপ। Redirect, header বদলানো, cache key স্বাভাবিক করা, token-এর সহজ যাচাই আর A/B পরীক্ষার ভাগ এখানে ভালো মানায়। উদাহরণ: CloudFront Functions, Lambda@Edge, Cloudflare Workers, Fastly Compute. Azure Front Door-এ অনেক কাজ rule engine দিয়ে হয়।

// Example: not runnable here. Adds security headers on the way back to the viewer.
function handler(event) {
  var response = event.response;
  response.headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubDomains' };
  response.headers['x-content-type-options'] = { value: 'nosniff' };
  return response;
}

প্রতিটি উত্তরে function-টি দুটি নিরাপত্তা header জোড়ে। App না বদলেই সব পাতায় নিয়ম বসে গেল। HSTS-এর সময় বাড়ানোর আগে পর্ব ১৪-এর সতর্কতা মনে রাখুন: একবার পাঠালে ফেরা কঠিন।

Edge সব কাজের জায়গা নয়। সীমাগুলো জেনে নিন:

  • সময় আর আকার ছোট। CPU সময়, memory আর কোডের আকারের কড়া সীমা থাকে। হালকা ধরনে network call-ও নিষেধ হতে পারে। সংখ্যাগুলো পণ্যভেদে আলাদা।
  • ডেটা কাছে নেই। Database এক region-এ থাকলে edge থেকে প্রতিটি query দূরে যায়। তখন edge-এ কোড চালিয়ে উল্টো দেরি বাড়ে।
  • Debug কঠিন। Log অনেক জায়গায় ছড়ানো। ভুল rollout সব edge-এ পৌঁছায়। তাই staging distribution আর ধীরে ছাড়া দরকার।
  • প্রতি অনুরোধে টাকা। সব অনুরোধে function চালালে বিল আর latency দুটোই বাড়ে। শুধু দরকারি path-এ লাগান।

Log — কী হচ্ছে, তার একমাত্র সাক্ষী

CDN-এর access log বলে কোন edge, কোন path, hit না miss, কত byte. WAF log বলে কোন rule, কোন action. নিচের Bash block একটি নমুনা log থেকে দুই রকম hit ratio, origin-এ ফেরা path আর status-এর ভাগ বের করে। সব ডেটা block-এর ভেতরেই বানানো।

set -euo pipefail
log=$(mktemp)
# fields: time edge status result bytes path (sample data)
cat > "$log" <<'EOF'
10:00:01 EDGE-A 200 Hit 48000 /css/app.7d2e40.css
10:00:01 EDGE-A 200 Hit 900000 /img/banner.webp
10:00:02 EDGE-B 200 Miss 900000 /img/banner.webp
10:00:02 EDGE-A 200 Hit 48000 /css/app.7d2e40.css
10:00:03 EDGE-A 200 Miss 3000 /index.html?utm_source=fb
10:00:03 EDGE-A 200 Miss 3000 /index.html?utm_source=wa
10:00:04 EDGE-B 200 Hit 900000 /img/banner.webp
10:00:04 EDGE-A 200 Miss 3000 /index.html?utm_source=sms
10:00:05 EDGE-A 200 Hit 48000 /css/app.7d2e40.css
10:00:05 EDGE-B 502 Error 0 /api/cart
10:00:06 EDGE-A 403 Blocked 150 /api/login
10:00:06 EDGE-A 200 Hit 900000 /img/banner.webp
10:00:07 EDGE-B 200 Hit 48000 /css/app.7d2e40.css
10:00:07 EDGE-A 200 Hit 900000 /img/banner.webp
EOF

echo "== hit ratio by requests and by bytes"
awk '$4=="Hit"{h++; hb+=$5} {n++; b+=$5}
END {printf "requests %d, hit %d (%.0f%%)\n", n, h, 100*h/n
     printf "bytes hit %.0f%%\n", 100*hb/b}' "$log"

echo "== what goes back to the origin"
awk '$4=="Miss"{print $6}' "$log" | cut -d'?' -f1 | sort | uniq -c | sort -k1,1nr

echo "== status by result"
awk '{print $3, $4}' "$log" | sort | uniq -c | sort -k1,1nr

rm -f "$log"

আউটপুট:

== hit ratio by requests and by bytes
requests 14, hit 8 (57%)
bytes hit 81%
== what goes back to the origin
      3 /index.html
      1 /img/banner.webp
== status by result
      8 200 Hit
      4 200 Miss
      1 403 Blocked
      1 502 Error

অনুরোধ ধরে ৫৭%, byte ধরে ৮১%, কারণ বড় ছবিটি বেশিরভাগ hit. Query বাদ দিলে দেখা যায় /index.html তিনবার miss, কারণ utm_source cache key-তে ঢুকে আছে। Key থেকে এটি সরালে তিনটি miss-এর জায়গায় একটি হতো: hit ১০/১৪ = ৭১%. একটি সেটিংয়ে ১৪ পয়েন্ট লাভ। Blocked আর Error-কে হিসাবে রাখা হবে কি না, সে সংজ্ঞা CDN-ভেদে আলাদা। পরে পর্ব ৬৪-তে centralized logging-এ আরও দেখবেন।

Log-এ ব্যক্তিগত তথ্য থাকতে পারে: IP, URL-এর query, cookie. Authorization আর Cookie header WAF log থেকে বাদ দিন (redaction), মেয়াদ ঠিক করুন, আর অনুমতি সীমিত রাখুন। প্রতিদিন যে সংখ্যাগুলোয় চোখ রাখবেন: hit ratio, edge-এর 4xx আর 5xx, origin-এর latency, WAF-এর block, আর egress.

বিলের খাত

খাতকীভাবে মাপা হয়কমানোর উপায়
CDN থেকে বাইরে যাওয়া ডেটাGB, অঞ্চল-ভেদে দাম আলাদাছবি ছোট করা, compression, সব অঞ্চল চালু না রাখা
অনুরোধপ্রতি ১০ লাখ বা ১০ হাজারেBrowser-cache লম্বা করা, যাতে অনুরোধই না আসে
Origin থেকে CDN-এGB, কিছু জুটিতে বিনা খরচেHit ratio বাড়ানো, shield
Invalidationনির্দিষ্ট সংখ্যার পরে path ধরেVersioned নাম
WAFPolicy, rule আর অনুরোধ ধরেঅপ্রয়োজনীয় rule বাদ, শুধু দরকারি path-এ দামি rule
Edge functionCall, কখনো সময়ওশুধু দরকারি path
Logজমা আর পাঠানো ডেটাSampling, lifecycle rule

এক শর্ত সবসময় মনে রাখুন: কোনো egress-এর দাম নির্দিষ্ট নয়। ফ্রি-টিয়ার আর চুক্তি provider-ভেদে আলাদা। আপনার traffic দিয়ে হিসাব করুন। পর্ব ৭৩-এ FinOps-এ বিস্তারিত দেখবেন।

আরও গভীরে: CDN-এর শিক্ষাগত ভিত্তি Akamai-এর প্রকাশিত প্রবন্ধগুলো: Dilley et al. “Globally Distributed Content Delivery” (IEEE Internet Computing, ২০০২) আর Nygren et al. “The Akamai Network” (ACM SIGOPS OSR, ২০১০). Edge-এর নকশায় একটি বড় বদল হলো anycast-এ HTTP চালানো, যেখানে একই IP অনেক শহর থেকে ঘোষিত হয়, আর আক্রমণের চাপও শহরে শহরে ভাগ হয়ে যায়। সংযোগ-স্তরের সুরক্ষার ক্লাসিক দলিল RFC 4987 (SYN flooding, ২০০৭), আর WAF rule-এর খোলা মান OWASP Core Rule Set, যেখানে paranoia level বাড়ালে সুরক্ষা ও false positive একসাথে বাড়ে।

পরীক্ষা ও ইন্টারভিউতে:

  • Hit ratio ৯০% থেকে ৯৫% হলে origin-এর ভার? Miss ১০% থেকে ৫%, অর্থাৎ অর্ধেক।
  • no-cache আর no-store-এর পার্থক্য? প্রথমটি রাখা যায় তবে যাচাই লাগে, দ্বিতীয়টি রাখাই যায় না।
  • Invalidation-এর চেয়ে versioned নাম ভালো কেন? Browser-এর কপিতেও কাজ করে, cold cache হয় না, rollback সহজ।
  • নতুন WAF rule কীভাবে ছাড়বেন? Count-এ বসিয়ে log পড়া, সরু ছাড়, তারপর block আর alert.
  • L3/L4 আর L7 DDoS-এর পার্থক্য? প্রথমটি network আর connection ভরে, মূলত provider শোষণ করে। দ্বিতীয়টি বৈধ-চেহারার অনুরোধে CPU ভরে, WAF আর cache লাগে।

১০ · AI-এর যুগে edge config যাচাই

AI একটি distribution বা WAF rule কয়েক সেকেন্ডে লিখে দেয়। কিন্তু edge-এর ভুল সব ব্যবহারকারীর ওপর একসাথে পড়ে। আর ভুলটি প্রায়ই চুপচাপ থাকে: সাইট চলছে, শুধু অন্যের পাতা অন্যজন দেখছেন, বা origin খোলা পড়ে আছে।

AI যা দিতে পারেঝুঁকিকীভাবে ধরবেন
লগইন-করা পাতায় Cache-Control: publicএক ব্যবহারকারীর তথ্য আরেকজনের কাছেদুই account দিয়ে throwaway পরিবেশে পরীক্ষা, cookie-সহ পাতা private বা no-store
Origin-এর firewall-এ 0.0.0.0/0CDN আর WAF পাশ কাটানো যায়CDN ছাড়া সরাসরি origin-এ curl করে দেখা, ব্যর্থ হওয়া উচিত
Bucket-এ "Principal": "*"পুরো bucket খোলাBlock public access আর একটি distribution-এর শর্ত
Deploy script-এ --paths "/*"Cold cache, origin-এ হঠাৎ চাপ, বাড়তি খরচশুধু HTML purge, বাকিটা hash-নাম
প্রথম দিনেই WAF-এ blockআসল ক্রেতা আটকে যানCount, log, সরু ছাড়, তারপর block
Config-এ গোপন header-এর মানGit-এ secret চলে যায়Secret manager থেকে আনা, পালা করে বদলানো
অস্তিত্বহীন argument বা পুরোনো fieldApply-তে ব্যর্থ, বা নীরবে অন্য defaultterraform plan পড়া, official docs মেলানো
ভুল region-এ certificateCDN certificate পায় নাProvider-এর region-এর নিয়ম মেলানো

AI-কে config লিখতে বলার সময় পরিবেশ, উদ্দেশ্য আর সীমা বলে দিন। শেষে যাচাইয়ের পথও চান। কোনো account id, key বা গোপন header-এর আসল মান দেবেন না।

আমি একটি অনলাইন দোকানের জন্য CDN সাজাচ্ছি। Origin দুটি: private bucket (/assets/*, নামে hash আছে) আর load balancer (বাকি সব, লগইন-করা পাতা ও API). নিচের কাজগুলো করো: ১. Terraform-এ distribution লেখো। ডিফল্ট behaviour-এ cache বন্ধ রাখবে। ২. Cache key-তে কী কী আছে, আর কেন, তা ব্যাখ্যা করো। utm_ query বাদ দেবে। ৩. Origin-এ সরাসরি ঢোকা ঠেকাতে কী কী করেছ বলো। কোনো secret-এর মান config-এ লিখবে না। ৪. WAF-এর managed rule set শুধু count মোডে বসাও, আর block-এ যাওয়ার শর্ত লেখো। ৫. প্রতিটি resource argument কোন official doc-এ আছে তার নাম বলো। অনিশ্চিত হলে "নিশ্চিত নই" লেখো। ৬. এই config-এ মাসে কোন কোন খাতে খরচ হবে তার তালিকা দাও। দাম অনুমান করবে না। ৭. আমি plan দেখার আগে কোনো destroy বা apply কমান্ড চালাতে বলবে না।

AI-এর দেওয়া edge config হাতে পেলে — যাচাইয়ের চেকলিস্ট

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

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

প্র ০১আক্রমণ ঠেকাতে তাড়াহুড়ো করে বসানো একটি cache নিয়ম কি নিজেই বড় দুর্ঘটনা ঘটাতে পারে?

পারে, আর এর একটি প্রকাশ্য উদাহরণ আছে। ২০১৫ সালের বড়দিনে Steam-এ ব্যবহারকারীরা হঠাৎ অন্যের account-এর পাতা দেখতে শুরু করেন। Valve-এর প্রকাশিত ব্যাখ্যা অনুযায়ী, সেদিন সাইটে সাধারণের বহু গুণ বেশি traffic এসেছিল, যা একটি DoS আক্রমণের অংশ। চাপ সামলাতে তাদের caching সহযোগী একটি নতুন config বসান। সেই config লগইন-করা ব্যবহারকারীদের উত্তরও ভুল করে cache করে ফেলে। ফলে প্রায় ৩৪ হাজার ব্যবহারকারীর ব্যক্তিগত তথ্যের কিছু অংশ অন্যরা দেখতে পান, যদিও Valve জানায় পূর্ণ কার্ড নম্বরের মতো তথ্য প্রকাশ পায়নি।

এই ঘটনায় তিনটি শিক্ষা আছে। প্রথমত, চাপের মুহূর্তেই মানুষ সবচেয়ে ঝুঁকিপূর্ণ বদল করে। পরিকল্পিত দিনে যে config-এ review হতো, আগুন নেভানোর সময় তা সরাসরি production-এ যায়। তাই আক্রমণের সময়ের পদক্ষেপ আগেই runbook-এ লিখে অনুশীলন করে রাখতে হয়।

দ্বিতীয়ত, cache-এর ডিফল্ট হওয়া উচিত “রাখবেন না”। এই পর্বের Terraform উদাহরণে ডিফল্ট behaviour ঠিক এজন্যই cache বন্ধ রাখে। ভুলে গেলে ক্ষতি হয় গতির, গোপনীয়তার নয়।

তৃতীয়ত, ব্যক্তিগত উত্তরে origin থেকেই স্পষ্ট private বা no-store পাঠান। তাহলে CDN-এর নিয়মে ভুল হলেও অনেক ক্ষেত্রে আরেকটি স্তর রক্ষা করে, যদিও override-এর সেটিং সেই সুরক্ষাও ভাঙতে পারে। এজন্য দুই account দিয়ে পরীক্ষা জরুরি।

গবেষকরা পরে web cache poisoning আর cache deception নামে এই পরিবারের ভুলগুলো নথিবদ্ধ করেছেন। প্রতিরক্ষার মূল কথা একই: cache key-তে উত্তরের সব প্রভাবক থাকবে, আর ব্যক্তিগত জিনিস cache হবে না।

মূল উপলব্ধি: Cache শুধু গতির টুল নয়, এটি তথ্য ভাগ করার যন্ত্র। ভুল জায়গায় বসলে এক জনের জিনিস সবার হয়ে যায়।

প্র ০২Edge-এ একটি ভুল rule সারা পৃথিবীতে একসাথে পৌঁছায়। তাহলে count mode কি যথেষ্ট সুরক্ষা?

না, যথেষ্ট নয়। Count বলে দেয় rule কাকে ধরবে, কিন্তু rule চলার খরচ থেকে বাঁচায় না। ২০১৯ সালের ২ জুলাই Cloudflare-এর ঘটনাটি এর সেরা উদাহরণ। তাদের প্রকাশিত postmortem অনুযায়ী, WAF-এ একটি নতুন regular expression যোগ হয়। Rule-টি simulate অবস্থায় ছিল, অর্থাৎ কাউকে আটকাচ্ছিল না। কিন্তু regex-টি backtracking-এ এত CPU খরচ করে যে সারা বিশ্বের edge-এ CPU প্রায় পূর্ণ হয়ে যায়। প্রায় ২৭ মিনিট বহু ওয়েবসাইটে 502 দেখা যায়। আক্রমণ ছিল না, ভুলটি নিজেদের।

কারণটি গঠনগত। WAF-এর rule দ্রুত ছড়াতে হয়, কারণ নতুন হুমকির সময় মিনিট গোনা হয়। তাই স্বাভাবিক কোডের ধীর rollout সেখানে এড়ানো হয়েছিল। Postmortem-এ তারা staged rollout ফেরানো আর regex engine বদলানোর পরিকল্পনার কথা জানায়।

আরেকটি উদাহরণ ২০২১ সালের জুনের Fastly-র ঘটনা। প্রকাশিত ব্যাখ্যা অনুযায়ী, একজন গ্রাহকের বৈধ config বদল আগে থেকে লুকিয়ে থাকা একটি software bug-কে জাগিয়ে তোলে। ফলে নেটওয়ার্কের বড় অংশ error দিতে শুরু করে, আর এক ঘণ্টার কম সময়ে বেশিরভাগ সেবা ফেরে। অনেক বড় সংবাদমাধ্যম আর সরকারি সাইট একসাথে ক্ষণিকের জন্য ডুবে যায়।

আপনার জন্য শিক্ষা হলো: edge config-কে production কোডের মতো দেখুন। Git-এ রাখুন, review করুন, staging distribution-এ আগে চালান, ছোট অংশে ছাড়ুন, আর metric দেখে এগোন। Rule-এর latency আর CPU-ও মাপুন। আর ভাবুন, CDN নিজে পড়ে গেলে কী হবে: DNS দিয়ে অন্য CDN-এ যাবেন, নাকি অপেক্ষা? উত্তরটি খরচ আর জটিলতার trade-off.

মূল উপলব্ধি: Edge আপনার সবচেয়ে বড় ঢাল, আবার সবচেয়ে বড় blast radius. যা সব জায়গায় একসাথে পৌঁছায়, তা ধীরে ছাড়ার নিয়ম সবচেয়ে বেশি দাবি করে।

প্র ০৩নিজের server বাড়িয়ে DDoS ঠেকানো যায় না কেন? আকারের ইতিহাস কী বলে?

কারণ চাপের সীমা আপনার server নয়, তার আগের পথ। ধরুন আপনার region-এ ১০ Gbps-এর সংযোগ। তার বেশি traffic এলে সেটি server পর্যন্ত পৌঁছানোর আগেই ভরে যায়। Server হাজারটি থাকলেও লাভ নেই। রাস্তা বন্ধ হলে কাউন্টার বাড়িয়ে কী হবে?

ইতিহাসে সংখ্যা দ্রুত বেড়েছে। ২০১৬ সালের অক্টোবরে Mirai নামের botnet, যা মূলত ক্যামেরা আর রাউটারের মতো দুর্বল IoT যন্ত্র নিয়ে গড়া, DNS প্রদানকারী Dyn-কে লক্ষ্য করে। ফলে বহু জনপ্রিয় সেবা কিছু সময় পৌঁছানোর বাইরে চলে যায়, যদিও তারা নিজেরা সরাসরি লক্ষ্য ছিল না। এটি dependency-র শিক্ষা। ২০১৮ সালের ফেব্রুয়ারিতে GitHub প্রায় ১.৩৫ Tbps-এর চাপ দেখে, আর DDoS সুরক্ষা সেবায় traffic ঘুরিয়ে কয়েক মিনিটের মধ্যে সামলায়। ২০২৩ সালের অক্টোবরে Google, Cloudflare আর AWS একসাথে HTTP/2 Rapid Reset (CVE-2023-44487) প্রকাশ করে। Google জানায়, সর্বোচ্চ চাপ ছিল সেকেন্ডে প্রায় ৩৯.৮ কোটি অনুরোধ। পরে আরও বড় চাপের খবরও এসেছে।

লক্ষ করুন, শেষ উদাহরণটি L7. সেটি ঠেকাতে protocol implementation-এ patch লেগেছিল। ক্ষমতা একা যথেষ্ট ছিল না। অর্থাৎ বড় network থাকলেও নতুন দুর্বলতার সামনে software দ্রুত হালনাগাদ করতে হয়।

তাই প্রতিরক্ষা দাঁড়িয়ে আছে তিনটি জিনিসে। ভাগ করা ক্ষমতা: Provider-এর network অনেক গ্রাহকের জন্য বিশাল, আর anycast চাপকে ছড়িয়ে দেয়। উৎসের কাছে থামানো: BCP 38 (RFC 2827, ২০০০) বলে, নেটওয়ার্কগুলো জাল ঠিকানার packet নিজের সীমানাতেই থামাক। নিয়মটি পুরোনো, তবে সবখানে মানা হয় না। নকশা: Origin আড়ালে, দামি path সীমিত, static জিনিস cache-এ।

মূল উপলব্ধি: DDoS সুরক্ষা server কেনার প্রশ্ন নয়, জায়গা বাছার প্রশ্ন। চাপকে আপনার দরজা থেকে অনেক দূরে, যার ক্ষমতা বেশি তার কাছে থামাতে হবে।

প্র ০৪CDN-কে TLS খুলতে দেওয়া মানে আপনি আসলে কাকে কী বিশ্বাস করছেন?

Edge cache বা WAF চালাতে হলে অনুরোধ পড়তে হয়। অর্থাৎ TLS edge-এ শেষ হয়। সেখানে ডেটা সাধারণ লেখা হিসেবে থাকে: password, card-এর তথ্য, session cookie. ব্যবহারকারী তালা দেখেন, কিন্তু সেই তালা খোলার ক্ষমতা তৃতীয় পক্ষের হাতে। “End-to-end encryption” কথাটি এখানে আর খাটে না।

এই বিশ্বাসের দাম প্রকাশ পেয়েছিল ২০১৭ সালের ফেব্রুয়ারিতে। Google Project Zero-র Tavis Ormandy লক্ষ করেন, Cloudflare-এর কিছু উত্তরে অন্য সাইটের memory-র টুকরো চলে আসছে। এর ডাকনাম হয় Cloudbleed. কারণ ছিল একটি HTML parser-এর bug. ফাঁস হওয়া টুকরোয় cookie আর token-এর মতো তথ্য ছিল, আর কিছু search engine-এর cache-এও তা জমেছিল। Cloudflare সেগুলো মুছতে কাজ করে। মূল কথা হলো, ভাগ করা edge-এ এক গ্রাহকের সাইটের কারণে অন্য গ্রাহকের ডেটা ফাঁস হতে পারে। আপনার কোডে ভুল না থাকলেও আপনি ক্ষতিগ্রস্ত হতে পারেন।

তাহলে কি CDN এড়াবেন? সাধারণত না, কারণ সুবিধা বিশাল। বরং ঝুঁকি কমান:

  • খুব সংবেদনশীল path, যেমন পেমেন্টের ধাপ, আলাদা domain-এ রাখুন, প্রয়োজনে L4 passthrough-এ।
  • কিছু ক্ষেত্রে field-level encryption ব্যবহার করুন, যাতে edge শুধু এনক্রিপ্ট করা মান দেখে।
  • Keyless ধরনের ব্যবস্থায় private key নিজের কাছে রাখা যায়, তবে খোলা ডেটা তবু edge দেখে।
  • Provider-এর audit report আর চুক্তির ডেটা-প্রক্রিয়াকরণের শর্ত দেখুন। পেমেন্ট বা স্বাস্থ্য-তথ্যে আইনি শর্ত থাকতে পারে, যা দেশ ও খাতভেদে আলাদা। বাংলাদেশে ব্যক্তিগত উপাত্ত সুরক্ষা আইন, ২০২৬ আর খাতের নিয়ন্ত্রকের বর্তমান নীতিমালা যাচাই করুন (পর্ব ৩৫)।
  • Log-এ কোনো গোপন তথ্য যেন না যায়, তা নিশ্চিত করুন।

মূল উপলব্ধি: CDN বেছে নেওয়া শুধু গতির সিদ্ধান্ত নয়, trust boundary-র সিদ্ধান্ত। আপনার threat model-এ edge একজন পক্ষ, আর তাকে কতটা দেখতে দেবেন তা আপনিই ঠিক করেন।

প্র ০৫Managed certificate থাকলে কি certificate-এর মেয়াদ নিয়ে আর ভাবতে হয় না?

কম ভাবতে হয়, তবে একেবারে না। Certificate ফুরানো শিল্পের সবচেয়ে বিব্রতকর দুর্ঘটনাগুলোর একটি, কারণ এটি আগে থেকেই ক্যালেন্ডারে লেখা থাকে। ২০২০ সালের ৩ ফেব্রুয়ারি Microsoft Teams কয়েক ঘণ্টার জন্য অনেক ব্যবহারকারীর কাছে অচল হয়। Microsoft জানায়, কারণ একটি মেয়াদোত্তীর্ণ authentication certificate. বড় প্রতিষ্ঠানেও এমন হয়, কারণ নবায়ন বছরে একবার ঘটে, আর সেই সময়ের মধ্যে দায়িত্বশীল মানুষ বদলে যান। তালিকায় একটি certificate বাদ পড়লেই পুরো সেবা থামতে পারে।

Managed ব্যবস্থা নবায়নের কাজ নেয়, কিন্তু নবায়নের শর্ত আপনার দায়িত্বে থাকে।

  • DNS record: Validation-এর record মুছলে নবায়ন আটকাতে পারে। DNS অন্য দলের হাতে থাকলে ঝুঁকি বেশি।
  • Email validation: নবায়নে মানুষের ক্লিক লাগে। সম্ভব হলে DNS validation নিন।
  • CAA record: ভুল সেট থাকলে নবায়নকারী CA প্রত্যাখ্যাত হতে পারে।
  • অন্য জায়গায় কপি: Certificate pinning করা mobile app, বা হাতে বসানো origin certificate নিজে নবায়ন হয় না।
  • Edge বনাম origin: Edge-এরটি নবায়ন হলেও origin-এরটি ফুরালে 502 আসবে।

শিল্প এখন উল্টো পথে হাঁটছে। মেয়াদ বাড়ানোর বদলে কমানো হচ্ছে, যাতে ফাঁস হওয়া key-র ক্ষতি সীমিত হয়, আর automation বাধ্য হয়। CA/Browser Forum-এর ২০২৫ সালের সিদ্ধান্তে ধাপে ধাপে ৪৭ দিনের দিকে যাওয়ার কথা বলা হয়েছে। ACME (RFC 8555, ২০১৯) এই পথকে সম্ভব করেছে। Certificate Transparency (RFC 6962, ২০১৩)-র ফলে প্রতিটি public certificate-এর লগ প্রকাশ্যে থাকে। তাই আপনার নামে অচেনা certificate বেরোলে নজরদারি করা যায়, আর এটিও মনে রাখুন যে certificate-এর host নাম গোপন থাকে না।

মূল উপলব্ধি: Automation দায়িত্ব মুছে দেয় না, দায়িত্বের জায়গা বদলায়। হাতে নবায়ন থেকে “নবায়ন সচল আছে কি না” মাপায়। মেয়াদের alert বন্ধ করবেন না।

অনুশীলন

কোনো cloud account লাগবে না। আসল cloud ব্যবহার সবসময় ঐচ্ছিক।

  1. হিসাব করুন: একটি সাইটে মাসে (৩০ দিন) ১৮ কোটি অনুরোধ আসে। Peak গড়ের ৮ গুণ। গড় উত্তর ৫০ KB. (ক) গড় আর peak req/s কত? (খ) Hit ratio ৯২% হলে peak-এ origin কত req/s পায়? (গ) Origin peak-এ সর্বোচ্চ ২০ req/s নিতে পারলে hit ratio কমপক্ষে কত লাগবে? (ঘ) ৯২% hit-এ মাসে কত GB origin থেকে CDN-এ আসে (miss-এর উত্তরের আকার গড়ের সমান ধরে)?

    (ক) ১৮,০০,০০,০০০ ÷ ২৫,৯২,০০০ s = ৬৯.৪ req/s গড়। Peak ৬৯.৪ × ৮ = ৫৫৫.৬ req/s.

    (খ) ৫৫৫.৬ × ০.০৮ = ৪৪.৪ req/s.

    (গ) ৫৫৫.৬ × (1 − h) ≤ ২০, তাই 1 − h ≤ ০.০৩৬, অর্থাৎ h ≥ ৯৬.৪%. ৯২% থেকে ৯৬.৪% মানে miss অর্ধেকের বেশি কমানো। প্রথমে cache key পরিষ্কার করুন আর TTL দেখুন।

    (ঘ) মোট ১৮ কোটি × ৫০ KB = ৯,০০০ GB. তার ৮% = ৭২০ GB.

  2. নকশা সমালোচনা করুন: একটি দলের সেটআপ: (১) cache key-তে সব cookie, (২) প্রতি deploy-এ /* invalidation, (৩) origin LB-র firewall 0.0.0.0/0, (৪) নতুন WAF rule সরাসরি block, (৫) সব অনুরোধে IP ধরে সেকেন্ডে ৫টির সীমা, (৬) certificate-এর DNS record “অদরকারি” ভেবে মুছে ফেলা। প্রতিটির ক্ষতি আর সমাধান বলুন।
    • (১) প্রতিটি ব্যবহারকারীর আলাদা কপি, তাই hit প্রায় শূন্য। Cookie শুধু দরকারি হলে, নাম ধরে allow-list করে রাখুন।
    • (২) প্রতি deploy-এ cold cache আর origin-এ ঢেউ। Hash-নাম আর শুধু HTML purge.
    • (৩) CDN আর WAF পাশ কাটানো যায়। CDN-এর range, গোপন header, সম্ভব হলে private origin.
    • (৪) আসল ক্রেতা আটকাবেন। Count, log, সরু ছাড়, তারপর block আর alert.
    • (৫) CGNAT-এর পেছনের ক্রেতারা আটকাবেন, আর একটি পাতার ঝাঁকেও আটকাতে পারে। Path ধরে সীমা, সম্ভব হলে user id দিয়ে, আর সংখ্যা ঠিক করতে আগে count.
    • (৬) নবায়ন ব্যর্থ হতে পারে, মাসখানেক পরে হঠাৎ সাইট অচল। Record ফেরান, IaC-তে রাখুন, মেয়াদের alert দিন।
  3. ফল আগে বলুন: Token bucket-এর capacity ৩, rate সেকেন্ডে ১, শুরুতে ভরা। প্রতি সেকেন্ডের শুরুতে আগে refill হয় (০ নম্বর সেকেন্ড ছাড়া)। আসা অনুরোধ: সেকেন্ড ০-এ ৫, ১-এ ০, ২-এ ০, ৩-এ ৩, ৪-এ ১. প্রতি সেকেন্ডে কতটি যাবে, কতটিতে 429, আর শেষে কত token থাকবে? উত্তর দেখার আগে হাতে করুন, তারপর token_bucket.js-এ show('test', 3, 1, [5, 0, 0, 3, 1]) যোগ করে মেলান।
     0  want   5  ok   3  429   2  tokens left 0
     1  want   0  ok   0  429   0  tokens left 1
     2  want   0  ok   0  429   0  tokens left 2
     3  want   3  ok   3  429   0  tokens left 0
     4  want   1  ok   1  429   0  tokens left 0
    passed 7/9 (78%), refused 2

    সেকেন্ড ৩-এ ৩টিই গেছে, কারণ দুই সেকেন্ড চুপ থাকায় token জমে ৩ হয়েছিল। সেকেন্ড ৪-এর শুরুতে ১টি token যোগ হয়েছে, সেটিই খরচ হলো, তাই শেষে ০। বিরতি মানেই সঞ্চয়, তবে capacity পর্যন্তই।

  4. Header পড়ুন: নিজের কোনো সাইটের, অথবা যে সাইটে কাজ করেন তার একটি CSS বা ছবির URL নিন। curl -sI দু-তিনবার চালান। cache-control, age, etag আর CDN-এর hit header লিখে রাখুন। এবার একটি HTML পাতায় একই কাজ করুন। কী বদলাল? (Traffic বাড়ানোর পরীক্ষা অন্যের সাইটে করবেন না। ঐচ্ছিকভাবে আসল CDN চেষ্টা করলে খরচ হতে পারে, তাই budget alert রাখুন। শেষে distribution বন্ধ করে মুছুন, তারপর bucket আর certificate মুছুন।)

    সাধারণ ফল: CSS বা ছবিতে লম্বা max-age, আর বারবার চালালে age বাড়ে, Miss থেকে Hit হয়। HTML-এ ছোট আয়ু, no-cache বা private থাকে, আর লগইন-করা পাতায় cache হয় না। CSS-এ max-age=0 বা no-store দেখলে সেটি উন্নতির সুযোগ। লগইন-করা HTML-এ public দেখলে সেটি নিরাপত্তার প্রশ্ন, দ্রুত দলকে জানান। মনে রাখবেন, ব্যস্ত নয় এমন সাইটে কাছের edge-এ কপি না থাকাই স্বাভাবিক, তাই প্রথমে Miss স্বাভাবিক।

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

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

ক্রমনতুন WAF rule ছাড়ার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. Rule count মোডে বসানো আর log চালু করা
  2. কয়েক দিনের স্বাভাবিক traffic জমানো
  3. Log পড়ে false positive খুঁজে বের করা
  4. নির্দিষ্ট path-এ সরু ছাড় দিয়ে আবার count
  5. Block-এ নেওয়া, 403-এর alert আর ফেরার পথ রেখে

একটি CDN-এর hit ratio ৯৬% থেকে বেড়ে ৯৮% হলো, আর মোট অনুরোধ একই থাকল। Origin-এর অনুরোধের কী হবে?

  • ২% কমবে
  • অর্ধেক হবে
  • একই থাকবে
  • চার ভাগের এক ভাগ হবে

HTTP header Cache-Control: no-cache আসলে কী বোঝায়?

  • কোনো cache উত্তরটি জমাতে পারবে না
  • শুধু browser রাখবে, CDN নয়
  • জমানো যাবে, কিন্তু ব্যবহারের আগে origin-এর কাছে যাচাই করতে হবে
  • এক বছর যাচাই ছাড়া রাখা যাবে

একটি load balancer-এর firewall শুধু CDN provider-এর সব IP range-কে ঢুকতে দেয়। তবু কী ঝুঁকি থাকে?

  • একই provider-এর অন্য গ্রাহকের distribution-ও origin-এ পৌঁছাতে পারে
  • Edge-এর cache কাজ করবে না
  • TLS certificate অকেজো হয়ে যাবে
  • Hit ratio শূন্য হয়ে যাবে

নামে hash-সহ নতুন CSS ফাইল সহ একটি site প্রকাশ করবেন। কোন ক্রম নিরাপদ?

  • আগে HTML, তারপর CSS
  • আগে পুরোনো CSS মোছা, তারপর নতুন CSS আর HTML
  • সব upload করে /* invalidation
  • আগে নতুন CSS, তারপর HTML, তারপর শুধু HTML purge, পুরোনো CSS পরে সরানো

একটি সাইটের দামি search path-এ বৈধ-চেহারার HTTP অনুরোধের বন্যা এলো। Network-এর পথ ফাঁকা, কিন্তু database-এর CPU পুরো ব্যস্ত। এই চাপ কোন স্তরের, আর মূল প্রতিরক্ষা কী?

  • Volumetric, provider-এর network একাই শোষণ করবে
  • Protocol, SYN cookie-ই যথেষ্ট
  • Application (L7), WAF rule, rate limit আর cache
  • কোনো স্তর নয়, শুধু autoscaling-এর max বাড়ানো

WAF-এর একটি rule count মোডে চলছে। কোন কথাটি সত্য?

  • মিলে যাওয়া অনুরোধ আটকে 403 দেয়
  • অনুরোধ এগিয়ে যায়, মিল log হয়, তবে rule চলার খরচ থাকে
  • Rule মূল্যায়নই হয় না, তাই কোনো ঝুঁকি নেই
  • পরের সব rule বাদ পড়ে যায়

শব্দকোষ

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

মনে রাখুন

  1. Edge হলো প্রথম দরজা: TLS, WAF, rate limit, cache. যত আগে অনুরোধ শেষ হয়, তত ভালো।
  2. Origin-এর ভার = মোট × (1 − h). হিসাব করুন miss দিয়ে, আর অনুরোধ ও byte দুটো দিয়েই মাপুন।
  3. Hash-সহ নামে লম্বা TTL, HTML-এ ছোট। ক্রম: আগে asset, পরে HTML, পুরোনো ফাইল পরে সরানো।
  4. Origin আড়ালে রাখুন, certificate-এর নবায়নের শর্ত সচল রাখুন, আর WAF rule count থেকে block-এ নিন।
  5. DDoS-এ L3/L4 মূলত provider, L7 অনেকটাই আপনার। Autoscaling-এর max, alert আর runbook আগেই ঠিক করুন।

পরের পর্বে: Cloud networking মডিউল শেষ। এবার প্রশ্ন বদলাচ্ছে: packet কোথায় যাবে নয়, কে কী করতে পারবে। পর্ব ৩১-এ শুরু হবে Cloud IAM: identity, role, policy আর temporary credential.

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

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