Course-এর সূচি

11.2

Geo Restriction, Invalidation, VPC Origin আর Signed URL

দেশ ধরে allow/block list, cache খালি করা, VPC-র ভেতরে রাখা private origin, signed URL আর cookie, আর price class।

24 মিনিট পড়া + Animation

টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।

এই লেসন শেষে তুমি পারবে

  • CloudFront, Shield Standard, AWS WAF আর Shield Advanced মিলে edge-এ কীভাবে কয়েক স্তরের DDoS সুরক্ষা তৈরি করে, সেটা বোঝাতে, আর কোন আক্রমণ কোন স্তরে থামে, বলে দিতে।
  • পেছনের দরজা খোলা না রেখে ALB বা EC2 instance-কে origin বানাতে: CloudFront managed prefix list, গোপন origin header, আর private ALB, NLB ও EC2-র জন্য VPC origin।
  • Allow list বা block list দিয়ে geo restriction সাজাতে, কখন 403 আসবে আগেই বলতে, আর কখন তার বদলে AWS WAF বা edge function লাগবে, সেটা চিনতে।
  • Invalidation দিয়ে cache-এর content নতুন করতে, তার খরচ হিসাব করতে, আর ঘন ঘন বদলানো file-এর জন্য versioned file name বেছে নিতে।
  • CloudFront signed URL বা signed cookie দিয়ে private content দিতে, এ দুটোর মধ্যে আর canned ও custom policy-র মধ্যে বেছে নিতে, আর S3 pre-signed URL-এর সাথে তুলনা করতে।
  • Price class দিয়ে খরচ কমাতে, আর দর্শককে ভদ্র custom error page দেখাতে।

#CloudFront: ঢোকার একটাই দরজা

লেসন ১১.১-এ CloudFront-কে দেখেছি একটা cache হিসেবে: দর্শকের কাছে edge location, দূরে একটা origin, একটা cache key আর একটা TTL। এই লেসন বাকি সবকিছু নিয়ে, যা একটা distribution পারে, যখন সব traffic তার ভেতর দিয়েই যায়। প্রতিটা request যেহেতু আগে edge-এ পৌঁছায়, তাই আক্রমণ ছাঁকা, দর্শক কোথায় আছে দেখা, দর্শক টাকা দিয়েছে কি না যাচাই করা, আর কিছু বিকল হলে কী দেখাব ঠিক করা, এসবের স্বাভাবিক জায়গাই হলো ওই edge।

তবে এর সবকিছু কাজ করে শুধু তখনই, যখন edge-ই ঢোকার একমাত্র পথ। কেউ যদি সরাসরি পেছনের ALB বা bucket-এ request পাঠাতে পারে, তাহলে WAF rule, geo restriction বা signed URL কোনো কিছুই পাহারা দেয় না। তাই এই লেসনে বারবার একটাই প্রশ্ন ফিরে আসবে: কেউ কি CloudFront এড়িয়ে ঢুকতে পারে?

পুরো লেসনে উদাহরণ থাকবে ঢাকার একটা online দোকান, shop.example.com, যেটা চলে d111111abcdef8.cloudfront.net distribution দিয়ে, আর তার origin হলো ap-south-1-এর (মুম্বাই) একটা Application Load Balancer। সাথে থাকবে একটা streaming service, stream.example.com, যেটা দেশভিত্তিক অধিকার নিয়ে film বিক্রি করে।

#Edge-এ DDoS সুরক্ষা

DDoS (distributed denial of service) আক্রমণে হাজার হাজার machine থেকে একসাথে বন্যার মতো traffic পাঠিয়ে একটা service-কে অচল করে দেওয়ার চেষ্টা হয়। বন্যা মোটামুটি দুই রকম:

  • Network আর transport স্তরের বন্যা (layer ৩ আর ৪): SYN flood, UDP flood, reflection আক্রমণ। এরা bandwidth বা connection table ফুরিয়ে ফেলতে চায়, আর কখনোই বৈধ HTTP request হয়ে ওঠে না।
  • Application স্তরের বন্যা (layer ৭): আসল HTTP request, একটা একটা করে দেখলে প্রতিটাই বৈধ (সেকেন্ডে পঞ্চাশ হাজারবার GET /search), সাথে request-এর ভেতরে লুকানো নিশানা করা আক্রমণ, যেমন SQL injection।

কোনো একটা নিয়ন্ত্রণ দুটোকেই থামাতে পারে না, এজন্যই AWS origin-এর সামনে তিনটা স্তর পরপর বসায়।

#Shield Standard: বিনা পয়সায়, সবসময় চালু

AWS Shield Standard প্রত্যেক AWS customer-কে কোনো বাড়তি খরচ ছাড়াই রক্ষা করে, কিছু চালু করারও দরকার নেই। এটা layer ৩ আর ৪-এর চেনা আক্রমণগুলো ঠেকায়, যেমন SYN আর UDP flood আর reflection আক্রমণ। Notes বলছে এটা CloudFront-এর সাথে আসে; আরও ঠিক করে বললে, এটা সব AWS customer আর resource-এর জন্যই, তবে সবচেয়ে জোরালো edge service-গুলোতে, মানে CloudFront, Route 53 আর Global Accelerator-এ, কারণ সেখানে আক্রমণটা একটা Regional দরজায় না পড়ে শত শত location জুড়ে ছড়ানো AWS-এর ক্ষমতায় শুষে যায়।

Caching প্রায় কাজে না লাগলেও ALB-এর সামনে CloudFront বসানোর এটাই প্রথম কারণ: দোকানের দিকে তাক করা বন্যা আছড়ে পড়ে CloudFront-এর edge network-এ, আর মুম্বাইয়ের ALB শুধু পুরো হওয়া, ঠিকঠাক HTTP request-ই দেখে।

#AWS WAF: প্রতিটা HTTP request খুলে দেখা

AWS WAF (web application firewall) layer ৭ দেখে: প্রতিটা request-এর path, query string, header, cookie আর body। তুমি distribution-এর সাথে একটা web ACL (access control list) জুড়ে দাও; তাতে থাকে rule, যেগুলো মিলে যাওয়া request-কে Allow, Block বা Count করে (অথবা challenge করে):

  • চেনা আক্রমণের জন্য AWS managed rule group: SQL injection (SQLi), cross-site scripting (XSS), পরিচিত ক্ষতিকর input, খারাপ bot, আর anonymous IP list (VPN, proxy, hosting provider)।
  • Rate-based rule: কোনো source IP (বা অন্য কোনো key) একটা ছোট সময়ে তোমার বেঁধে দেওয়া সীমার বেশি request পাঠালে তাকে block করে। HTTP flood-এর বিরুদ্ধে এটাই অস্ত্র।
  • IP set, geo match (দেশ আর region), আর request-এর যেকোনো অংশে string বা regex মেলানো।

CloudFront-এর web ACL-এর scope global, আর সেটা চালাতে হয় us-east-1 থেকে, ঠিক CloudFront-এর ACM certificate-এর মতো। WAF শুধু CloudFront-এর জন্য না: লেসন ৬.২-এ ALB, API Gateway, AppSync, Cognito user pool, App Runner, Verified Access আর Amplify-এর তালিকা আছে, আর সেখানেই বলা আছে NLB বা Classic Load Balancer-এ এটা জোড়া যায় না। CloudFront-এ এটা চলে edge-এ, তাই block হওয়া request সাগর পেরিয়ে তোমার origin পর্যন্ত যায়ই না। খরচ দিতে হয় প্রতিটা web ACL, প্রতিটা rule আর প্রতি দশ লাখ request যাচাইয়ের জন্য।

#Shield Advanced: টাকা দিয়ে নেওয়া স্তর

যেসব প্রতিষ্ঠান কোনোভাবেই বন্ধ হয়ে যেতে পারে না, তাদের জন্য AWS Shield Advanced আরও সুরক্ষা যোগ করে:

  • তোমার বেছে নেওয়া protected resource: CloudFront distribution, Route 53 hosted zone, Global Accelerator accelerator, Application আর Classic Load Balancer, আর Elastic IP address (যেটা দিয়ে EC2 instance আর তার পেছনের NLB-ও ঢাকা পড়ে)।
  • প্রতিটা resource-এর স্বাভাবিক traffic বুঝে আরও ভালো ধরা আর থামানো, যার মধ্যে আছে automatic application layer DDoS mitigation, যেটা আক্রমণের সময় নিজেই WAF rule লিখে বসিয়ে দেয়।
  • Shield Response Team (SRT), দিনে-রাতে ২৪ ঘণ্টা পাওয়া যায় এমন AWS-এর DDoS বিশেষজ্ঞ দল। Notes একে DRT (DDoS Response Team) বলেছে, ওটা এর পুরোনো নাম। SRT-র সাথে যোগাযোগের জন্য Business বা Enterprise Support লাগে।
  • DDoS cost protection: protected resource-এর ওপর DDoS আক্রমণের কারণে scaling-এর খরচ বেড়ে গেলে (বেশি EC2 instance, বেশি CloudFront বা ALB ব্যবহার), আবেদন করলে AWS সেটা service credit হিসেবে ফেরত দেয়। Notes বলছে AWS “টাকা রিফান্ড করে দেয়”; আসলে এটা scaling-এর খরচের বিপরীতে তোমার AWS বিলে একটা credit, পুরো বিলের নগদ ফেরত না।
  • WAF ধরা আছে: protected resource-এর সাধারণ AWS WAF খরচ subscription-এর মধ্যেই।

দাম: প্রতি organisation মাসে $৩,০০০ (payer account-এ বিল হয়, তার সব account এতে ঢাকা পড়ে), এক বছরের চুক্তিতে, সাথে protected resource-এর data transfer out-এর usage fee। Notes-এর “মাসে প্রায় $৩,০০০” ঠিক আছে; লোকে যেটা ভুলে যায়, সেটা হলো চুক্তি আর বাড়তি usage fee।

Edge-এ তিন স্তরের পাহারা

ক্রেতা আর একটা botnet, দুজনেই একই CloudFront edge দিয়ে দোকানে ঢোকে। সেখানে Shield Standard network-এর বন্যা ছেঁকে ফেলে, WAF web ACL প্রতিটা HTTP request খুলে দেখে, আর শুধু পরিষ্কার request-গুলোই মুম্বাইয়ের ALB পর্যন্ত যায়।

পরিস্থিতি

একজন ক্রেতা একটা product page খুলল: প্রতিটা স্তর দেখে, কেউ আপত্তি করে না।

ap-south-1
ক্রেতারাআসল মানুষ
Botnetআক্রমণকারী
Edge locationShield Standard
AWS WAFweb ACL
ALBorigin
EC2দোকানের app
GET /products/42
ধাপ 1 / 5
1

ঢাকার একজন ক্রেতা shop.example.com/products/42 খুলল। DNS তাকে কাছের একটা CloudFront edge-এ পাঠায়, তাই TCP আর TLS handshake তার কাছেই শেষ হয়, মুম্বাইয়ে না।

#কোন আক্রমণ কোন স্তরে থামে

আক্রমণ বা প্রয়োজনস্তরকী থামায়
SYN flood, UDP flood, reflection৩ / ৪Shield Standard (ফ্রি), edge-এই শুষে নেয়
Request-এর ভেতরে SQL injection, cross-site scripting৭AWS WAF-এর managed rule group
HTTP flood: সেকেন্ডে অসংখ্য বৈধ request৭WAF rate-based rule, সাথে edge-এ caching
একটা IP range বা একটা দেশ আটকানো৭WAF-এর IP set বা geo match (পুরো দেশের জন্য CloudFront geo restriction-ও চলে)
বড়, জটিল আক্রমণ; বিশেষজ্ঞের সাহায্য দরকার৩–৭SRT সহ Shield Advanced
আক্রমণে scaling-এর কারণে হঠাৎ বড় বিল এড়ানো–Shield Advanced-এর DDoS cost protection
অনেক account-এর WAF আর Shield rule এক জায়গা থেকে–AWS Firewall Manager (chapter ২১)

#ALB বা EC2 যখন origin

S3 bucket origin-কে আটকানো হয় Origin Access Control দিয়ে (লেসন ১১.১): bucket private থাকে, শুধু distribution-ই পড়তে পারে। ALB বা EC2 origin-এর (custom origin) জন্য আলাদা উত্তর লাগে, আর সেই উত্তর দুই ঘরানার: origin public রাখো কিন্তু শুধু CloudFront যেন সেখানে পৌঁছাতে পারে, নয়তো origin-কে private করে দাও আর CloudFront-কে VPC-র ভেতরে ঢুকে পৌঁছাতে দাও।

#Public origin আর CloudFront prefix list

VPC origin আসার আগে CloudFront শুধু internet দিয়েই origin-এ পৌঁছাতে পারত, তাই origin-কে public হতেই হতো:

  • EC2 যখন origin: instance-এর একটা public IP লাগে, আর তার security group-কে CloudFront edge location-এর IP address-গুলোকে ঢুকতে দিতে হয়।
  • ALB যখন origin: ALB-কে internet-facing হতে হয়, আর তার security group edge location-গুলোকে ঢুকতে দেয়। পেছনের EC2 instance-গুলো private subnet-এ থাকতে পারে; তাদের security group শুধু ALB-এর security group-কে ঢুকতে দেয় (লেসন ৩.৫)।

“Edge location-গুলোকে ঢুকতে দেওয়া” মানে আগে ছিল ip-ranges.json থেকে (বা d7uri8nf7uskq.cloudfront.net/tools/list-cloudfront-ips-এর তালিকা থেকে) CloudFront-এর IP range কপি করে security group-এ বসানো, আর AWS নতুন range যোগ করলেই সেটা হালনাগাদ করা। এখন একটাই inbound rule-এ তুমি AWS managed prefix list com.amazonaws.global.cloudfront.origin-facing-এর নাম দিয়ে দাও (IPv6-এর জন্য com.amazonaws.global.ipv6.cloudfront.origin-facing)। AWS এটাকে হালনাগাদ রাখে, আর এতে ঠিক সেই address-গুলোই আছে, যেগুলো দিয়ে CloudFront origin-এর সাথে কথা বলে।

একটা হাতে-কলমে ঝামেলা: এই prefix list-এর weight ৫৫, মানে security group-এর default ৬০টা inbound rule-এর কোটা থেকে এটা একাই ৫৫টা খেয়ে নেয়। জায়গা রাখো, নয়তো কোটা বাড়ানোর আবেদন করো।

#ফাঁকটা: অন্য কারও distribution

Prefix list এলোমেলো scanner-কে আর সরাসরি ALB-তে আঘাত করা সবাইকে থামায়। কিন্তু CloudFront জানে এমন কাউকে থামায় না। একজন আক্রমণকারী নিজের account-এ একটা CloudFront distribution বানিয়ে origin হিসেবে তোমার ALB-এর DNS নাম দিতে পারে। তখন তার request তোমার ALB-তে আসে ঠিক সেই CloudFront origin-facing address থেকেই, যেগুলো তোমার distribution-ও ব্যবহার করে, আর security group তাকে ঢুকতে দেয়। তোমার WAF rule, geo restriction আর signed URL সব থাকে তোমার distribution-এ, তাই তার request এর একটাও পার হতে হয় না।

#সমাধান: গোপন header

AWS যেটা যোগ করতে বলে, সেটা একটা গোপন custom origin header:

  1. Distribution-এর origin setting-এ একটা custom header যোগ করো

    যেমন X-Origin-Verify, সাথে একটা লম্বা random মান। এই origin-এ পাঠানো প্রতিটা request-এ CloudFront এটা জুড়ে দেয়। দর্শক কখনো এটা দেখে না।

  2. ALB-কে দিয়ে এটা বাধ্যতামূলক করো

    একটা listener rule যোগ করো: X-Origin-Verify header-এ ঠিক ওই মান থাকলে target group-এ পাঠাও। Default rule বদলে একটা fixed 403 response করে দাও (লেসন ৬.৩)। Header ছাড়া request, আক্রমণকারীর নিজের distribution-এরটা সহ, 403 পায়।

  3. এটা গোপন রাখো

    CloudFront আর ALB-এর মাঝে HTTPS রাখো, যাতে কেউ মাঝপথে header-টা দেখে না ফেলে, মানটা একটা secret store-এ রাখো, আর মাঝে মাঝে বদলাও (নতুন header যোগ করো, কিছুদিন দুটোই মেনে নাও, তারপর পুরোনোটা সরাও)। Listener rule-এর বদলে ALB-এ বসানো একটা WAF web ACL-ও header-টা যাচাই করতে পারে।

Prefix list আর header একসাথে হলো public origin-এর সবচেয়ে মজবুত সাজ: prefix list network স্তরেই CloudFront ছাড়া সব traffic আটকায়, আর header layer ৭-এ অন্যের distribution আটকায়।

#VPC origin: private ALB, NLB বা EC2

২০২৪-এর নভেম্বর থেকে CloudFront VPC origin origin-কে public রাখার দরকারটাই সরিয়ে দিয়েছে। ALB (বা NLB, বা EC2 instance) বসে থাকে একটা private subnet-এ, কোনো public IP ছাড়া, আর CloudFront সেখানে private পথে পৌঁছায়:

  • তুমি resource-এর ARN দিয়ে একটা VPC origin বানাও। CloudFront ওই private subnet-এ নিজের পরিচালিত একটা network interface বসায় (subnet-এ একটা খালি IPv4 address লাগে), আর edge থেকে traffic পাঠায় AWS-এর network দিয়ে, কখনো public internet দিয়ে না।
  • Origin-এর security group inbound অনুমতি দেয় service-এর পরিচালিত security group CloudFront-VPCOrigins-Service-SG-কে (সবচেয়ে কড়া বিকল্প: শুধু তোমার distribution-গুলো), অথবা CloudFront prefix list-কে।
  • আক্রমণকারীর তাক করার মতো কিছু থাকে না: internal ALB-এর নাম শুধু private address-এ মেলে, আর তোমার account-এর VPC origin তার নিজের distribution ব্যবহার করতে পারে না। Public subnet লাগে না, বদলানোর মতো গোপন header-ও না।
  • VPC origin-এর জন্য বাড়তি কোনো খরচ নেই; CloudFront-এর সাধারণ দামই দাও।

যে খুঁটিনাটিগুলোতে লোকে আটকায়:

  • VPC-তে একটা internet gateway জোড়া থাকতেই হবে, যদিও এই traffic route করতে সেটা ব্যবহার হয় না; AWS এটা দিয়ে বোঝে যে এই VPC internet থেকে traffic নিতে রাজি।
  • সমর্থিত origin হলো ALB, NLB আর EC2। Gateway Load Balancer হতে পারে না, NLB-তে security group থাকতে হবে, আর TLS listener থাকা NLB চলে না।
  • VPC origin-এ gRPC traffic বা Lambda@Edge-এর origin request আর origin response trigger চলে না, আর এই traffic-এর জন্য network ACL-এর inbound rule দেখা হয় না (ফেরার পথের জন্য outbound rule দেখা হয়)।
  • AWS Resource Access Manager দিয়ে একটা VPC origin অন্য account-এর সাথে ভাগ করা যায়।

Notes-এ শুধু ALB আর EC2-র কথা আছে; slide NLB-ও যোগ করেছে, আর slide-টাই ঠিক: VPC origin তিনটাকেই সমর্থন করে।

#Origin কীভাবে আটকাবে, বেছে নেওয়া

Public ALB, prefix listPublic ALB, prefix list + গোপন headerVPC origin (private ALB, NLB, EC2)OAC সহ S3
Internet থেকে origin-এ পৌঁছানো যায়শুধু CloudFront-এর address থেকেশুধু CloudFront-এর address থেকেনানা (private bucket)
অন্য account-এর distribution এটা ব্যবহার করতে পারেহ্যাঁনা (403)নানা
রক্ষণাবেক্ষণRule-এর weight ৫৫Header বদলানোকিছু নাBucket policy
পরীক্ষার keyword“শুধু CloudFront IP-কে ঢুকতে দাও”“সরাসরি ঢোকা আটকাও, custom header”“private subnet, internet-এ খোলা না”“bucket private রাখো”

কেউ কি CloudFront এড়িয়ে ঢুকতে পারে?

দোকানের WAF, geo restriction আর cache, সব আছে তার নিজের distribution-এ। আক্রমণকারী অন্য কোনো পথে ALB-তে পৌঁছাতে পারলে এগুলো সবই এড়িয়ে যায়। একটা public ALB, CloudFront prefix list দেওয়া security group, একটা গোপন header আর একটা VPC origin পাশাপাশি দেখো।

পরিস্থিতি

ALB-এর security group 443-এ 0.0.0.0/0 খুলে রেখেছে: CloudFront কাজ করে, কিন্তু পেছনের দরজাও খোলা।

ap-south-1
VPC10.0.0.0/16
Public subnet
Private subnet
ক্রেতা
তোমার distributionWAF + geo
আক্রমণকারী198.51.100.23
ALBshop-alb
EC210.0.2.15
GET /cart
ধাপ 1 / 3
1

স্বাভাবিক পথ: ক্রেতা distribution-এ পৌঁছায়, সেটা WAF আর geo rule যাচাই করে, তারপর cache miss হলে ALB-এর public DNS নামে পাঠায়। EC2 instance ALB-এর পেছনে একটা private subnet-এ বসা।

#Geo restriction

#Allow list আর block list

Geo restriction (geoblocking) দিয়ে একটা distribution দেশ দেখে দর্শককে ফিরিয়ে দিতে পারে:

  • Allow list: শুধু তালিকার দেশগুলোর দর্শককে দাও।
  • Block list: তালিকার দেশগুলো ছাড়া বাকি সবাইকে দাও।

একটা distribution এর যেকোনো একটা নেয়। ফিরিয়ে দেওয়া দর্শক edge থেকেই সরাসরি HTTP 403 Forbidden পায়, origin জড়ায়ই না। 403-এর জন্য একটা custom error response রাখলে “এই film তোমার দেশে পাওয়া যায় না” ধরনের page দেখানো যায়; CloudFront default-এ সেই error ১০ সেকেন্ড cache করে।

দুটো সীমা প্রতিটা design-কে প্রভাবিত করে:

  • এটা কাজ করে শুধু দেশের স্তরে।
  • এটা খাটে পুরো distribution-এ। Trailer সব জায়গায় চলবে কিন্তু film শুধু কিছু দেশে, এমন হলে দুটো distribution লাগবে, নয়তো AWS WAF, যার rule একটা path ধরে বসানো যায়।

#CloudFront দেশ ঠিক করে কীভাবে

CloudFront দর্শকের IP address একটা third-party geolocation database-এ খুঁজে দেখে। AWS-এর হিসাবে মোট নির্ভুলতা প্রায় ৯৯.৮%, দেশভেদে কমবেশি। এর দুটো ফল:

  • VPN এটাকে হারিয়ে দেয়। ঢাকার একজন দর্শক US-এর একটা VPN server দিয়ে এলে তার address দেখায় আমেরিকান, আর সে শুধু-US allow list পার হয়ে যায়। চুক্তিতে আরও কড়াকড়ি চাইলে WAF-এর managed anonymous IP list rule group যোগ করো (পরিচিত VPN, proxy আর hosting provider), আর signed URL দেওয়ার আগে app-এ account-এর billing দেশ যাচাই করো।
  • অজানা address-কে দিয়ে দেওয়া হয়। CloudFront অবস্থান বের করতে না পারলে allow list থাকলেও request-টা দিয়ে দেয়। Geo restriction license মানার হাতিয়ার, একা access control না।

কিছু আটকানো ছাড়াই CloudFront অবস্থানটা origin-কে জানিয়েও দিতে পারে: origin request policy দিয়ে CloudFront-Viewer-Country-র মতো header যোগ করো (বা CloudFront-Viewer-City, CloudFront-Viewer-Country-Region), তাহলে app দাম টাকায় না ডলারে দেখাবে, ঠিক করতে পারে।

#দেশের চেয়ে সূক্ষ্ম: AWS WAF আর edge function

Notes বলছে: দেশের বদলে একটা শহর বা একটা IP address আটকাতে হলে AWS WAF। এর অর্ধেক ঠিক:

  • IP address আর range → WAF-এর IP set rule। ঠিক।
  • দেশের ভেতরের region (US-এর একটা state, বাংলাদেশের একটা বিভাগ) → WAF-এর geo match statement, যেটা প্রতিটা request-এ তার দেশ আর ISO 3166-2 region-এর label লাগায়, যেমন US-TX; তারপর একটা label match rule সেটা block বা allow করে।
  • শহর → WAF না: WAF geo match শহর পর্যন্ত নামে না। এমন একটা edge function ব্যবহার করো, যেটা CloudFront-Viewer-City header পড়ে (লেসন ১১.৩), নয়তো app-এ একটা third-party geolocation service, যেটা শুধু অনুমতি থাকা দর্শককেই signed URL দেয়।

আরেকটা যোগসূত্র: CloudFront geo restriction যে request ফিরিয়ে দেয়, সেটা কখনো WAF-এ যায় না (অনুমতি পাওয়াগুলো যায়)। ভৌগোলিক শর্তের সাথে অন্য শর্ত মেলাতে চাইলে, বা WAF দিয়ে ওই request-গুলো গুনতে আর log করতে চাইলে, geo restriction-এর বদলে WAF-এর geo match statement ব্যবহার করো।

Edge-এ geo restriction

একটা streaming service কোনো film শুধু সেখানেই দেখাতে পারে, যেখানে তার অধিকার আছে। Edge প্রত্যেক দর্শকের IP address একটা geolocation database-এ খুঁজে দেখে, তারপর হয় request-টা দেয়, নয়তো 403 দেয়।

পরিস্থিতি

একটা আমেরিকান studio একটা film শুধু US-র জন্য license দিয়েছে (notes-এর copyright উদাহরণ)।

us-east-1
দর্শক, US203.0.113.10
দর্শক, ঢাকা192.0.2.44
VPN serverUS-তে
Edge locationgeo lookupallow: US
Film-এর fileS3 + OAC
ধাপ 1 / 5
1

Distribution-এর geo restriction একটা allow list, তাতে একটাই দেশ: US। Distribution-এর প্রতিটা file-এ এটা খাটে।

নিজেকে যাচাই করোপ্রশ্ন

একটা কোম্পানি CloudFront geo restriction দিয়ে পাঁচটা দেশ block করে, আবার AWS WAF-ও ব্যবহার করে। Security দল চায় WAF-এর log আর metric-এ ওই দেশগুলো থেকে আসা প্রতিটা request দেখা যাক, আর তার একটা দেশের এক partner-এর IP range ঢুকতে পাক। Architect কী করবে?

#Cache invalidation

#User-রা কেন পুরোনো file দেখে

Notes-এর উদাহরণ: দোকানের অফারের banner, /images/banner.jpg, edge-গুলোতে cache করা আছে। Origin কোনো Cache-Control না পাঠালে আর default cache setting থাকলে CloudFront এটা রাখে default TTL ২৪ ঘণ্টা (৮৬,৪০০ সেকেন্ড) পর্যন্ত। সকাল ১০টায় marketing একই নামে নতুন banner S3-এ upload করল। ক্রেতারা তবুও পুরোনো অফার দেখতে থাকে, কারণ edge-এর কাছে মেয়াদ থাকা একটা কপি আছে, আর origin বদলেছে, এ খবর CloudFront-কে কেউ দেয় না। Origin নিজে থেকে পরিবর্তন ঠেলে পাঠায় না; TTL শেষ হলে তবেই edge আবার ফিরে যায়।

(Notes বলছে CloudFront “ক্যাশ করে রেখেছে, যাকে বলা হয় TTL”। Cache হলো রেখে দেওয়া কপিটা; TTL হলো কপিটা কতক্ষণ টাটকা ধরা হবে, সেই সময়।)

#Path invalidate করা

Invalidation CloudFront-কে বলে TTL শেষ হওয়ার আগেই প্রতিটা edge cache থেকে object সরিয়ে ফেলতে। এরপর সেগুলোর জন্য পরের request হয় miss, আর edge origin থেকে বর্তমান version নিয়ে আসে।

aws cloudfront create-invalidation --distribution-id E1ABCDEXAMPLE \
  --paths "/images/banner.jpg" "/index.html"

একটা path-এর নিয়ম:

  • Path লেখা হয় distribution-এর হিসাবে, শুরু হয় / দিয়ে: /images/banner.jpg, পুরো URL না।
  • * wildcard হিসেবে কাজ করে শুধু শেষ অক্ষর হলে: /images/* (folder-এর নিচের সবকিছু), /images/banner* (banner দিয়ে শুরু হওয়া সব নাম), /* (পুরো distribution)। Command line-এ এটা উদ্ধৃতিচিহ্নের মধ্যে রাখো।
  • Path-এ বড়-ছোট হাতের অক্ষর আলাদা: /images/Banner.jpg আরেকটা file।
  • Query string cache key-র অংশ হলে প্রতিটা রূপ আলাদা cache-এর object; /images/banner.jpg* সবগুলোকে ধরে।

একটা invalidation প্রথমে InProgress, তারপর Completed দেখায়, পুরো network-এ সাধারণত কয়েক সেকেন্ড থেকে কয়েক মিনিট লাগে। এটা শুধু মোছে; নতুন file আগে থেকে এনে রাখে না।

#Invalidation-এর খরচ

Notes ঠিকই বলেছে, একটা ফ্রি পরিমাণের পর টাকা লাগে। আসল নিয়ম:

  • মাসে প্রথম ১,০০০টা invalidation path ফ্রি, প্রতি AWS account ধরে, তার সব distribution মিলিয়ে।
  • এরপর প্রতিটা path $০.০০৫।
  • এক request-এ কয়েকটা path দিলেও প্রতিটা আলাদা করে গোনা হয়। Wildcard থাকা path যতগুলো file-ই ধরুক, গোনা হয় একটা path হিসেবে।

ধরো তিনটা distribution প্রতিদিন ৫০টা করে path invalidate করে, ৩০ দিন ধরে: মোট ৪,৫০০ path। ফ্রি পরিমাণের ওপরে ৩,৫০০টা, তাই ৩,৫০০ × $০.০০৫ = মাসে $১৭.৫০। একই দল প্রতি deploy-এ একবার /assets/* invalidate করলে কিছুই দিতে হতো না।

#Versioned file name: ভালো অভ্যাস

একটা file-কে জায়গায় বসে না বদলে প্রতিটা version-কে একটা নতুন নাম দাও: banner-v2.jpg, বা app.3f9a1c.js-এর মতো content-এর hash, যেটা build tool নিজেই বসিয়ে দেয়। HTML page নতুন নামটা দেখায়, আর শুধু HTML-টাই বদলাতে হয় (ছোট TTL দিয়ে, বা একটা path invalidate করে)। ঘন ঘন বদলানো file-এর জন্য AWS এটাই করতে বলে, কারণ:

  • নতুন নাম মানে নতুন cache key, তাই প্রতিটা edge আর প্রতিটা browser সাথে সাথে সেটা আনে। Invalidation browser cache বা অফিসের proxy পর্যন্ত পৌঁছায় না; নতুন নাম এগুলোকে পাশ কাটিয়ে যায়।
  • কোনো invalidation fee লাগে না, আর versioned file-এর TTL এক বছরও রাখা যায়।
  • আগের অবস্থায় ফেরা মানে HTML-কে পুরোনো নামের দিকে দেখানো, যেটা এখনো cache-এ আছে।
  • Log-এ পরিষ্কার দেখা যায় কোন দর্শক কোন version পেয়েছে।

Notes এটাকে বলেছে “Object Versioning”। আসলে বোঝানো হয়েছে versioned file name; S3-এর object versioning (version ID, লেসন ১০.৪) আলাদা একটা feature, এখানে কাজে লাগে না, কারণ CloudFront তখনো একই key চায়।

#Invalidation-এর ফাঁদ

  • ভিড়ের সময় /* invalidate করা। এটা একটাই ফ্রি path, কিন্তু প্রতিটা edge-এর প্রতিটা object একসাথে miss হয়ে যায়। Edge-গুলো যদি সেকেন্ডে ২০,০০০ request-এর ৯৫% cache থেকে দিত, তাহলে origin হঠাৎ ১,০০০-এর বদলে ২০,০০০ পর্যন্ত দেখে। সরু path, Origin Shield (লেসন ১১.১), বা versioned নাম বেছে নাও।
  • Browser-এর কথা ভুলে যাওয়া। File-এ এক দিনের Cache-Control: max-age থাকলে ফিরে আসা দর্শক এক দিন পর্যন্ত পুরোনো কপিই রাখে, তুমি যা-ই invalidate করো।
  • গতির সীমা। CloudFront প্রতি account-এ সেকেন্ডে ১৫০টা পর্যন্ত path (বা tag) আর সেকেন্ডে একটা wildcard invalidation সামলায়; খুব বড় invalidation-এ সময় লাগে।
  • Rewrite-এর পরের path। কোনো edge function URI বদলে দিলে আসল আর বদলানো, দুটো path-ই invalidate করো।

Cache-এ থাকা file বদলানো: অপেক্ষা, invalidate, নাকি নতুন নাম

দোকানটা /images/banner.jpg ২৪ ঘণ্টার জন্য cache করে (default TTL ৮৬,৪০০ সেকেন্ড)। সকাল ১০টায় marketing একই নামে নতুন ঈদের banner upload করল। S3 origin, edge cache, এক ক্রেতার browser cache আর সে আসলে কী দেখছে, ধাপে ধাপে দেখো।

পরিস্থিতি

কিছুই না করলে: TTL শেষ না হওয়া পর্যন্ত edge পুরোনো banner রেখে দেয়।

S3 origin

banner.jpg = পুরোনো

Edge cache

পুরোনো banner, TTL ২৪ ঘণ্টা

Browser cache

cache-এ কিছু নেই

ক্রেতা দেখছে

পুরোনো banner: ২০% ছাড়

সময়

দিন ১, সকাল ৮টা

Invalidation

নেই

এই মাসের path

0

Origin-এর চাপ

স্বাভাবিক

Invalidation-এর খরচের হিসাব

প্রতি AWS account-এ (সব distribution মিলিয়ে) মাসে প্রথম ১,০০০টা invalidation path ফ্রি; এরপর প্রতিটা path $০.০০৫। * wildcard থাকা path যতগুলো file-ই ধরুক, গোনা হয় একটা হিসেবে।

Cache কীভাবে নতুন করো

জমা দেওয়া path

2,400

ফ্রি সীমা

1,000

যে path-এর টাকা লাগবে

1,400

মাসের invalidation খরচ

$7.00

Wildcard সস্তা, কিন্তু প্রতিটা edge-এ পুরো folder খালি করে দেয়; versioned নামে কোনো খরচ নেই আর কখনো পুরোনো file যায় না, এজন্যই ঘন ঘন বদলানো file-এর জন্য AWS এটাই করতে বলে।

ধাপ 1 / 4
1

দিনের প্রথম ক্রেতা banner.jpg চাইল। Cache miss: edge সেটা S3 থেকে এনে ২৪ ঘণ্টার জন্য রেখে দিল।

#দর্শকের প্রবেশ সীমিত করা

OAC bucket-কে private করে, কিন্তু distribution নিজে তখনো public: URL যার কাছে আছে, সে-ই film দেখতে পারে। টাকা দিয়ে দেখার বা private content-এর জন্য একটা cache behavior দর্শকের প্রবেশ সীমিত করতে পারে (Restrict viewer access): তখন CloudFront তার file শুধু বৈধ signed URL বা signed cookie থাকা request-কেই দেয়। কে পাবে, সেটা ঠিক করে তোমার application (login, subscription, কেনা), আর সে-ই sign করে; CloudFront edge-এ শুধু signature যাচাই করে।

যাচাইটা যেহেতু cache behavior ধরে হয়, একটা distribution-এ public path (/trailers/*) আর private path (/films/*) মেশানো যায়। Behavior-গুলোর ক্রম সাবধানে ঠিক করো: একটা request সেই প্রথম behavior-টাই নেয়, যার path pattern মেলে।

#Key group: কে sign করতে পারে

Sign করতে লাগে একটা public–private key pair, RSA ২০৪৮-bit বা ECDSA ২৫৬-bit:

  • Private key থাকে তোমার application-এর কাছে (একটা secret store-এ), সে এটা দিয়ে sign করে।
  • Public key CloudFront-এ upload করা হয় আর একটা trusted key group-এ রাখা হয়, যেটা তুমি cache behavior-এর সাথে জুড়ে দাও। প্রতিটা edge এটা দিয়ে signature যাচাই করে।

Trusted key group-ই ব্যবহার করো। পুরোনো বিকল্প, মানে AWS account-এর CloudFront key pair, বানাতে হয় root user দিয়ে, API বা IAM দিয়ে চালানো যায় না, আর account-এ একসাথে মাত্র দুটো চালু key pair রাখা যায়। একটা key group-এ পাঁচটা পর্যন্ত public key থাকে, আর একটা cache behavior চারটা পর্যন্ত key group বিশ্বাস করতে পারে, তাই এখনো চালু URL না ভেঙেই key বদলানো যায়: নতুন key যোগ করো, সেটা দিয়ে sign করো, আর পুরোনো key-র শেষ URL-এর মেয়াদ ফুরোলে সেটা সরাও।

#Canned আর custom policy

প্রতিটা signed URL বা cookie-র সাথে একটা policy থাকে, যেটা বলে সে কী কী অনুমতি দেয়:

Canned policyCustom policy
Resourceঠিক একটা URLএকটা URL, বা * সহ একটা pattern (/films/7/*)
কতক্ষণ চলবেহ্যাঁ (Expires)হ্যাঁ
কখন থেকে চলবে (শুরুর সময়)নাহ্যাঁ
দর্শকের IP address বা rangeনাহ্যাঁ
আকারছোট URLলম্বা (policy নিজেই base64 করে ভেতরে থাকে)
Signed URL নাও, যখনSigned cookie নাও, যখন
প্রবেশ একটা file-এ: একটা installer, প্রিন্ট করার একটা ticket, একটা film-এর offline কপিপ্রবেশ অনেক file-এ: একটা HLS video-র সব segment, শুধু সদস্যদের একটা অংশ
Client cookie বোঝে না (custom HTTP client, কিছু player)Page-গুলো এখন যে URL ব্যবহার করে, সেগুলো বদলাতে চাও না

Signed URL-এ যোগ হয় query parameter Expires (custom policy হলে Policy), Signature আর Key-Pair-Id। Signed cookie একই তিনটা মান রাখে cookie হিসেবে: CloudFront-Expires বা CloudFront-Policy, CloudFront-Signature আর CloudFront-Key-Pair-Id। একটা request-এ দুটোই থাকলে signed URL-ই জেতে।

মনে রেখো, signed URL একটা bearer token: যার হাতে থাকবে, মেয়াদ থাকা পর্যন্ত সে-ই চালাতে পারবে। মেয়াদ ছোট রাখো, মানালে দর্শকের IP সহ custom policy দাও, আর origin private রাখো (S3-এর জন্য OAC, ALB-এর জন্য VPC origin বা গোপন header), নইলে লোকে সোজা CloudFront এড়িয়ে চলে যাবে।

Signed URL আর signed cookie

stream.example.com-এ শুধু টাকা দেওয়া সদস্যরাই film দেখতে পারে। App একটা private key দিয়ে অনুমতিতে sign করে; প্রতিটা CloudFront edge একটা trusted key group-এর মিলে যাওয়া public key দিয়ে signature যাচাই করে। Bucket নিজে OAC-র আড়ালে private থাকে।

পরিস্থিতি

একজন সদস্য একটা file নামাচ্ছে, একটা film-এর offline কপি।

দর্শক
Appprivate key তার কাছে
CloudFront edgepublic key
S3private, OAC
login, “film ৭ নামাও”
ধাপ 1 / 7
1

সদস্য login করে একটা film নামাতে চাইল। সদস্য কে, CloudFront তা জানে না; কে কী পাবে, সেটা app ঠিক করে।

#CloudFront signed URL বনাম S3 pre-signed URL

লেসন ১০.৯-এ S3 pre-signed URL দেখেছি। দুটোই private content-এ সাময়িক প্রবেশ দেয়, কিন্তু কাজ করে একেবারে আলাদাভাবে:

CloudFront signed URL বা cookieS3 pre-signed URL
কী দিয়ে signতোমার নিজের key pair (key group)যে sign করছে তার IAM credential (SigV4)
কার হয়ে কাজ করেCloudFront যে অনুমতি যাচাই করেযে IAM principal sign করেছে
কোথায় যায়একটা CloudFront edge, তারপর যেকোনো origin (S3, ALB, EC2, custom)সরাসরি S3-এ, একটা Region-এ
Caching আর global গতিহ্যাঁ, edge-এনা
কী কী বাঁধা যায়Path বা path pattern, শুরু, মেয়াদ, IP rangeএকটা object, একটা operation, মেয়াদ
মেয়াদতুমি যতক্ষণ চাও৭ দিন পর্যন্ত, temporary credential হলে আরও কম
Uploadমূলত downloadGET আর PUT (upload)

পরীক্ষার নিয়ম: CloudFront দিয়ে সারা বিশ্বে দেওয়া private content → CloudFront signed URL বা cookie (bucket-এ OAC সহ)। একটা S3 object-এর সাময়িক link, বিশেষ করে upload → S3 pre-signed URL।

#Price class

Edge কোথায়, তার ওপর CloudFront-এর দাম আলাদা হয়। একটা price class ঠিক করে কোন edge location-গুলো তোমার distribution চালাবে:

Price classকোন edge location ব্যবহার হয়
Price Class All (default)সব edge location, দক্ষিণ আমেরিকা আর অস্ট্রেলিয়া-নিউজিল্যান্ডসহ: সবচেয়ে ভালো গতি
Price Class 200উত্তর আমেরিকা, ইউরোপ, ইসরায়েল আর তুরস্ক, আফ্রিকা আর মধ্যপ্রাচ্য, জাপান, ভারত আর এশিয়ার বেশিরভাগ; সবচেয়ে দামি location (দক্ষিণ আমেরিকা, অস্ট্রেলিয়া-নিউজিল্যান্ড) বাদ
Price Class 100শুধু সবচেয়ে সস্তাগুলো: যুক্তরাষ্ট্র, কানাডা, মেক্সিকো, ইউরোপ, ইসরায়েল আর তুরস্ক

Price class কাউকে আটকায় না। অন্তর্ভুক্ত এলাকার বাইরের দর্শককেও দেওয়া হয়, তবে দূরের একটা অন্তর্ভুক্ত edge থেকে, বেশি latency নিয়ে। ঢাকার দোকানের জন্য Price Class 200 ক্রেতাদের কাছে ভারতের edge রাখে; Price Class 100 তাদের পাঠাত ইউরোপে। প্রায় সব দর্শক উত্তর আমেরিকা আর ইউরোপে হলে, আর বাকিদের চেয়ে খরচটাই বেশি জরুরি হলে Price Class 100 নাও।

#Custom error page

Origin error দিলে, বা CloudFront কোনো request ফিরিয়ে দিলে, দর্শক সাধারণত একটা খালি error দেখে। প্রতিটা status code-এর জন্য একটা custom error response (403, 404, 500, 502, 503, 504 আর বাকি 4xx আর 5xx code) দিয়ে তুমি পারো:

  • নিজের page দিতে, যেমন /errors/503.html, যেটা রাখা আছে বিকল origin ছাড়া অন্য কোনো origin-এ (/errors/*-এর জন্য নিজস্ব cache behavior সহ একটা S3 bucket)।
  • দর্শক যে status code পায়, সেটা বদলাতে। চেনা উদাহরণ হলো OAC সহ S3-এ রাখা একটা single-page application: /orders/42-এর মতো route কোনো object না, S3 403 বা 404 দেয়, আর একটা custom error response 200 সহ /index.html ফেরত দেয়, যাতে app-এর router page-টা দেখাতে পারে (লেসন ১০.৩-এ S3-এর error document দিয়ে একই কাজ করা হয়েছিল)।
  • Error caching minimum TTL ঠিক করতে: আবার origin-কে জিজ্ঞেস করার আগে CloudFront error-টা কতক্ষণ cache করবে। Default ১০ সেকেন্ড। বেশি লম্বা হলে origin ঠিক হওয়ার পরেও দর্শক error দেখতে থাকে; বেশি ছোট হলে বিকল origin-এর ওপর হাতুড়ি পড়তে থাকে।

Custom error page হলো ভদ্র শেষ ভরসা, availability না। সত্যিকারের failover-এর জন্য একটা origin group ব্যবহার করো (লেসন ১১.১), আর পুরো site বন্ধ হলে Route 53 failover (লেসন ৮.৩)।

#কোথায় গোলমাল হয়

লক্ষণসম্ভাব্য কারণসমাধান
Upload-এর পরেও user-রা পুরোনো file দেখছেTTL শেষ হয়নি, CloudFront-কে জানানো হয়নিPath invalidate করো, নয়তো versioned file name-এ যাও
Invalidation-এর পরেও একজন user পুরোনো file দেখছেBrowser cache (max-age) বা অফিসের proxyVersioned নাম; জায়গায় বসে বদলানো file-এর জন্য ছোট max-age
Deploy-এর ঠিক পরে origin-এ অতিরিক্ত চাপভিড়ের সময় /* invalidate, সব object missসরু path, Origin Shield, versioned নাম
Invalidation-এর বিল আসছেAccount-এ মাসে ১,০০০-এর বেশি pathপুরো folder-এর জন্য wildcard, versioned নাম
কিছু traffic WAF rule মানছে নাOrigin-এ সরাসরি, বা অন্য distribution দিয়ে পৌঁছানো যায়Prefix list + গোপন header, নয়তো VPC origin
Security group prefix list-এর rule নিচ্ছে নাPrefix list-এর weight ৫৫, কোটা ৬০টা ruleRule কমাও বা কোটা বাড়াও
VPC origin বানানো যাচ্ছে না বা পৌঁছানো যাচ্ছে নাVPC-তে internet gateway নেই, subnet-এ খালি IP নেই, NLB-তে security group নেই বা TLS listener আছেInternet gateway জোড়ো, address খালি করো, NLB ঠিক করো
অনুমতি থাকা দেশের দর্শক 403 পাচ্ছেGeolocation তাদের address অন্য দেশে দেখাচ্ছে, বা WAF আটকাচ্ছেWAF log, geolocation আর allow list দেখো
Block করা দেশের দর্শক ঢুকে যাচ্ছেVPN, বা অজানা অবস্থানের addressWAF anonymous IP list, app-এর দিকে যাচাই, signed URL
Key group যোগ করার পর সবাই 403 পাচ্ছেBehavior এখন signature চায়, আর app এখনো sign করছে নাআগে sign চালু করো, তারপর restrict করো, বা আলাদা path restrict করো
Signed URL এক জায়গায় চলে, পরে বন্ধুর কাছে 403মেয়াদ শেষ, বা custom policy IP বেঁধে দিয়েছেনতুন URL দাও; এটাই তো চাওয়া হয়েছিল
Origin ঠিক হওয়ার পরেও error page থেকে যাচ্ছেError caching minimum TTL বেশি লম্বাকমাও (default ১০ সেকেন্ড)

#System design-এ CloudFront-এর feature

  • একটাই মজবুত প্রবেশপথ। সবকিছুর সামনে WAF আর Shield সহ CloudFront (OAC সহ S3, VPC origin হিসেবে ALB), Route 53-এর alias record distribution-এর দিকে। প্রতিটা request একই যাচাই পার হয়, আর origin-গুলো কোথাও public না। AWS-এ একটা public web application-এর এটাই স্বাভাবিক উত্তর।
  • অধিকার মেনে media দেওয়া। License-এর জন্য geo restriction (বা WAF geo match), টাকা দেওয়া সদস্যদের জন্য signed cookie, bucket-এ OAC। VPN-এর দর্শক নিয়ে মাথাব্যথা থাকলে WAF anonymous IP list যোগ করো।
  • Deployment pipeline। Asset-এর জন্য hash সহ file name আর এক বছরের TTL, HTML-এর জন্য ছোট TTL, আর প্রতি release-এ শুধু /index.html invalidate। Release হয় সাথে সাথে, প্রায় বিনা খরচে।
  • খরচ নিয়ন্ত্রণ। দর্শকের সাথে মিলিয়ে price class, origin traffic কমাতে caching, আর Shield Advanced শুধু সেখানে, যেখানে বড় একটা DDoS বা তার বিল সত্যিই ক্ষতি করবে।
  • ভদ্রভাবে ব্যর্থ হওয়া। আলাদা S3 origin থেকে custom error page, failover-এর জন্য origin group, আর ছোট error caching TTL, যাতে ঠিক হওয়াটা তাড়াতাড়ি দেখা যায়।
  • যখন CloudFront ঠিক হাতিয়ার না। UDP game-এর মতো HTTP ছাড়া traffic-এর জন্য, বা client-দের স্থির IP address লাগলে, Global Accelerator নাও (লেসন ১১.৪), যার edge-এও Shield-এর সুরক্ষা আছে।

#নিজে করে দেখো

AWS CLI আর E1ABCDEXAMPLE distribution (d111111abcdef8.cloudfront.net) দিয়ে:

# 1. Is it cached? Look at x-cache (Hit / Miss / RefreshHit from cloudfront), age and x-amz-cf-pop
curl -sI https://d111111abcdef8.cloudfront.net/images/banner.jpg | grep -iE 'x-cache|age|x-amz-cf-pop|cache-control'

# 2. Invalidate one file and a folder, then watch the status
aws cloudfront create-invalidation --distribution-id E1ABCDEXAMPLE \
  --paths "/images/banner.jpg" "/assets/*"
aws cloudfront list-invalidations --distribution-id E1ABCDEXAMPLE
aws cloudfront get-invalidation --distribution-id E1ABCDEXAMPLE --id I2J3K4EXAMPLE

# 3. Geo restriction and price class live in the distribution config
aws cloudfront get-distribution-config --id E1ABCDEXAMPLE > dist.json
#   edit .DistributionConfig.Restrictions.GeoRestriction:
#     {"RestrictionType": "whitelist", "Quantity": 1, "Items": ["US"]}
#   and .DistributionConfig.PriceClass: "PriceClass_200"
aws cloudfront update-distribution --id E1ABCDEXAMPLE \
  --if-match <ETag from get-distribution-config> --distribution-config file://config-only.json

# 4. The CloudFront managed prefix list for the ALB's security group (weight 55)
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-EXAMPLE}]'

# 5. Test the secret-header rule: direct to the ALB without the header should give 403
curl -sI https://shop-alb-123456789.ap-south-1.elb.amazonaws.com/ | head -1

# 6. A VPC origin for a private ALB
aws cloudfront create-vpc-origin --vpc-origin-endpoint-config \
  'Name=shop-private-alb,Arn=arn:aws:elasticloadbalancing:ap-south-1:111122223333:loadbalancer/app/shop-int/0123456789abcdef,HTTPPort=80,HTTPSPort=443,OriginProtocolPolicy=https-only'

# 7. Signed URLs: upload a public key, make a key group, then sign
openssl genrsa -out private_key.pem 2048
openssl rsa -pubout -in private_key.pem -out public_key.pem
aws cloudfront create-public-key --public-key-config \
  "CallerReference=$(date +%s),Name=stream-key-1,EncodedKey=$(cat public_key.pem)"
aws cloudfront create-key-group --key-group-config 'Name=stream-signers,Items=K2JCJMDEHXQW5F'
aws cloudfront sign --url https://d111111abcdef8.cloudfront.net/films/film7.mp4 \
  --key-pair-id K2JCJMDEHXQW5F --private-key file://private_key.pem \
  --date-less-than 2026-12-31T23:59:59Z

aws cloudfront sign নিজের কম্পিউটারেই একটা canned-policy signed URL বানায়; AWS-এ কিছুই যায় না। URL-টা চালিয়ে দেখো, তারপর query string বাদ দিয়ে একই URL (403), তারপর মেয়াদ পেরোনোর পরে (403)। API এখনো allow list-কে বলে whitelist আর block list-কে blacklist।

#সারসংক্ষেপ

মূল কথাগুলো

  • CloudFront তখনই ঢাল, যখন সেটাই ঢোকার একমাত্র পথ। এই লেসনের প্রতিটা feature ধরে নেয় যে origin-এ পাশ কাটিয়ে পৌঁছানো যায় না।
  • Shield Standard: ফ্রি, আপনা-আপনি চালু, layer ৩ আর ৪ (SYN আর UDP flood), সবচেয়ে জোরালো edge-এ। AWS WAF: layer ৭-এর web ACL, managed rule (SQL injection, XSS), rate-based rule, IP set আর geo match সহ; CloudFront-এর জন্য global scope। Shield Advanced: প্রতি organisation মাসে $৩,০০০, এক বছরের চুক্তি, সাথে usage fee; ২৪ ঘণ্টা SRT (আগের নাম DRT), automatic layer ৭ mitigation, service credit হিসেবে DDoS cost protection, WAF ধরা আছে।
  • ALB বা EC2 origin: public origin + CloudFront managed prefix list সহ security group (weight ৫৫), সাথে ALB listener rule দিয়ে যাচাই করা একটা গোপন custom header, কারণ অন্য account-এর distribution-ও prefix list পার হয়। নয়তো VPC origin (২০২৪-এর নভেম্বর থেকে): private ALB, NLB বা EC2, internet-এ খোলা না, service security group, internet gateway জোড়া, বাড়তি খরচ নেই। S3 origin-এ OAC।
  • Geo restriction: allow list বা block list, শুধু দেশের স্তরে, পুরো distribution-এ, 403, third-party database-এ IP দেখে; VPN এটা এড়িয়ে যায়, আর অজানা অবস্থানকে দিয়ে দেওয়া হয়। Region আর IP range → WAF; শহর → CloudFront-Viewer-City সহ edge function বা third-party service।
  • Invalidation TTL শেষের আগেই সব edge থেকে object সরায়: path, * শুধু শেষে, বড়-ছোট অক্ষর আলাদা; প্রতি account মাসে ১,০০০ path ফ্রি, তারপর প্রতি path $০.০০৫, wildcard path একটা হিসেবে গোনা। Browser cache খালি করে না। ঘন ঘন বদলালে versioned file name।
  • Signed URL (একটা file, cookie না বোঝা client) আর signed cookie (HLS segment-এর মতো অনেক file, URL অপরিবর্তিত), private key দিয়ে sign, যার public key থাকে একটা trusted key group-এ (root key pair না)। Canned policy: একটা URL আর মেয়াদ; custom: wildcard, শুরুর সময়, IP range। Cookie-র ওপরে signed URL জেতে। S3 pre-signed URL থেকে আলাদা, যেটা IAM credential ব্যবহার করে আর সোজা S3-এ যায়।
  • Price class (All, 200, 100) টাকা বাঁচাতে কোন edge চলবে সেটা সীমিত করে; বাকি জায়গার দর্শক ধীরে পায়, কখনো আটকায় না। Custom error response নিজের page দেখায়, status code বদলাতে পারে (SPA → 200), আর default-এ error ১০ সেকেন্ড cache করে।