এজে TLS ও প্রোটোকল
একটা HTTPS রিকোয়েস্টে আসলে দুইটা আলাদা TLS কানেকশন — সার্টিফিকেট কোথা থেকে আসে, TLS মোড কেন রিডাইরেক্ট লুপ বানায়, HSTS কেন ফেরত নেওয়া কঠিন, আর HTTP/2, HTTP/3, 0-RTT এজে কী বদলায়।
গল্পে বুঝি
মিরপুর এক নম্বরে ফারাবির একটা মোবাইল ব্যাংকিং এজেন্ট দোকান। দিনের শেষে দোকানে জমা হওয়া নগদ টাকা তাকে মতিঝিলে ব্যাংকের শাখায় জমা দিতে হয়। পথটা দুই ভাগে। প্রথম ভাগে গ্রাহক কিন্দি দোকানে এসে টাকা দেয়। কিন্দি দেখে নেয় দোকানে কোম্পানির আসল লাইসেন্স টাঙানো আছে আর সাইনবোর্ডের নাম লাইসেন্সের নামের সাথে মেলে; তারপর টাকা দেয়, আর হাতে একটা সিল দেওয়া রসিদ পায়। এই লেনদেনটা কিন্দি আর ফারাবির মধ্যে, নিরাপদ, যাচাই করা।
দ্বিতীয় ভাগে ফারাবির কর্মচারী রাজি টাকার ব্যাগ নিয়ে ব্যাংকে যায়। এখানে কিন্দির কোনো ভূমিকা নেই, কিন্দি জানেও না রাজি কোন পথে যাচ্ছে। একজন সতর্ক এজেন্ট এই অংশটাও সুরক্ষিত করে: সিল করা ব্যাগ, ব্যাংকের কাউন্টারে গিয়ে কাউন্টারের লোকটা আসলেই ব্যাংকের কর্মচারী কিনা তার আইডি কার্ড দেখা। পাশের দোকানের এজেন্ট মরিয়ম আবার খরচ বাঁচাতে টাকা খোলা ব্যাগে রিকশায় পাঠায়, আর রাস্তায় যে কেউ “আমি ব্যাংকের লোক” বললে তার হাতেই দিয়ে দেয়। কিন্দির দিক থেকে দুটো দোকানই সমান নিরাপদ দেখায়, দুই জায়গাতেই সে সিল দেওয়া রসিদ পেয়েছে। কিন্তু টাকা আসলে নিরাপদে পৌঁছাল কিনা, সেটা নির্ভর করে দ্বিতীয় ভাগের ওপর, যা কিন্দি দেখতেই পায় না।
একদিন মরিয়মের দোকানে একটা অদ্ভুত ঝামেলা হলো। ব্যাংকের নতুন নিয়ম: “নগদ জমা শুধু সুরক্ষিত ভ্যানে আসলে নেব; খোলা ব্যাগে এলে আগে সুরক্ষিত ভ্যানের কাউন্টারে যাও।” মরিয়মের লোক খোলা ব্যাগে গেল, ব্যাংক বলল সুরক্ষিত কাউন্টারে যাও। লোকটা দোকানে ফিরে মরিয়মকে জানাল, মরিয়ম আবার সেই খোলা ব্যাগেই পাঠাল, কারণ দোকানে সুরক্ষিত ভ্যানের ব্যবস্থাই নেই। ব্যাংক আবার ফেরত দিল। সারাদিন লোকটা দোকান আর ব্যাংকের মাঝে ঘুরতে থাকল।
মিলিয়ে নিই: কিন্দি থেকে ফারাবির দোকান হলো client থেকে এজ TLS — দোকানের লাইসেন্স হলো এজের সার্টিফিকেট, আর সাইনবোর্ডের নাম মেলানো হলো হোস্টনেম যাচাই। দোকান থেকে ব্যাংক হলো এজ থেকে origin TLS, যা ইউজার কখনো দেখে না। ফারাবির সিল করা ব্যাগ আর আইডি দেখা হলো Full (strict): এনক্রিপ্টেড এবং origin-এর সার্টিফিকেট যাচাই করা। মরিয়মের খোলা ব্যাগ হলো Flexible: ইউজারের দিকে HTTPS, origin-এর দিকে plain HTTP। আর “যে কেউ ব্যাংকের লোক বললেই দিয়ে দেওয়া” হলো এনক্রিপ্টেড কিন্তু যাচাই-বিহীন Full। দোকান আর ব্যাংকের মাঝে সারাদিনের ঘোরাঘুরি হলো সেই বিখ্যাত রিডাইরেক্ট লুপ: origin বলে “HTTPS-এ যাও”, এজ আবার HTTP-তেই যায়। বাস্তবে CDN চালুর প্রথম দিনেই এই লুপ সবচেয়ে বেশি দেখা যায়, আর এর কারণ সবসময় এই দ্বিতীয় ভাগের মোড।
দুইটা TLS কানেকশন
CDN-এর পেছনের একটা HTTPS সাইটে প্রতিটা রিকোয়েস্টে দুইটা সম্পূর্ণ আলাদা TLS সেশন থাকে:
| প্রথম অংশ: client → এজ | দ্বিতীয় অংশ: এজ → origin | |
|---|---|---|
| কে TLS শেষ করে | CDN-এর এজ | আপনার origin |
| কোন সার্টিফিকেট | এজে থাকা baytalhikma.org-এর সার্টিফিকেট | origin-এ থাকা সার্টিফিকেট |
| কে যাচাই করে | ব্রাউজার | CDN (যদি যাচাই চালু থাকে) |
| কোন প্রোটোকল | HTTP/1.1, HTTP/2, বা HTTP/3 | সাধারণত HTTP/1.1 বা HTTP/2 |
| ইউজার কী দেখে | তালার আইকন | কিছুই না |
সবচেয়ে গুরুত্বপূর্ণ উপলব্ধি: ব্রাউজারের তালা শুধু প্রথম অংশের কথা বলে। দ্বিতীয় অংশ plain HTTP হলেও তালা সবুজ থাকে। আর এজ TLS “শেষ” (terminate) করে, মানে এজে রিকোয়েস্টটা প্লেইনটেক্সট হয়, ক্যাশ হয়, WAF দেখে, তারপর নতুন করে origin-এর দিকে এনক্রিপ্ট হয়। CDN আপনার ট্রাফিকের সব কিছু দেখে; এটা CDN-এর ডিজাইন, বাগ না। এজন্যই CDN বেছে নেওয়া একটা বিশ্বাসের সিদ্ধান্ত।
প্রথম অংশ: এজে সার্টিফিকেট কোথা থেকে আসে
এজ যেহেতু ব্রাউজারকে baytalhikma.org হিসেবে সার্টিফিকেট দেখায়, CDN-এর কাছে আপনার ডোমেইনের একটা বৈধ সার্টিফিকেট আর তার প্রাইভেট কী থাকতে হবে। তিনটা উপায়:
১. CDN-ম্যানেজড সার্টিফিকেট (সবচেয়ে প্রচলিত)। CDN নিজেই একটা পাবলিক CA (যেমন Let’s Encrypt বা অন্য কোনো CA) থেকে আপনার ডোমেইনের সার্টিফিকেট নেয়, এজে বসায়, আর নিজে রিনিউ করে। আপনাকে শুধু প্রমাণ করতে হয় ডোমেইনটা আপনার (DCV, domain control validation)।
২. নিজের সার্টিফিকেট আপলোড। আপনি নিজে সার্টিফিকেট কেনেন বা ইস্যু করেন, আর সার্টিফিকেট + প্রাইভেট কী CDN-এ আপলোড করেন। নিয়ন্ত্রণ বেশি (নির্দিষ্ট CA, EV/OV সার্টিফিকেট), কিন্তু রিনিউয়ের দায়িত্বও আপনার। ক্যালেন্ডারে রিমাইন্ডার না রাখলে একদিন সার্টিফিকেট এক্সপায়ার হবে আর পুরো সাইট ব্রাউজারে লাল সতর্কবার্তা দেখাবে।
৩. Keyless বা remote signing। কিছু CDN এমন ব্যবস্থা দেয় যেখানে প্রাইভেট কী আপনার নিজের সার্ভারে থাকে, আর প্রতিটা হ্যান্ডশেকে এজ আপনার সার্ভারকে সাইন করতে বলে। ব্যাংক বা যেখানে নিয়ম অনুযায়ী কী বাইরে দেওয়া যায় না, সেখানে কাজে লাগে।
DCV: CDN কীভাবে প্রমাণ করে ডোমেইন আপনার
CA শুধু তখনই সার্টিফিকেট দেয় যখন কেউ প্রমাণ করে ডোমেইন তার নিয়ন্ত্রণে। CDN-এর জন্য সাধারণ পদ্ধতি:
- HTTP: CA একটা নির্দিষ্ট URL-এ একটা টোকেন খোঁজে। ডোমেইন ইতিমধ্যে CDN-এ পয়েন্ট করা থাকলে CDN নিজেই সেটা সার্ভ করে।
- DNS TXT: একটা
_acme-challengeTXT রেকর্ড। Wildcard সার্টিফিকেটের জন্য এটাই একমাত্র পথ। - DNS CNAME delegation: আপনি একবার
_acme-challenge.baytalhikma.org-কে CDN-এর একটা নামে CNAME করে দেন। এরপর CDN প্রতিবার রিনিউয়ের সময় নিজের zone-এ TXT বসায়, আপনাকে কিছু করতে হয় না।
illustrative
_acme-challenge.baytalhikma.org. 300 IN CNAME baytalhikma.org.dcv.cdn-provider.example. DCV CNAME মুছে দিলে প্রথম দিন কিছু হয় না, সার্টিফিকেট তো বৈধ। সমস্যা আসে রিনিউয়ের সময়, ৬০ থেকে ৯০ দিন পর, যখন কেউ আর মনে রাখে না রেকর্ডটা কেন ছিল। DNS পরিষ্কার করার সময় _acme-challenge আর CDN-এর ভেরিফিকেশন রেকর্ডে হাত দেওয়ার আগে নিশ্চিত হোন। আর আপনার zone-এ CAA রেকর্ড থাকলে CDN যে CA ব্যবহার করে সেটা অনুমোদিত কিনা দেখুন (DNS ট্র্যাক, চ্যাপ্টার ৩)।
SNI: একটা IP, হাজার ডোমেইন
একটা এজ সার্ভারে হাজার হাজার গ্রাহকের ডোমেইন একই IP-তে থাকে। TLS হ্যান্ডশেকের প্রথম মেসেজে (ClientHello) ব্রাউজার SNI (Server Name Indication) দিয়ে বলে দেয় কোন হোস্টনেম চায়, আর এজ সেই অনুযায়ী সার্টিফিকেট বেছে নেয়। SNI ছাড়া এজ জানবেই না কোন সার্টিফিকেট দেখাবে।
curl বা openssl দিয়ে নির্দিষ্ট SNI-তে কোন সার্টিফিকেট আসে দেখা যায়:
openssl s_client -connect baytalhikma.org:443 -servername baytalhikma.org </dev/null 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName illustrative
subject=CN=baytalhikma.org
issuer=C=US, O=Let's Encrypt, CN=R11
notBefore=Sep 30 08:12:44 2026 GMT
notAfter=Dec 29 08:12:43 2026 GMT
X509v3 Subject Alternative Name:
DNS:baytalhikma.org, DNS:*.baytalhikma.org ECH: SNI-ও লুকানো
SNI প্লেইনটেক্সটে যায়, তাই নেটওয়ার্কের মাঝের যে কেউ (ISP, অফিসের ফায়ারওয়াল) দেখতে পায় আপনি কোন সাইটে যাচ্ছেন, যদিও কন্টেন্ট দেখতে পায় না। ECH (Encrypted Client Hello) ClientHello-র সংবেদনশীল অংশ এনক্রিপ্ট করে; বাইরে দেখা যায় শুধু CDN-এর একটা সাধারণ নাম। ২০২৬ সালের অক্টোবর অনুযায়ী ECH RFC 9849 হিসেবে স্ট্যান্ডার্ড হয়েছে, আর ECH-এর কনফিগ DNS-এর HTTPS রেকর্ডে প্রকাশ করা হয়। CDN-এর মতো বড় শেয়ার্ড প্ল্যাটফর্মেই এটা সবচেয়ে কার্যকর, কারণ একই বাইরের নামের পেছনে হাজার সাইট থাকে। আপনার CDN আর আপনার ইউজারদের ব্রাউজারে এটা চালু আছে কিনা, তাদের ডকে দেখে নিন; সাপোর্ট এখনো ছড়াচ্ছে।
দ্বিতীয় অংশ: এজ থেকে origin, আর TLS মোড
এখানেই বেশিরভাগ গোলমাল। CDN-গুলো সাধারণত কয়েকটা “মোড” দেয়, যা আসলে দ্বিতীয় অংশের নীতি। নাম ভেন্ডরভেদে আলাদা; উদাহরণ হিসেবে ২০২৬ সালের অক্টোবর অনুযায়ী Cloudflare-এর ডকুমেন্টেশনের নামগুলো:
| মোড | client → এজ | এজ → origin | origin সার্টিফিকেট যাচাই |
|---|---|---|---|
| Off | HTTP | HTTP | না |
| Flexible | HTTPS | HTTP | প্রযোজ্য না |
| Full | ইউজার যা ব্যবহার করে | ইউজারের প্রোটোকলের মতো | না (self-signed, এক্সপায়ার্ড চলে) |
| Full (strict) | ইউজার যা ব্যবহার করে | ইউজারের প্রোটোকলের মতো | হ্যাঁ |
| Strict (SSL-only origin pull) | যেকোনো | সবসময় HTTPS | হ্যাঁ |
তারা একটা “Automatic” মোডও দেয়, যেখানে তাদের সিস্টেম origin পরীক্ষা করে সবচেয়ে নিরাপদ সম্ভাব্য মোড বেছে নেয়। অন্য CDN-এ একই ধারণা “origin protocol policy” বা “origin SSL verification” নামে থাকে। নিজের ভেন্ডরের ডকে নামগুলো মিলিয়ে নিন।
নিয়ম সোজা: Full (strict) বা তার সমতুল্য ছাড়া অন্য কিছু প্রোডাকশনে রাখবেন না।
- Flexible মানে ইউজারের পাসওয়ার্ড, কুকি, পেমেন্ট এজ থেকে origin পর্যন্ত ইন্টারনেটের ওপর দিয়ে প্লেইনটেক্সটে যায়, অথচ ইউজার তালা দেখে। এটা প্রতারণামূলক নিরাপত্তা।
- Full (যাচাই ছাড়া) এনক্রিপ্ট করে, কিন্তু origin-এর পরিচয় যাচাই করে না। এজ আর origin-এর মাঝের কেউ নিজের যেকোনো সার্টিফিকেট দেখিয়ে origin সেজে যেতে পারে।
Origin-এ বৈধ সার্টিফিকেট পেতে খরচ লাগে না: origin-এ Let’s Encrypt (TLS ট্র্যাক দেখুন), বা অনেক CDN-এর দেওয়া “origin certificate” যা শুধু সেই CDN বিশ্বাস করে (ব্রাউজার না)। দ্বিতীয়টা সহজ, কিন্তু মনে রাখুন, CDN বদলালে বা CDN পাশ কাটিয়ে কাউকে সরাসরি origin দেখাতে হলে সেটা ব্রাউজারে কাজ করবে না।
বিখ্যাত রিডাইরেক্ট লুপ
সবচেয়ে প্রচলিত CDN সমস্যাগুলোর একটা, আর এর মেকানিজমটা বুঝলে চিরকালের জন্য মনে থাকবে:
- Origin-এর nginx-এ একটা নিয়ম আছে: HTTP-তে এলে HTTPS-এ রিডাইরেক্ট করো।
- CDN Flexible মোডে, মানে এজ origin-এর কাছে সবসময় HTTP-তে যায়।
- ইউজার
https://baytalhikma.org/চায়। এজ origin-কেhttp://দিয়ে জিজ্ঞেস করে। - Origin দেখে HTTP, বলে
301 Location: https://baytalhikma.org/। - এজ সেই 301 ইউজারকে দেয়। ইউজার আবার
https://চায়। ধাপ ৩-এ ফেরত।
curl -sIL --max-redirs 5 https://baytalhikma.org/ | grep -iE '^(HTTP|location)' illustrative
HTTP/2 301
location: https://baytalhikma.org/
HTTP/2 301
location: https://baytalhikma.org/
HTTP/2 301
location: https://baytalhikma.org/
curl: (47) Maximum (5) redirects followed একই URL-এ বারবার 301 = লুপ। সমাধান: origin-এ বৈধ সার্টিফিকেট বসান আর মোড Full (strict) করুন। HTTP থেকে HTTPS রিডাইরেক্ট এজে করুন (প্রায় সব CDN-এ “always use HTTPS” জাতীয় সেটিং আছে), origin-এ না।
একই লুপের আরেকটা রূপ: origin অ্যাপ নিজে X-Forwarded-Proto হেডার দেখে ঠিক করে রিকোয়েস্ট HTTPS কিনা। প্রক্সি সেই হেডার না পাঠালে বা অ্যাপ সেটা বিশ্বাস না করলে (অনেক ফ্রেমওয়ার্কে “trust proxy” সেটিং লাগে), অ্যাপ সব রিকোয়েস্টকে HTTP ভাবে আর রিডাইরেক্ট করে।
HSTS: শক্তিশালী, আর ফেরত নেওয়া কঠিন
HSTS (Strict-Transport-Security হেডার) ব্রাউজারকে বলে: “এই ডোমেইনে আগামী এত সেকেন্ড শুধু HTTPS ব্যবহার করবে, কোনো ব্যতিক্রম নেই।” এরপর ইউজার http:// টাইপ করলেও ব্রাউজার নিজেই HTTPS-এ যায়, আর সার্টিফিকেট এরর হলে ইউজারকে “তবুও যান” বাটন দেখায় না।
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload প্রতিটা অংশের ঝুঁকি:
max-ageব্রাউজারের মনে থাকে। কাল হেডারটা তুলে নিলেও যারা আজ দেখেছে তাদের ব্রাউজারে বাকি সময় পর্যন্ত নিয়মটা থাকবে।includeSubDomainsসব সাবডোমেইনে প্রযোজ্য। কোনো একটা অভ্যন্তরীণ সাবডোমেইন (printer.baytalhikma.org, পুরনো একটা টুল) যদি HTTPS না পারে, সেটা ব্রাউজারে আর খুলবে না।preloadমানে ডোমেইনটা ব্রাউজারের ভেতরে হার্ডকোড করা তালিকায় ঢোকানো (hstspreload.org-এ জমা দিয়ে)। তালিকা ব্রাউজারের সাথে শিপ হয়, তাই প্রথম ভিজিটেও প্রযোজ্য। কিন্তু বের হতে চাইলে ব্রাউজারের নতুন রিলিজ লাগে, আর ইউজাররা আপডেট না করা পর্যন্ত পুরনো তালিকা থাকে: মাসের হিসাব।
ধাপে ধাপে বাড়ান: প্রথমে max-age=300 (৫ মিনিট), সব সাবডোমেইন HTTPS-এ ঠিক আছে নিশ্চিত হয়ে এক সপ্তাহ, তারপর এক বছর, আর একদম শেষে, পুরোপুরি নিশ্চিত হলে, preload। CDN-এর ড্যাশবোর্ডে এক ক্লিকে HSTS চালু করার বাটন থাকে; এটা বাটন হলেও প্রভাবটা ব্রাউজারে মাসব্যাপী।
প্রোটোকল: এজ আর origin আলাদা ভাষায় কথা বলে
CDN-এর একটা বড় সুবিধা হলো আপনার origin পুরনো প্রোটোকলে থাকলেও ইউজার আধুনিক প্রোটোকল পায়।
HTTP/2 এজে, HTTP/1.1 origin-এ
HTTP/2 একটা কানেকশনে অনেক রিকোয়েস্ট একসাথে চালায় (multiplexing), হেডার কমপ্রেস করে। বেশিরভাগ CDN এজে ডিফল্টে HTTP/2 চালু রাখে। এজ থেকে origin-এ অনেক CDN এখনো HTTP/1.1 ব্যবহার করে, কিছু HTTP/2-ও সাপোর্ট করে। Origin-এর দিকে এটা সাধারণত কোনো সমস্যা না: এজ আর origin-এর মাঝে কানেকশন দীর্ঘস্থায়ী আর রিইউজ হয় (আগের চ্যাপ্টারের keepalive), তাই HTTP/2-এর লাভটা ওখানে কম।
একটা ফাঁদ: HTTP/2-তে হেডারের নাম ছোট হাতের অক্ষরে হতে হয়, আর কিছু হেডার (Connection, Keep-Alive, Transfer-Encoding) নিষিদ্ধ। পুরনো অ্যাপ যদি অদ্ভুত হেডার পাঠায়, এজ সেগুলো ঠিক করে নেয় বা বাদ দেয়। অ্যাপের একটা কাস্টম হেডার ইউজারের কাছে না পৌঁছালে এটা একটা সম্ভাব্য কারণ।
HTTP/3 ও QUIC
HTTP/3 চলে QUIC-এর ওপর, যা UDP-ভিত্তিক। লাভ: TCP-এর head-of-line blocking নেই (একটা প্যাকেট হারালে বাকি স্ট্রিম আটকে থাকে না), কানেকশন সেটআপ দ্রুত (TLS 1.3 QUIC-এর ভেতরেই), আর নেটওয়ার্ক বদলালে (Wi-Fi থেকে মোবাইল ডেটা) কানেকশন টিকে থাকে। হারানো প্যাকেট যেখানে বেশি, যেমন দুর্বল মোবাইল নেটওয়ার্ক, সেখানে পার্থক্যটা সবচেয়ে বেশি চোখে পড়ে।
ব্রাউজার জানবে কীভাবে যে HTTP/3 পাওয়া যায়? দুই পথে:
Alt-Svcহেডার। প্রথম রিকোয়েস্ট HTTP/2-তে যায়, রেসপন্সে এজ বলেalt-svc: h3=":443"; ma=86400, পরের রিকোয়েস্ট থেকে ব্রাউজার HTTP/3 চেষ্টা করে।- DNS-এর HTTPS রেকর্ড (DNS ট্র্যাকের চ্যাপ্টার ৩)। ব্রাউজার DNS লুকআপেই জেনে যায়
alpn=h3আছে, তাই প্রথম কানেকশনেই HTTP/3 নিতে পারে।
curl -sI https://baytalhikma.org/ | grep -i alt-svc
dig +short HTTPS baytalhikma.org
curl -sI --http3 https://baytalhikma.org/ | head -1 # needs a curl built with HTTP/3 illustrative
alt-svc: h3=":443"; ma=86400
1 . alpn="h3,h2" ipv4hint=192.0.2.10 ipv6hint=2001:db8::10
HTTP/3 200 HTTP/3 শুধু এজে লাগে, origin-এ না। আর UDP/443 যে নেটওয়ার্কে ব্লক (কিছু অফিস ফায়ারওয়াল), সেখানে ব্রাউজার চুপচাপ HTTP/2-তে ফিরে যায়; ইউজার কিছু টের পায় না।
0-RTT: দ্রুত, কিন্তু রিপ্লে করা যায়
TLS 1.3-এ একটা ফিচার আছে: আগে কানেক্ট করা ক্লায়েন্ট আবার আসলে হ্যান্ডশেক শেষ হওয়ার আগেই প্রথম রিকোয়েস্ট পাঠিয়ে দিতে পারে (“early data” বা 0-RTT)। এক round trip বাঁচে।
সমস্যা হলো রিপ্লে। মাঝখানের কেউ সেই early data প্যাকেটটা কপি করে আবার পাঠালে সার্ভার সেটা আবার প্রসেস করতে পারে। GET /article/42 দুইবার হলে ক্ষতি নেই। POST /transfer?amount=5000 দুইবার হলে বিপর্যয়।
তাই নিয়ম:
- CDN সাধারণত শুধু নিরাপদ মেথডের (GET, HEAD) জন্য 0-RTT গ্রহণ করে। আপনার CDN কী নীতি নেয়, ডকে দেখে নিন।
- এজ যখন একটা early data রিকোয়েস্ট origin-এ পাঠায়, সে
Early-Data: 1হেডার যোগ করতে পারে (RFC 8470)। Origin চাইলে সংবেদনশীল কাজের জন্য425 Too Earlyফেরত দিতে পারে, তখন ক্লায়েন্ট হ্যান্ডশেক শেষ করে আবার পাঠায়। - আর সবচেয়ে বড় কথা: GET দিয়ে কখনো অবস্থা বদলাবেন না। এই নিয়ম মানলে 0-RTT প্রায় নিরাপদ।
সেশন রিজিউম্পশন
প্রতিটা নতুন TLS হ্যান্ডশেকে public-key ক্রিপ্টোগ্রাফি লাগে, যা CPU-ভারী আর সময় নেয়। সেশন রিজিউম্পশন (session tickets বা PSK) দিয়ে আগে কানেক্ট করা ক্লায়েন্ট পরেরবার ছোট হ্যান্ডশেকে ফিরে আসে। CDN-এ এটা ডিফল্টে চালু থাকে। নিজের এজ চালালে (চ্যাপ্টার ১৩) দুইটা জিনিস মনে রাখুন: একাধিক এজ সার্ভারের মধ্যে ticket key শেয়ার না করলে ইউজার অন্য সার্ভারে গেলে রিজিউম কাজ করবে না; আর ticket key নিয়মিত রোটেট করুন, কারণ পুরনো কী ফাঁস হলে সেই কী দিয়ে এনক্রিপ্ট করা পুরনো ট্রাফিক ডিক্রিপ্ট করা যেতে পারে।
Mixed content
HTTPS পেজ যদি কোনো ফাইল http:// থেকে লোড করে, ব্রাউজার সেটা ব্লক করে (স্ক্রিপ্ট, স্টাইলশিট সবসময়; ইমেজ অনেক সময় আপগ্রেড বা ব্লক)। CDN-এ মাইগ্রেট করার পর এটা প্রায়ই দেখা যায়, কারণ পুরনো কন্টেন্টে, ডেটাবেসে বা টেমপ্লেটে http:// লিংক হার্ডকোড করা থাকে। পেজ খোলে, কিন্তু স্টাইল নেই বা কোনো বাটন কাজ করে না।
curl -s https://baytalhikma.org/ | grep -oE '(src|href)="http://[^"]+"' | sort -u সমাধান: লিংকগুলো রিলেটিভ বা https:// করুন। সাময়িক নিরাপত্তা জাল হিসেবে Content-Security-Policy: upgrade-insecure-requests হেডার দেওয়া যায়, যা ব্রাউজারকে সব http:// সাব-রিসোর্স HTTPS-এ চাইতে বলে। কিছু CDN “automatic HTTPS rewrites” জাতীয় ফিচারও দেয়।
এজ সার্টিফিকেটের রিনিউ ফেল করা
CDN-ম্যানেজড সার্টিফিকেট নিজে রিনিউ হয়, যতক্ষণ DCV পাস করে। রিনিউ ফেল করার সাধারণ কারণ:
- DNS আর CDN-এ পয়েন্ট করা নেই (ডোমেইন অন্য কোথাও সরানো হয়েছে, বা প্রক্সি বন্ধ করা হয়েছে), তাই HTTP DCV পাস হয় না
_acme-challengeCNAME মুছে ফেলা হয়েছে- CAA রেকর্ড CDN-এর CA-কে অনুমোদন দেয় না
- Origin বা ফায়ারওয়াল
/.well-known/acme-challenge/পাথ আটকে দিচ্ছে (যদি DCV origin পর্যন্ত যায়)
বেশিরভাগ CDN রিনিউ ফেল করলে ইমেইল পাঠায়, যা প্রায়ই কারো ইনবক্সে চাপা পড়ে। নিজের মনিটরিং রাখুন:
# Days until the edge certificate expires; alert below a threshold.
end=$(echo | openssl s_client -connect baytalhikma.org:443 -servername baytalhikma.org 2>/dev/null \
| openssl x509 -noout -enddate | cut -d= -f2)
echo $(( ( $(date -d "$end" +%s) - $(date +%s) ) / 86400 )) (macOS-এ date -d নেই; date -j -f "%b %d %T %Y %Z" "$end" +%s ব্যবহার করুন।)
ডিবাগিং: এই চ্যাপ্টারের সমস্যাগুলো
লক্ষণ: CDN চালুর পরেই ERR_TOO_MANY_REDIRECTS। নিশ্চিত করুন:
curl -sIL --max-redirs 5 https://baytalhikma.org/ | grep -iE '^(HTTP|location)' একই HTTPS URL-এ বারবার 301 মানে origin HTTP-তে রিকোয়েস্ট পাচ্ছে আর HTTPS-এ পাঠাচ্ছে। সমাধান: origin-এ সার্টিফিকেট, TLS মোড Full (strict), HTTP থেকে HTTPS রিডাইরেক্ট এজে। অ্যাপ-লেভেলে রিডাইরেক্ট হলে অ্যাপকে X-Forwarded-Proto বিশ্বাস করতে কনফিগার করুন।
লক্ষণ: CDN-এর এরর পেজ বলছে origin-এর সাথে TLS হ্যান্ডশেক ফেল, বা “invalid SSL certificate” (Cloudflare-এ 525/526)। নিশ্চিত করুন: CDN যে নাম দিয়ে origin-এ যায়, সেই নামেই origin-এর সার্টিফিকেট দেখুন।
openssl s_client -connect 198.51.100.10:443 -servername baytalhikma.org </dev/null 2>/dev/null \
| openssl x509 -noout -subject -dates -ext subjectAltName হোস্টনেম SAN-এ নেই, সার্টিফিকেট এক্সপায়ার্ড, বা chain অসম্পূর্ণ (origin শুধু leaf পাঠাচ্ছে, intermediate না)? সেটা ঠিক করুন। nginx-এ ssl_certificate-এ fullchain.pem দিন, cert.pem না।
লক্ষণ: ব্রাউজারে সার্টিফিকেট এরর, বা ভুল নামের সার্টিফিকেট, শুধু একটা সাবডোমেইনে। নিশ্চিত করুন: ওই SNI দিয়ে এজ কোন সার্টিফিকেট দেখায়।
openssl s_client -connect shop.baytalhikma.org:443 -servername shop.baytalhikma.org </dev/null 2>/dev/null \
| openssl x509 -noout -subject -ext subjectAltName SAN-এ নামটা না থাকলে: CDN-এ ওই হোস্টনেম যোগ করা হয়নি, অথবা wildcard শুধু এক স্তর কভার করে (*.baytalhikma.org মেলে shop.baytalhikma.org-এর সাথে, কিন্তু api.shop.baytalhikma.org-এর সাথে না)।
লক্ষণ: এজ সার্টিফিকেট শিগগিরই এক্সপায়ার হবে বা হয়ে গেছে, অথচ “auto-renew” চালু। নিশ্চিত করুন: DCV পথগুলো খোলা কিনা।
dig +short CNAME _acme-challenge.baytalhikma.org
dig +short CAA baytalhikma.org
dig +short baytalhikma.org # still pointing at the CDN? সমাধান: মুছে যাওয়া DCV রেকর্ড ফেরত আনুন, CAA-তে CDN-এর CA যোগ করুন, তারপর CDN-এর ড্যাশবোর্ড থেকে রিনিউ আবার চালান।
লক্ষণ: একটা অভ্যন্তরীণ সাবডোমেইন হঠাৎ ব্রাউজারে খোলে না, “তবুও যান” বাটনও নেই। নিশ্চিত করুন: প্যারেন্ট ডোমেইন includeSubDomains সহ HSTS পাঠাচ্ছে কিনা।
curl -sI https://baytalhikma.org/ | grep -i strict-transport সমাধান: সাবডোমেইনে বৈধ HTTPS দিন (সবচেয়ে সহজ পথ)। ব্রাউজারে মনে থাকা নিয়ম শুধু সেই ব্রাউজারের HSTS সেটিং পেজ থেকে মোছা যায় (Chrome-এ chrome://net-internals/#hsts); সব ইউজারের জন্য সেটা সম্ভব না।
লক্ষণ: কিছু ইউজারের জন্য সাইট ধীর বা অদ্ভুত, অন্যদের ঠিক; সন্দেহ HTTP/3। নিশ্চিত করুন: দুই প্রোটোকলে আলাদা করে মাপুন।
curl -so /dev/null -w 'h2 %{http_version} %{time_total}\n' --http2 https://baytalhikma.org/
curl -so /dev/null -w 'h3 %{http_version} %{time_total}\n' --http3 https://baytalhikma.org/ HTTP/3-তে স্পষ্টভাবে খারাপ বা ফেল করলে: সমস্যাটা নেটওয়ার্কের দিকে (UDP ব্লক বা থ্রটল); ব্রাউজার সাধারণত নিজে HTTP/2-তে ফেরে। সন্দেহ থাকলে সাময়িকভাবে CDN-এ HTTP/3 বন্ধ করে তুলনা করুন।
লক্ষণ: পেজ খোলে কিন্তু স্টাইল নেই, কনসোলে “Mixed Content”। নিশ্চিত করুন: পেজের HTML-এ http:// রিসোর্স খুঁজুন (উপরের grep কমান্ড)। সমাধান: লিংক ঠিক করুন; সাময়িকভাবে upgrade-insecure-requests।
মূল শিক্ষা
- CDN-এর পেছনে প্রতিটা HTTPS রিকোয়েস্টে দুইটা আলাদা TLS কানেকশন। ব্রাউজারের তালা শুধু প্রথমটার কথা বলে।
- প্রোডাকশনে শুধু Full (strict) বা সমতুল্য। Flexible মানে origin পর্যন্ত প্লেইনটেক্সট; যাচাই-বিহীন Full মানে যে কেউ origin সাজতে পারে।
- রিডাইরেক্ট লুপ প্রায় সবসময় এজ থেকে origin-এ HTTP যাওয়া + origin-এর HTTPS রিডাইরেক্ট। HTTPS রিডাইরেক্ট এজে করুন।
- DCV রেকর্ড আর CAA হলো ভবিষ্যতের রিনিউয়ের চাবি। আজ মুছলে ৬০ দিন পর সাইট ডাউন।
- HSTS ধাপে ধাপে বাড়ান;
preloadপ্রায় অপরিবর্তনীয়।includeSubDomainsদেওয়ার আগে প্রতিটা সাবডোমেইন HTTPS-এ আছে নিশ্চিত হোন। - HTTP/2 আর HTTP/3 এজে লাগে, origin-এ না। HTTP/3 ঘোষণা হয়
Alt-Svcবা DNS-এর HTTPS রেকর্ডে। - 0-RTT রিপ্লে করা যায়। GET দিয়ে কখনো অবস্থা বদলাবেন না, আর সংবেদনশীল কাজে
Early-Dataহেডার দেখে425দিন। - CDN TLS শেষ করে, তাই আপনার সব ট্রাফিক দেখে। CDN বেছে নেওয়া একটা বিশ্বাসের সিদ্ধান্ত।