2.8
TLS 1.2 বনাম TLS 1.3 Handshake, আর Mutual TLS
দুটো handshake-এর প্রতিটা message, forward secrecy, 0-RTT, আর service-গুলো কীভাবে একে অপরের কাছে নিজের পরিচয় প্রমাণ করে।
45 মিনিট পড়া + Animation
টিপস: ডটেড-আন্ডারলাইন করা যেকোনো শব্দে ট্যাপ বা Hover করলে তার অর্থ দেখবে।
এই Lesson শেষে তুমি পারবে
- TLS 1.2 Handshake একটা একটা Message ধরে (ClientHello থেকে Finished) বোঝাতে, আর প্রতিটা Message কী প্রমাণ করে তা বলতে।
- RSA Key Transport কেন বাদ গেল আর Forward Secrecy কীসের হাত থেকে বাঁচায়, সেটা ব্যাখ্যা করতে।
- TLS 1.3 Handshake বোঝাতে: প্রথম Message-এই Key Share, HKDF Key Schedule, কী কী Encrypt হয়, HelloRetryRequest, পাঁচটা Cipher Suite আর কোন কোন জিনিস বাদ পড়েছে।
- TCP + TLS 1.2, TCP + TLS 1.3, QUIC, Resumption আর 0-RTT-এ কত Round Trip লাগে গুনতে, আর 0-RTT কেন শুধু Idempotent Request-এর জন্য নিরাপদ তা বলতে।
- SNI, Encrypted Client Hello, ALPN আর Post-quantum Hybrid Key Share বোঝাতে, আর লক্ষণ দেখে Handshake-এর চেনা ব্যর্থতাগুলো ধরতে।
- Load Balancer-এ TLS Termination, Re-encryption আর Passthrough-এর মধ্যে বাছতে।
- Mutual TLS শুরু থেকে শেষ বোঝাতে: CertificateRequest, Client Certificate, SPIFFE পরিচয়, স্বল্পমেয়াদি Certificate আর Rotation, Sidecar বনাম Ambient Mesh, আর কখন API Key বা JWT-র বদলে mTLS নেবে।
#এই Lesson কোথায় বসে
Lesson ১.৯-এ তুমি পুরো ছবিটা দেখেছ: TLS গোপনীয়তা, অখণ্ডতা আর পরিচয় প্রমাণ দেয়; TLS 1.3-এ এক Round Trip লাগে; Browser Certificate-এর নাম, তারিখ আর Chain যাচাই করে; 0-RTT Replay হতে পারে; HSTS HTTPS-এ বাধ্য করে। Lesson ২.৭-এ শিখেছ ইট-পাথরগুলো: Symmetric আর Asymmetric Key, ECDHE, Signature, Certificate, CA আর Chain of Trust। Lesson ১.১২-এ Zero Trust-এর অংশ হিসেবে mTLS-এর সাথে পরিচয় হয়েছে।
এবার এই টুকরোগুলো জোড়া লাগিয়ে Handshake-এর ভেতরটা খুলব। TLS Handshake হলো সেই প্রক্রিয়া, যেখানে Client আর Server কোন Cryptographic Algorithm চালাবে তা ঠিক করে, পরিচয় যাচাই করে, আর Encryption-এর জন্য একটা নিরাপদ Symmetric Session Key বানায়। যে Version-ই হোক, প্রতিটা Handshake-কে এই চারটা কাজ করতেই হয়:
| লক্ষ্য | কেন দরকার | TLS 1.2 কী দিয়ে করে | TLS 1.3 কী দিয়ে করে |
|---|---|---|---|
| Version আর Algorithm-এ একমত হওয়া | দুই পাশকে একই Cipher-এ কথা বলতে হবে | ClientHello-র তালিকা → ServerHello-র পছন্দ | একই, সাথে supported_versions |
| এমন Key-তে একমত হওয়া যা আর কেউ জানে না | সব Data এগুলো দিয়েই Encrypt হবে | ServerKeyExchange + ClientKeyExchange (ECDHE) | দুই Hello-তেই key_share |
| Server-এর পরিচয় প্রমাণ (চাইলে Client-এরও) | নইলে হয়তো আক্রমণকারীর সাথেই কথা বলছ | Certificate + ServerKeyExchange-এর Signature | Certificate + CertificateVerify |
| প্রমাণ করা যে কেউ Handshake-এ হাত দেয়নি | আক্রমণকারী Hello থেকে শক্ত Option মুছে দিতে পারত | Finished (সব Message-এর ওপর Key দেওয়া Hash) | Finished, আর প্রতিটা Key Transcript-এর সাথে বাঁধা |
দুই Version একই লক্ষ্যে পৌঁছায়; TLS 1.3 শুধু এক Round Trip আগে পৌঁছায়, আর পথে অনেক বেশি কিছু লুকিয়ে রাখে।
#TLS 1.2, একটা একটা Message ধরে
TLS 1.2-এ (RFC 5246, ২০০৮) TCP-র পরে Application Data চলার আগে দুটো Round Trip লাগে। নোটে এটা চারটা তীর দিয়ে আঁকা; এখানে আসল সব Message দেখো।
TLS 1.2 Handshake, একটা একটা Message ধরে
TCP আগেই চালু। মাঝের Recorder প্রতিটা Byte কপি করে রাখে, একদিন Decrypt করার আশায়।
পরিস্থিতি
স্বাভাবিক TLS 1.2 Handshake: অস্থায়ী (Ephemeral) Elliptic-curve Key Exchange আর RSA Certificate (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256)।
Client পাঠায় তার সবচেয়ে উঁচু Version (1.2), ৩২ Byte-এর Client Random, পছন্দের ক্রমে Cipher Suite-এর তালিকা, আর কিছু Extension: SNI (shop.example.com), ALPN (h2, http/1.1), কোন কোন Group চলে (x25519, P-256) আর কোন Signature Algorithm চলে।
১. ClientHello (Client → Server)
Client পাঠায় তার সবচেয়ে উঁচু Version, ৩২ Byte-এর একটা Client Random, পছন্দের ক্রমে তার Cipher Suite-গুলো, আর কিছু Extension: SNI (Hostname), ALPN (
h2,http/1.1), কোন কোন Elliptic-curve Group সে চালায় আর কোন Signature Algorithm সে মানে।২. ServerHello, Certificate, ServerKeyExchange, ServerHelloDone (Server → Client)
চারটা Message মিলে একটা চালান। ServerHello একটা Cipher Suite বেছে নেয়, সাথে ৩২ Byte-এর Server Random। Certificate হলো Chain, আগে Leaf, আর এটা যায় Encrypt ছাড়াই। ServerKeyExchange-এ থাকে Server-এর একদম নতুন, অস্থায়ী ECDHE Public Key, দুটো Random-সহ Certificate-এর Private Key দিয়ে Sign করা; এতে প্রমাণ হয় Key-টা Certificate-এর মালিকেরই, আর এই Session-এরই। ServerHelloDone বলে “এবার তোমার চাল”। Server এখনো Finished পাঠাতে পারে না: Client-এর Key Share সে এখনো দেখেনি।
৩. Client যাচাই করে, হিসাব করে
Client Chain, Hostname আর তারিখ যাচাই করে (Lesson ২.৭), নিজের একটা অস্থায়ী Key Pair বানায়, আর দুজনের ECDHE মান হিসাব করে: এটাই Pre-master Secret। একটা Pseudorandom Function (PRF) এটাকে দুটো Random-এর সাথে মিশিয়ে ৪৮ Byte-এর Master Secret বানায়, তারপর সেখান থেকে একটা Key Block বের হয়: প্রতিটা দিকের জন্য আলাদা Encryption Key (আর Initialisation Vector)।
৪. ClientKeyExchange, ChangeCipherSpec, Finished (Client → Server)
ClientKeyExchange-এ থাকে Client-এর অস্থায়ী Public Key, যাতে Server-ও একই Secret হিসাব করতে পারে। ChangeCipherSpec মানে “এর পরের Record থেকে আমি Encrypt করব”। Finished হলো প্রথম Encrypt করা Message: এ পর্যন্ত সব Handshake Message-এর ওপর একটা Key দেওয়া Hash।
৫. ChangeCipherSpec, Finished (Server → Client)
Server Client-এর Finished মিলিয়ে দেখে, তারপর নিজেরটা পাঠায়। কেউ যদি Hello বদলে দিত, ধরো শক্ত Cipher Suite-গুলো মুছে দুর্বল একটা চাপিয়ে দিত, তাহলে দুই পাশের Hash আলাদা হতো আর Handshake ব্যর্থ হতো। এবার Application Data চলে।
খরচ: TCP-র ১টার ওপর TLS-এর জন্য ২টা Round Trip। Browser False Start দিয়ে নিজের Finished-এর ঠিক পরেই প্রথম Request পাঠিয়ে দিত (ECDHE Suite-এ এক Round Trip বাঁচাত), কিন্তু Protocol-এর হিসাবে দুটোই।
#RSA Key Transport বনাম ECDHE: Forward Secrecy
TLS 1.2-এ আরও সহজ একটা Key Exchange চলত, RSA Key Transport: Client নিজেই Pre-master Secret বানায়, আর Certificate-এর ভেতরের Server-এর RSA Public Key দিয়ে Encrypt করে পাঠিয়ে দেয়। ServerKeyExchange নেই। এটা কাজ করে, বহু বছর এটাই ডিফল্ট ছিল। ওপরের Animation-এর দ্বিতীয় Scenario চালাও, সমস্যাটা দেখবে।
সবকিছু ঝুলে আছে একটাই দীর্ঘস্থায়ী Key-এর ওপর। আক্রমণকারী আজ Encrypt করা Traffic রেকর্ড করে রাখল, আর পরে কোনোদিন Private Key চুরি করল (একটা Breach, চুরি যাওয়া Backup, ২০১৪-র Heartbleed-এর মতো Memory ফাঁসের Bug, কিংবা আদালতের আদেশ)। তখন সে জমানো প্রতিটা ClientKeyExchange খুলে প্রতিটা Session-এর Secret বের করবে, আর বছরের পর বছরের Traffic পড়ে ফেলবে। ECDHE-তে প্রতিটা Handshake নতুন Key Pair বানায়, কাজ শেষে মুছে ফেলে; Certificate-এর Key শুধু Sign করে। পরে সেটা চুরি করলে আক্রমণকারী ভবিষ্যতে Server সেজে বসতে পারে, কিন্তু অতীত Decrypt করতে পারে না। এই গুণের নাম Forward Secrecy।
RSA Key Transport-এ Padding-oracle আক্রমণও হয়েছে (Bleichenbacher ১৯৯৮ সালে, ২০১৭ সালে আবার নতুন রূপে)। তাই TLS 1.3 এটা বাদ দিয়েছে: TLS 1.3-এর প্রতিটা Handshake অস্থায়ী Diffie-Hellman দিয়ে।
#TLS 1.2-এর একটা Cipher Suite পড়া
TLS 1.2-এর Suite-এর নামে একসাথে চারটা সিদ্ধান্ত গোঁজা থাকে:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256-এর অংশ | মানে |
|---|---|
ECDHE | Key Exchange: অস্থায়ী Elliptic-curve Diffie-Hellman (Forward Secrecy) |
RSA | পরিচয় প্রমাণ: Certificate-এ RSA Key, যা ECDHE-র মানগুলো Sign করে |
AES_128_GCM | মূল Cipher: ১২৮ bit Key-এর AES, GCM Mode-এ; এটা AEAD, মানে Encrypt আর যাচাই একসাথে |
SHA256 | Key বানানোর PRF-এ যে Hash চলে |
এমন শত শত জোড়া Register করা ছিল, তার অনেকগুলোই দুর্বল (Export-grade, RC4, 3DES, আলাদা MAC-সহ CBC)। TLS 1.2 Server শক্ত করার বড় একটা অংশ হলো এই তালিকার বেশিরভাগটা মুছে ফেলা।
#TLS 1.3: এক Round Trip, প্রায় পুরোটাই Encrypt করা
TLS 1.3 (RFC 8446, ২০১৮) অপ্রয়োজনীয় ধাপ ফেলে দিয়ে এক Round Trip-এ (1-RTT) Handshake শেষ করে, তাতে Latency অনেক কমে। কৌশলটা প্রথম Message-এ: Server কোন Key Exchange Group নেবে, Client সেটা অনুমান করে, আর সাথে সাথেই নিজের Key Share পাঠিয়ে দেয়।
TLS 1.3 Handshake: এক Round Trip, প্রায় পুরোটাই Encrypt করা
{বন্ধনী}-র ভেতরের Message Handshake Key দিয়ে Encrypt করা; [বন্ধনী] মানে Application Data। TCP আগেই চালু।
পরিস্থিতি
একটা Message-এই সব: supported_versions (1.3, 1.2), তিনটা Cipher Suite, X25519MLKEM768-এর একটা key_share আর X25519-এর একটা, SNI, ALPN আর Signature Algorithm। Key Share এখনই পাঠানোই হলো সেই Round Trip বাঁচানোর কৌশল।
১. ClientHello + key_share (Client → Server)
supported_versions-এ থাকে 1.3 আর 1.2 (পুরোনো Version Field-টা 1.2-তেই আটকে রাখা হয়েছে, যাতে আধাখেঁচড়া Middlebox আটকে না দেয়), তিন-চারটা Cipher Suite, যে Group-গুলোর ওপর বাজি ধরছে তাদের প্রত্যেকটার একটা করে key_share (আজকের Browser পাঠায় X25519MLKEM768 আর X25519), SNI, ALPN আর Signature Algorithm।২. ServerHello + key_share (Server → Client)
Server Version, Suite আর একটা Group বাছে, আর নিজের Share ফেরত পাঠায়। এবার দুই পাশই Shared Secret হিসাব করতে পারে। এটাই শেষ খোলা (Plaintext) Handshake Message।
৩. {EncryptedExtensions}, {CertificateRequest}, {Certificate}, {CertificateVerify}, {Finished} (Server → Client)
একই চালান, Handshake Key দিয়ে Encrypt করা। EncryptedExtensions-এ থাকে এমন উত্তর যা খোলা রাখার দরকার নেই (যেমন বেছে নেওয়া ALPN Protocol)। CertificateRequest আসে শুধু Mutual TLS-এ। Certificate এখন Encrypt করা, তাই পথে বসে কেউ জানতে পারে না কোন Certificate গেল। CertificateVerify হলো এ পর্যন্ত পুরো Handshake-এর Hash-এর ওপর একটা Signature, যা প্রমাণ করে Private Key Server-এর কাছেই আছে, আর ঠিক এই Session-এর জন্যই। Finished হলো Transcript-এর ওপর Key দেওয়া Hash। Server চাইলে এখনই Data পাঠানো শুরু করতে পারে (“0.5-RTT” Data)।
৪. {Finished} + প্রথম Request (Client → Server)
Client সব যাচাই করে Finished পাঠায়, আর একই চালানে প্রথম HTTP Request। Handshake-এর পরে Server পরের বার Resume করার জন্য এক বা একাধিক NewSessionTicket পাঠায়।
#Key Schedule: HKDF
TLS 1.2 Master Secret থেকে একবারেই সব Key বানাত। TLS 1.3 HKDF (HMAC-ভিত্তিক Key Derivation) দিয়ে ধাপে ধাপে একটা শিকল বানায়, আর প্রতিটা ধাপে এ পর্যন্ত Handshake Message-গুলোর একটা Hash মেশায় (এর নাম Transcript):
PSK (বা শূন্য) ──► Early Secret ──► client_early_traffic_secret (0-RTT Data)
│
ECDHE Shared ──────► Handshake Secret ──► Client/Server Handshake Traffic Secret
│ (EncryptedExtensions … Finished)
▼
Master Secret ──► Client/Server Application Traffic Secret
──► Resumption Secret (→ পরের বারের Ticket)
──► Exporter Secret (TLS-এর ওপর বানানো Protocol-এর জন্য)
Interview-এর জন্য তিনটা ফল মনে রাখো। Key প্রতিটা দিক আর প্রতিটা ধাপের জন্য আলাদা, তাই এক ধাপের Bug আরেক ধাপ খুলে দেয় না। প্রতিটা Key Transcript-এর ওপর নির্ভর করে বলে কোথাও হাত দিলেই সব Key বদলে যায়, আর Handshake সোজা ব্যর্থ হয়। আর লম্বা Connection নতুন Handshake ছাড়াই KeyUpdate Message দিয়ে Key সামনে এগিয়ে নিতে পারে।
#HelloRetryRequest: অনুমান ভুল হলে
Client যদি শুধু এমন Group-এর Share পাঠায় যা Server নেবে না, কিন্তু তালিকায় এমন একটা রাখে যা Server চালায়, তাহলে Server উত্তর দেয় HelloRetryRequest দিয়ে (বিশেষ একটা নির্দিষ্ট Random-ওয়ালা ServerHello): “আমাকে P-256-এর Share দাও”। Client দ্বিতীয় একটা ClientHello পাঠায়, নতুন Share ছাড়া হুবহু আগেরটার মতো, আর Handshake এগিয়ে যায়। খরচ একটা বাড়তি Round Trip। ওপরের দ্বিতীয় Scenario চালিয়ে দেখো।
এজন্যই Client দুটো Share পাঠায়, আর এজন্যই Browser প্রথমে যা অনুমান করে (আজ X25519MLKEM768 আর X25519), Server-এর সেটা চালানো উচিত। HelloRetryRequest-এ একটা Cookie-ও থাকতে পারে; Flood-এর মধ্যে Server তাহলে কোনো State না রেখে অপেক্ষা করতে পারে, যতক্ষণ না Client প্রমাণ দেয় যে সে নিজের Address-এ Packet পায়।
#TLS 1.3-এর Cipher Suite
TLS 1.3-এ Suite-এর নামে থাকে শুধু AEAD Cipher আর Hash। Key Exchange আলাদাভাবে ঠিক হয় (supported_groups, key_share), Signature-ও (signature_algorithms)। Suite আছে মাত্র পাঁচটা:
| Suite | মন্তব্য |
|---|---|
TLS_AES_128_GCM_SHA256 | বাধ্যতামূলক; সবচেয়ে বেশি চলে |
TLS_AES_256_GCM_SHA384 | লম্বা Key; সরকারি নিয়মে প্রায়ই চায় |
TLS_CHACHA20_POLY1305_SHA256 | Software-এ দ্রুত; AES Hardware ছাড়া ফোনে এটাই পছন্দ |
TLS_AES_128_CCM_SHA256 | ছোট IoT Device-এর জন্য |
TLS_AES_128_CCM_8_SHA256 | IoT-র জন্য ছোট Tag; “Recommended না” হিসেবে চিহ্নিত |
ভুল Config করার মতো দুর্বল কিছু আর বাকি নেই: প্রতিটা Suite AEAD, প্রতিটা Key Exchange অস্থায়ী।
#TLS 1.3 কী কী বাদ দিল, আর কেন
| বাদ গেছে | কেন |
|---|---|
| RSA Key Transport আর Static Diffie-Hellman | Forward Secrecy নেই; Padding-oracle আক্রমণ |
| আলাদা MAC-সহ CBC Mode-এর Cipher | Padding-oracle আর Timing আক্রমণ (Lucky 13 আর আরও কিছু) |
| RC4, 3DES, Export Cipher, MD5 আর SHA-1 Signature | ভাঙা বা খুব দুর্বল |
| Compression | Response-এর আকার দেখে গোপন তথ্য ফাঁস হতো (CRIME আক্রমণ) |
| Renegotiation | আক্রমণ আর জটিলতার উৎস; জায়গা নিয়েছে KeyUpdate আর Handshake-পরবর্তী পরিচয় প্রমাণ |
| নিজের বানানো Diffie-Hellman Group | Server দুর্বল Group বাছত; এখন শুধু নাম দেওয়া, যাচাই করা Group |
| ChangeCipherSpec (আসল Message হিসেবে) | Key বদল এখন নিজে থেকেই বোঝা যায়; পুরোনো Middlebox-কে শান্ত রাখতে শুধু একটা নকল কপি যায় |
| আলাদা আলাদা ব্যবস্থা হিসেবে Session ID আর Ticket | একসাথে মিশে হয়েছে Pre-shared Key (PSK) |
আরও দুটো সুরক্ষার নাম জানা দরকার। Downgrade সুরক্ষা: 1.3 জানা Server যদি শেষে 1.2-তে কথা বলে, সে নিজের Random-এর শেষ ৮ Byte-এ একটা নির্দিষ্ট চিহ্ন লিখে দেয়; 1.3 জানা Client সেটা দেখলে বোঝে আক্রমণকারী Hello থেকে 1.3 মুছে দিয়েছে, আর থেমে যায়। Middlebox-এর সাথে মানিয়ে চলা: TLS 1.3 Handshake-কে সাজিয়ে TLS 1.2-এর Session Resumption-এর মতো দেখানো হয়, কারণ মাপার মতো সংখ্যক Firewall নতুন কিছু দেখলেই ভেঙে পড়ত। TLS 1.0 আর 1.1 আনুষ্ঠানিকভাবে বাতিল (RFC 8996, ২০২১); আজ Browser-এর বেশিরভাগ Connection TLS 1.3-এ, আর TLS 1.2 টিকে আছে পুরোনো Client, IoT আর Enterprise System-এ।
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.3 Handshake-এ Network-এর কোনো নজরদার সবশেষে কোন Message-টা খোলা অবস্থায় পড়তে পারে?
#Round Trip গোনা
Round Trip-এর দৌড়: দুটো Handshake পাশাপাশি
দুটো লেন একই মুহূর্তে, একই ১০০ ms-এর পথে শুরু করে। প্রতিটা ধাপ আধা Round Trip, মানে ৫০ ms। দেখো, কোন লেনের Request কখন অবশেষে বের হতে পারে।
পরিস্থিতি
লেন A: TCP + TLS 1.2। লেন B: TCP + TLS 1.3। একদম নতুন Connection, কিছুই আগে থেকে জমা নেই।
Race-এর ঘড়ি (১০০ ms Round Trip)
| লেন | কত Round Trip গেল | ঘড়ি |
|---|---|---|
| A: TLS 1.2 | 0 | 0 → 50 ms |
| B: TLS 1.3 | 0 | 0 → 50 ms |
দুই Client-ই TCP Handshake শুরু করে। TLS-এর আগে একটা চালু Byte Stream লাগে, তাই TLS-এর Version যা-ই হোক, এই Round Trip দুই লেনকেই দিতে হয়।
দৌড়ে যা দেখলে, নিচের টেবিলেও তা-ই। ১০০ ms Round Trip-এ একদম নতুন Connection-এর খরচ:
| ব্যবস্থা | Request-এর আগে কত Round Trip | Response আসে (১০০ ms RTT) | ২০০ ms RTT-তে |
|---|---|---|---|
| TCP + TLS 1.2 | ৩ | ৪০০ ms | ৮০০ ms |
| TCP + TLS 1.3 | ২ | ৩০০ ms | ৬০০ ms |
| TCP + TLS 1.3, HelloRetryRequest | ৩ | ৪০০ ms | ৮০০ ms |
| TCP + TLS 1.3, PSK Resumption | ২ (Certificate নেই, সস্তা) | ৩০০ ms | ৬০০ ms |
| TCP + TLS 1.3, 0-RTT | ১ (শুধু TCP) | ২০০ ms | ৪০০ ms |
| QUIC (ভেতরে TLS 1.3) | ১ | ২০০ ms | ৪০০ ms |
| QUIC-এ 0-RTT | ০ | ১০০ ms | ২০০ ms |
| আবার ব্যবহার করা Connection | ০ | ১০০ ms | ২০০ ms |
“Response আসে”-তে Request-এর নিজের এক Round Trip ধরা আছে। DNS আর কোনো Redirect থাকলে সেটা আলাদা যোগ হবে।
আর কীসে সময় যায়। CPU এখন খুব কমই আটকায়: X25519 Key Exchange-এ লাগে কয়েক দশ Microsecond, ECDSA P-256 Signature-এও কয়েক দশ Microsecond, RSA-2048 Signature-এ মোটামুটি এক Millisecond (ব্যস্ত Server ECDSA Certificate পছন্দ করে মূলত এজন্যই)। আকার বেশি গুরুত্বপূর্ণ: ৩–৫ KB-এর Certificate Chain আর ১–২ KB-এর Post-quantum Key Share-কে TCP-র প্রথম Congestion Window-তে (প্রায় ১৪ KB) আঁটতে হবে; ফোলানো Chain বা RSA-4096 Key Server-এর চালানকে সেই সীমা পার করিয়ে আরেকটা Round Trip যোগ করতে পারে। Certificate Compression (RFC 8879) এখানে সাহায্য করে। সবচেয়ে বড় হাতিয়ার হলো Handshake একেবারেই না করা: Keep-alive, Connection Pool, Resumption, আর ব্যবহারকারীর কাছের Edge-এ TLS শেষ করা, যাতে Round Trip-টাই ২০০-র বদলে ১০ ms হয়।
#Session Resumption আর 0-RTT
Resumption আর 0-RTT Early Data, আর Replay কেন গুরুত্বপূর্ণ
Client-এর কাছে গতকালের একটা Ticket আছে। আক্রমণকারী Packet রেকর্ড করে আবার পাঠাতে পারে, কিন্তু Decrypt করতে পারে না।
পরিস্থিতি
Ticket-টা Pre-shared Key হিসেবে দেওয়া হয়, সাথে একটা “Binder” (একটা HMAC, যা প্রমাণ করে Secret-টা সত্যিই Client-এর কাছে আছে) আর একটা নতুন Key Share। Browser psk_dhe_ke Mode চালায়: PSK আর সাথে নতুন ECDHE, এতে Forward Secrecy থেকে যায়।
TLS 1.2-এ Resume করার দুটো উপায় ছিল। Session ID-তে Server সাম্প্রতিক Session-গুলোর একটা Cache রাখে; Load Balancer-এর পেছনে Client প্রায়ই এমন Server-এ গিয়ে পড়ে যার কাছে সেটা নেই। Session Ticket-এ (RFC 5077) Server Session-এর অবস্থাটা একটা Ticket Key দিয়ে Encrypt করে Client-কেই দিয়ে দেয়, নিজে কিছু রাখে না; বহরের প্রতিটা Server-কে সেই Ticket Key ভাগ করে নিতে হয়। ছোট (Abbreviated) Handshake-এ লাগে ১ Round Trip, Certificate বাদ। দুর্বল জায়গা: TLS 1.2-এ Resume করা Session-এ নতুন Key Exchange হয় না, তাই Ticket Key চুরি হলে ওই Key-এর অধীনে Resume হওয়া সব রেকর্ড করা Session খুলে যায়। Ticket Key কয়েক ঘণ্টা পরপর বদলাও, শুধু Memory-তে রাখো।
TLS 1.3 দুটোকে মিলিয়ে বানিয়েছে Pre-shared Key (PSK)। আগের বারের NewSessionTicket দেওয়া হয় pre_shared_key-এ, সাথে একটা Binder (একটা HMAC, যা প্রমাণ করে Secret-টা Client-এর কাছে আছে)। Browser যে psk_dhe_ke Mode চালায় তাতে নতুন একটা ECDHE Exchange-ও যোগ হয়, তাই Resumption-এও Forward Secrecy থাকে। Ticket সর্বোচ্চ ৭ দিন বাঁচে।
0-RTT Early Data আরেক ধাপ এগোয়: আগে এসেছে এমন Client Handshake শেষ হওয়ার আগেই, একদম প্রথম চালানে Encrypt করা Data পাঠিয়ে দেয়। Early Data Encrypt হয় এমন Key দিয়ে, যা আসে শুধু Ticket থেকে। এর দুটো দাম আছে:
১. Replay। প্রথম চালানে Server-এর দেওয়া কিছুই নেই, তাই আক্রমণকারী এটা রেকর্ড করে আবার পাঠাতে পারে, একই Server-এ বা অন্য Edge Server-এ, আর সেটা ঠিকঠাক Decrypt হবে। TLS এটা কিছুটা কমাতে পারে (একবার-ব্যবহারের Ticket, সাম্প্রতিক ClientHello-র Cache, ছোট সময়সীমা), কিন্তু ছড়ানো একটা বিশাল বহরে পুরোপুরি থামাতে পারে না।
২. Early Data-র নিজের কোনো Forward Secrecy নেই: এটা শুধু Ticket-এর Secret-এর ওপর নির্ভর করে।
তাই নিয়ম হলো: 0-RTT নাও শুধু নিরাপদ, Idempotent Request-এর জন্য (একটা Page-এর GET, দামের তালিকা, Static File)। যা কিছু অবস্থা বদলায়, তার জন্য Server Early Data প্রত্যাখ্যান করে, 425 Too Early উত্তর দেয় (RFC 8470), অথবা Early-Data: 1 Header দিয়ে Origin-এ পাঠায় যাতে Origin সিদ্ধান্ত নেয়; Client তখন Handshake-এর পরে আবার পাঠায়। nginx-এ ডিফল্ট হলো ssl_early_data off; যে CDN 0-RTT দেয়, সাধারণত শুধু GET Request-এর জন্য দেয়।
#যে Extension-গুলো Handshake-এর চেহারা ঠিক করে: SNI, ECH আর ALPN
SNI, Encrypted Client Hello আর ALPN: প্রথম Message কী ঠিক করে দেয়
একটাই IP Address, 203.0.113.10, shop.example.com আর blog.example.org দুটোই চালায়, প্রত্যেকের নিজের Certificate।
পরিস্থিতি
Hostname যায় ClientHello-র server_name Extension-এ, কারণ HTTP-র Host Header যাবে Handshake-এর পরে, Encrypt হয়ে।
SNI (Server Name Indication)। একটা IP Address হাজারটা HTTPS সাইট চালাতে পারে, কিন্তু HTTP-র Host Header আসে Handshake-এর পরে। তাই Client ClientHello-র server_name Extension-এ Hostname বসিয়ে দেয়, আর Server মিলে যাওয়া Certificate বাছে। Client যদি কোনো SNI না পাঠায় (কিছু পুরোনো HTTP Library, IP দিয়ে Connect করা Health Check), Server শুধু তার ডিফল্ট Certificate দেখাতে পারে, আর Client নাম না মেলার Error-এ আটকে যায়; কড়া Server এর বদলে unrecognized_name Alert পাঠায়। SNI খোলা লেখা, তাই TLS 1.3-এও পথের যে কেউ জানে তুমি কোন সাইটে যাচ্ছ।
ECH (Encrypted Client Hello)। সাইট নিজের DNS HTTPS Record-এ একটা ECH Public Key প্রকাশ করে (Lesson ১.৮)। Client আসল ClientHello (আসল SNI আর ALPN-সহ) Encrypt করে, আর সেটা মুড়ে দেয় একটা বাইরের ClientHello-তে, যার SNI হলো Provider-এর একটা সাধারণ Public নাম। ২০২৩ থেকে Chrome আর Firefox এটা চালায়, বড় CDN-ও দেয়। সাইট লুকায় কেবল তখনই, যখন অনেক সাইট Provider-এর একই Address ভাগ করে; নিজস্ব IP হলে Address-ই সাইট ধরিয়ে দেয়। নাম দেখে ছাঁকতে কিছু Network ECH বন্ধ রাখে।
ALPN (Application-Layer Protocol Negotiation)। Client কিছু Protocol প্রস্তাব করে (h2, http/1.1; QUIC-এ h3), আর Server Handshake-এর ভেতরেই একটা বাছে, তাই আলাদা কোনো Round Trip খরচ হয় না। কোনোটাই না মিললে কড়া Server উত্তর দেয় no_application_protocol। চেনা উদাহরণ gRPC: তার HTTP/2 লাগে, অথচ সামনের Proxy শুধু HTTP/1.1 জানে।
#Post-quantum Key Exchange
ভবিষ্যতের কোনো বড় Quantum Computer X25519 আর RSA ভাঙতে পারবে। Signature-এর গুরুত্ব শুধু Handshake-এর মুহূর্তে, কিন্তু Key Exchange-এর গুরুত্ব যতদিন Data গোপন থাকা দরকার ততদিন: আক্রমণকারী এখন জমিয়ে রেখে পরে Decrypt করতে পারে। তাই Browser আগে Key Exchange নিয়েই এগিয়েছে।
X25519MLKEM768 Group পুরোনো X25519-কে মেশায় ML-KEM-768-এর সাথে; ML-KEM হলো Lattice-ভিত্তিক Key-encapsulation পদ্ধতি, NIST ২০২৪ সালে যেটার মানদণ্ড ঠিক করেছে (FIPS 203)। Shared Secret দুটোর ওপরই নির্ভর করে, তাই যেকোনো একটা টিকে থাকলেই Connection নিরাপদ। Chrome ২০২৪ সালে এটা ডিফল্ট করেছে, Firefox পেছনে পেছনে এসেছে, Apple ২০২৫-এর Operating System-এ যোগ করেছে, আর OpenSSL 3.5 (২০২৫) ডিফল্টভাবেই এটা দেয়; বড় CDN Browser Traffic-এর বড় একটা অংশে ইতিমধ্যে এটাই চালায়।
দাম হলো আকার: শুধু Client-এর ML-KEM Share-ই ১১৮৪ Byte, Server-এর উত্তর ১০৮৮, তাই ClientHello বেড়ে হয় প্রায় ১.৮ KB, লাগে দুটো TCP Segment। কিছু পুরোনো Middlebox Hello-টা এক Packet-এ আশা করত, তারা এটা ফেলে দিয়েছে; লক্ষণ হিসেবে দেখা যায় ঝুলে থাকা, কোনো TLS Error না (নিচের ব্যর্থতার Animation-এর তৃতীয় Scenario)। Certificate আর তার Signature এখনো পুরোনো ধাঁচের; Post-quantum Signature আকারে বড়, সেগুলো এখনো ধীরে ধীরে চালু হচ্ছে।
#TLS কোথায় শেষ হয়: Termination, Re-encryption, Passthrough
TLS কোথায় শেষ হয়: Termination, Re-encryption আর Passthrough
একই Client, একই Backend; Load Balancer বসানোর তিনটা উপায়। নিচের টেবিলে দেখো Load Balancer কী কী দেখতে পায়।
পরিস্থিতি
Certificate থাকে Load Balancer-এর কাছে, সে-ই Decrypt করে। Backend পায় সাধারণ HTTP।
Load Balancer কী দেখে
SNI
shop.example.com
Method + Path
POST /api/cart
Header, Cookie
সব পড়া যায়
Client-এর TLS Handshake শেষ হয় Load Balancer-এ, shop.example.com-এর Certificate আর Private Key তার কাছেই।
| Mode | Certificate কোথায় থাকে | Load Balancer কী করতে পারে | ভেতরের Traffic | সাধারণত কোথায় |
|---|---|---|---|---|
| Termination (Offload) | Load Balancer-এ | Layer 7-এর সব: Path আর Host দেখে Routing, Header যোগ, WAF, Cache, Compression | সাধারণ HTTP | বেশিরভাগ Web App, AWS ALB, nginx বা CDN-এর পেছনে |
| Re-encryption (Bridging) | Public Cert Load Balancer-এ, Internal Cert Backend-এ | Layer 7-এর সব | দ্বিতীয় একটা TLS Session দিয়ে Encrypt করা | Compliance (Card বা স্বাস্থ্যের তথ্য), Zero Trust |
| Passthrough | শুধু Backend-এ | শুধু SNI বা Port দেখে Routing; Path, Header, WAF, Cache কিছুই না | শুরু থেকে শেষ পর্যন্ত Encrypt করা | End-to-end Client mTLS, এমন Load Balancer যাকে Key দিয়ে বিশ্বাস করা যায় না, HTTP না এমন Protocol |
কীভাবে বাছবে। শুরু করো Edge-এ Termination দিয়ে: Certificate এক জায়গায় থাকে, Crypto-র বোঝা নামে, Routing নমনীয় হয়। ভেতরের Network-ও Encrypt রাখতে হলে Re-encryption যোগ করো; আজকাল এটাই স্বাভাবিক প্রত্যাশা। Passthrough নাও শুধু তখন, যখন Backend-কে নিজেকেই Client-এর TLS দেখতে হবে (End-to-end mTLS), বা Load Balancer-কে কখনোই Key দেওয়া যাবে না; তখন Layer 7-এর সুবিধা হারাবে, আর Client-এর IP আনতে হবে Proxy Protocol দিয়ে। AWS-এ ALB Terminate করে (আর HTTPS Target-এ আবার Encrypt করতে পারে); NLB TLS Listener দিয়ে Terminate করতে পারে, বা TCP Listener দিয়ে Passthrough।
Client mTLS যদি Load Balancer-এ যাচাই হয়, Backend আর Certificate দেখতে পায় না, তাই Load Balancer যাচাই করা পরিচয়টা একটা Header-এ পাঠায় (Envoy-তে x-forwarded-client-cert, AWS ALB-তে X-Amzn-Mtls-Clientcert)। Client-এর পাঠানো এমন যেকোনো Header Load Balancer-কে মুছে ফেলতে হবে, আর Backend-কে শুধু Load Balancer-এর Traffic নিতে হবে; নইলে Backend পর্যন্ত পৌঁছাতে পারে এমন যে কেউ যেকোনো পরিচয় দাবি করতে পারবে।
#HSTS আর Preload তালিকা, সংক্ষেপে
Lesson ১.৯-এ HSTS দেখেছ: Strict-Transport-Security Header পেলে Browser নিজে থেকেই সাইটটার জন্য HTTPS ব্যবহার করে, আর Certificate Error-কে কড়া ব্যর্থতা বানিয়ে দেয়। প্রথম ভিজিট তবু খোলা থাকে, সেটা সারায় Preload তালিকা। hstspreload.org-এ জায়গা পেতে সাইটকে বৈধ Certificate দিতে হয়, একই Host-এ HTTP থেকে HTTPS-এ Redirect করতে হয়, আর includeSubDomains ও preload-সহ অন্তত এক বছরের max-age পাঠাতে হয়। তালিকা থেকে নাম সরাতে মাসের পর মাস লাগে, তাই আগে ছোট max-age দিয়ে চালু করো। Handshake-এর দিক থেকে HSTS-এর লাভ হলো, সাধারণ HTTP-র Redirect-টা উঠে যায়; প্রথম নিরাপদ Byte-এর আগে আরেকটা Round Trip বাঁচে।
#যখন Handshake ব্যর্থ হয়
Production-এ যখন Handshake ব্যর্থ হয়
তিনটা ব্যর্থতা যা Browser-এ চট করে Test করলে ধরা পড়ে না। মাঝের জন হলো পথে যা-ই বসে আছে: Firewall, Proxy বা Load Balancer।
পরিস্থিতি
Certificate Renew করার পরে Server-এ শুধু Leaf Certificate বসানো হয়েছে, পুরো Chain না।
স্বাভাবিক Handshake শুরু।
Handshake ব্যর্থ হলে শেষ হয় একটা TLS Alert দিয়ে, আর তার নাম সাধারণত বলে দেয় কোথায় খুঁজতে হবে:
| লক্ষণ (Alert বা Error) | সাধারণ কারণ | সমাধান |
|---|---|---|
certificate_expired (৪৫), NET::ERR_CERT_DATE_INVALID | Renewal ব্যর্থ, বা Client-এর ঘড়ি ভুল | Renewal স্বয়ংক্রিয় করো, মেয়াদ শেষের অনেক আগে Alert; NTP দিয়ে সময় মেলাও |
| এক ধরনের Device-এ শুধু “এখনো বৈধ না” | Device ভুল ঘড়ি নিয়ে চালু হয়েছে (Battery-চালিত ঘড়ি নেই) | প্রথম TLS Call-এর আগে সময় মেলাও |
curl, Java, App-এ unable to get local issuer certificate; Browser-এ ঠিক | Server শুধু Leaf পাঠায়, Intermediate না | পুরো Chain বসাও; openssl s_client দিয়ে Test করো |
| শুধু কিছু Client থেকে Hostname মেলে না | SNI নেই, তাই ডিফল্ট Certificate যাচ্ছে | Client যেন SNI পাঠায়; IP দিয়ে করা Check-এ প্রত্যাশিত নাম বলে দাও |
protocol_version (৭০) | Client খুব পুরোনো (TLS 1.0/1.1), বা Server-এর সর্বনিম্ন খুব উঁচু | Client আপগ্রেড করো; Server-এর সর্বনিম্ন TLS 1.2 রাখো |
handshake_failure (৪০), “no shared cipher” | মিলে যাওয়া Cipher Suite বা Group নেই | Client ঠিক করো; মূল Endpoint-এ দুর্বল Suite বন্ধ রাখো |
no_application_protocol (১২০) | ALPN মেলে না, যেমন HTTP/1.1-only Proxy-র পেছনে gRPC (h2) | Proxy বা Load Balancer-এ h2 চালু করো |
unknown_ca (৪৮) | অন্য পাশ যাকে বিশ্বাস করে না এমন CA-র Certificate (ভুল Environment, Private CA বসানো নেই) | ঠিক CA Bundle বসাও; যাচাই বন্ধ করে কখনো “সমাধান” কোরো না |
certificate_required (১১৬) | Server Client Certificate চায়, কিন্তু কিছু আসেনি (mTLS) | Client Certificate Mount করো; Client Library সেটা পাঠায় কি না দেখো |
| ClientHello-র পরে ঝুলে থাকা বা Reset, কোনো Alert নেই | কোনো Middlebox বড় Post-quantum ClientHello ফেলে দিচ্ছে, বা MTU-র সমস্যা | Middlebox আপডেট করো; MTU আর Fragmentation দেখো |
#Mutual TLS (mTLS)
সাধারণ TLS/HTTPS-এ শুধু Client Server-এর পরিচয় যাচাই করে (One-way Authentication): Server প্রমাণ করে সে shop.example.com, আর TLS-এর স্তরে Client অচেনাই থাকে, পরে Password বা Token দিয়ে Login করে। Mutual TLS (mTLS)-এ Server আর Client দুজনেই একে অপরের Certificate যাচাই করে (Two-way Authentication)।
[ One-way TLS / সাধারণ HTTPS ]
Client ── Server-এর Certificate যাচাই ──► Server
[ Mutual TLS (mTLS) ]
Client ── Server-এর Certificate যাচাই ──► Server
Client ◄── Client-এর Certificate যাচাই ── Server
Mutual TLS: দুই পাশই Certificate দেখায়
Orders Service Payments Service-কে Call করে। দুজনের কাছেই কোম্পানির Private CA থেকে পাওয়া স্বল্পমেয়াদি Certificate।
পরিস্থিতি
একদম সাধারণ TLS 1.3 ClientHello। এতে “আমার Certificate আছে” বলা থাকে না: চাইবে কি না, সেটা Server ঠিক করে।
#কীভাবে কাজ করে
১. সাধারণ TLS-এর মতোই Server তার Certificate পাঠায়
Handshake শুরু হয় হুবহু সাধারণ Handshake-এর মতো।
২. Server Client-এর Certificate চায় (CertificateRequest)
বাড়তি ধাপ হিসেবে Server পাঠায় CertificateRequest, যাতে লেখা থাকে কোন Signature Algorithm আর চাইলে কোন CA সে মানে।
৩. Client নিজের Certificate আর Private Key দিয়ে Sign করা প্রমাণ পাঠায়
Client পাঠায় নিজের Certificate আর একটা CertificateVerify: নিজের Private Key দিয়ে Handshake Transcript-এর ওপর একটা Signature। Key কখনো Client ছেড়ে যায় না, যায় শুধু Key থাকার প্রমাণ। TLS 1.3-এ দুটোই Encrypt করা; TLS 1.2-এ Client Certificate খোলা অবস্থায় যেত, ফলে Client কে, সেটা সবাই দেখতে পেত।
৪. Server যাচাই করে, তবেই Connection মঞ্জুর
Server তার Client CA Bundle দিয়ে Chain, তারিখ আর Signature মিলিয়ে দেখে। কোনো একটা না মিললে একটা Alert দিয়ে Handshake শেষ:
certificate_required(Certificate নেই),unknown_ca(ভুল CA),certificate_expired, বাbad_certificate। তারপর আসে আলাদা একটা ধাপ, যেটা মানুষ ভুলে যায়: Authorisation (অনুমতি)। বৈধ Certificate বলে Call করছে কে; সে কী করতে পারবে, তা এখনো একটা নিয়মকে ঠিক করতে হয় (ওপরের শেষ Scenario)।
#কোথায় ব্যবহার হয়
- Microservice। ভেতরের Service-to-service Traffic নিরাপদ রাখতে, সাধারণত Istio বা Linkerd-এর মতো Kubernetes Service Mesh নিজে থেকেই করে।
- Zero Trust। প্রতিটা Workload আর Device-এর পরিচয় প্রমাণ করা, Network-এর “ভেতরে” আছে বলেই কাউকে বিশ্বাস না করা (Lesson ১.১২; Zero Trust-এর নকশা Chapter ৩৩-এ)।
- Financial আর B2B API। Bank, Payment Gateway আর Open Banking API প্রায়ই Partner-দের Client Certificate দেখাতে বলে, কখনো OAuth Token-কেও সেই Certificate-এর সাথে বেঁধে দেয় (OAuth আসবে Chapter ৩৪–৩৫-এ)।
- Device। IoT Device কারখানাতেই বসানো একটা Certificate দিয়ে নিজের Cloud-এ পরিচয় দেয়।
#Service-এর পরিচয়: SPIFFE আর SPIRE
একটা Service-এর Certificate-এ এমন একটা নাম লাগে, যা তোমার নিয়মের কাছে অর্থ বহন করে। SPIFFE হলো সেই নামের একটা খোলা মানদণ্ড: spiffe://example.com/ns/shop/sa/orders-এর মতো একটা URI (আগে Trust Domain, তারপর একটা Path; Istio Namespace আর Service Account ব্যবহার করে)। এটা থাকে একটা SVID-এ, সাধারণত একটা X.509 Certificate, যার URI SAN-এ ID বসানো। SPIRE হলো মূল বাস্তবায়ন: একটা Server যা পরিচয় Sign করে, আর প্রতিটা Node-এ একটা Agent, যে Workload-কে যাচাই করে (কোন Kubernetes Service Account, কোন Node, কোন Process), তারপর Local Socket দিয়ে তাকে Certificate দেয়। Istio আর Linkerd নিজেদের CA থেকে SPIFFE ধাঁচের পরিচয় দেয়।
#স্বল্পমেয়াদি Certificate আর Rotation
ভেতরের mTLS Certificate ইচ্ছে করেই স্বল্পমেয়াদি: SPIRE-এ ডিফল্ট এক ঘণ্টা, Istio আর Linkerd-এ ২৪ ঘণ্টা। তাহলে চুরি যাওয়া Key কাজে লাগে কয়েক ঘণ্টা, এক বছর না, আর Revocation তালিকার দরকার প্রায় থাকে না। দাম হলো, Renewal হয়ে যায় জরুরি পথ: Proxy মোটামুটি অর্ধেক মেয়াদে Renew করে, আর বাকি মেয়াদের চেয়ে বেশি সময় CA-তে পৌঁছানো না গেলে সব Call একসাথে ব্যর্থ হয় (Mesh Animation-এর শেষ Scenario)। CA-কে High Availability-তে চালাও, Renewal ব্যর্থ হলে আর Certificate-এর বয়স বাড়লে Alert দাও, আর এমন মেয়াদ বাছো যা CA-র সবচেয়ে খারাপ যে Outage তুমি সারাতে পারো তার চেয়ে লম্বা।
Client Certificate-এর জন্য Private CA ব্যবহার করো। Public CA Domain নামের জামিন দেয়, তোমার Service-এর না; আর ২০২৬ সাল জুড়ে Public Web CA-গুলো Client-authentication EKU-ওয়ালা Certificate দেওয়াই বন্ধ করছে (Chrome Root Program-এর নিয়ম), তাই Public Web Certificate-এর ওপর বানানো mTLS ভেঙে যায়।
#Service Mesh: Sidecar বনাম Ambient
Service Mesh-এ mTLS: পরিচয়, Proxy আর Rotation
Application-গুলো Local Proxy-র সাথে সাধারণ HTTP-তে কথা বলে; Proxy-গুলো Mesh CA-র Certificate দিয়ে mTLS করে।
পরিস্থিতি
প্রতিটা Pod-এর নিজের একটা Proxy Container (Istio-তে Envoy, Linkerd-এ linkerd2-proxy)।
চালু হওয়ার সময় প্রতিটা Proxy CA-কে প্রমাণ দেয় সে কোন Workload হিসেবে চলছে (Kubernetes Service Account, Node-এর প্রমাণ), আর পায় একটা স্বল্পমেয়াদি Certificate, যার URI SAN-এ তার SPIFFE ID। Private Key Pod-এর ভেতরেই তৈরি হয়, কখনো বাইরে যায় না।
Sidecar Mesh-এ প্রতিটা Pod পায় নিজের একটা Proxy (Istio-তে Envoy, Linkerd-এ linkerd2-proxy)। Application Localhost-এর সাথে সাধারণ HTTP-তে কথা বলে; Proxy-রা mTLS করে, নিয়ম খাটায়, Retry করে, Metric জমায়। Application-এ কোনো TLS Code লাগে না, কিন্তু প্রতিটা Pod-কে একটা Proxy-র Memory আর CPU গুনতে হয়, দুই পাশে একটা করে বাড়তি ধাপ, আর Proxy আপগ্রেড করলে Pod Restart হয়।
Ambient (Sidecar ছাড়া) Mode-এ, যা Istio-তে ২০২৪ সালের শেষ থেকে সবার জন্য চালু, প্রতি Node-এ একটা ভাগ করা Proxy (ztunnel) প্রতিটা Pod-এর নিজের পরিচয়ে mTLS Tunnel-এ Traffic বয়, আর Layer 4-এর নিয়ম খাটায়; দরকার হলে শুধু সেখানে একটা Waypoint Proxy Layer 7-এর নিয়ম যোগ করে। Cilium-ও Node-স্তরের এমন একটা ব্যবস্থা দেয়। একই নিশ্চয়তা, অনেক কম Proxy। Mesh-এর নকশা আর তার দরদাম আসবে Chapter ৩৩ আর ৪৬-এ।
#mTLS বনাম API Key বনাম JWT
| API Key | JWT (Bearer Token) | mTLS | |
|---|---|---|---|
| কী পাঠানো হয় | Header-এ একটা গোপন String | Claim আর মেয়াদসহ Sign করা একটা Token | শুধু Private Key থাকার একটা প্রমাণ |
| ধরা পড়লে বা Log-এ উঠলে | Rotate না করা পর্যন্ত ব্যবহারযোগ্য | মেয়াদ শেষ না হওয়া পর্যন্ত ব্যবহারযোগ্য | Private Key ছাড়া অকেজো |
| কাকে চেনায় | একটা Application বা Account | একজন User বা Service, Claim-সহ (Role, Scope) | একটা Workload বা Device (Certificate-এর Subject, SPIFFE ID) |
| স্তর | Application (HTTP) | Application (HTTP) | Transport (TLS) |
| TLS শেষ করা Proxy পার হয়? | হ্যাঁ | হ্যাঁ | না: Proxy-কে পরিচয়টা এগিয়ে দিতে হয় |
| পরিচালনা | দেওয়া সহজ; সব জায়গায় Rotate করা কঠিন | একটা Signing Key আর Issuer লাগে | CA, Certificate দেওয়া, Rotation, Trust Bundle লাগে |
| কোথায় সবচেয়ে ভালো | সাধারণ Public API, ব্যবহার মাপা | Service-জুড়ে End User-এর পরিচয় | Service-to-service, Partner, Device |
এরা প্রতিদ্বন্দ্বী না। Production-এ চেনা একটা নকশা হলো Workload-এর পরিচয়ের জন্য mTLS (কোন Service Call করছে), আর End User-এর জন্য JWT (কার হয়ে Call করছে); OAuth তো Token-কে Client Certificate-এর সাথে বেঁধেও দিতে পারে, যাতে চুরি যাওয়া Token অন্য কোথাও অকেজো (Chapter ৩৪–৩৫)।
#System Design-এ TLS
- TLS 1.3 পছন্দ করো; পুরোনো Client-এর জন্য TLS 1.2 রাখো শুধু ECDHE আর AEAD Suite দিয়ে; 1.0 আর 1.1 বন্ধ।
- Connection আবার ব্যবহার করো (Keep-alive, Pool, HTTP/2 আর HTTP/3)। সবচেয়ে দ্রুত Handshake হলো যেটা করতেই হয় না।
- Edge-এ Terminate করো, ব্যবহারকারীর কাছে, আর Edge থেকে Origin পর্যন্ত চালু, আবার Encrypt করা Connection রাখো।
- Resumption চালু, Ticket Key বদলানো আর বহরে ভাগ করা; 0-RTT শুধু Idempotent Path-এ, যদি আদৌ রাখো।
- Handshake-এর CPU কমাতে ECDSA Certificate (বা ECDSA আর RSA দুটোই); Chain ছোট আর সম্পূর্ণ রাখো।
- Edge-এ X25519MLKEM768 চালাও; দেখে নাও তোমার Middlebox দুই Packet-এর ClientHello পার হতে দেয় কি না।
- Certificate স্বয়ংক্রিয় করো আর তাদের বয়স নজরে রাখো; বেশিরভাগ TLS Outage হয় মেয়াদ, হারানো Intermediate, নয়তো ঘড়ির কারণে।
- ভেতরে: Private CA থেকে আসা, স্বল্পমেয়াদি, নিজে থেকে Rotate হওয়া Certificate দিয়ে mTLS, সাথে প্রতিটা Service-এর জন্য Authorisation-এর নিয়ম।
#নিজে করে দেখো
# পুরো TLS 1.3 Handshake-এর খুঁটিনাটি: Version, Cipher, Group, Certificate Chain
openssl s_client -connect example.com:443 -servername example.com -brief </dev/null
# জোর করে TLS 1.2 চালাও, পুরোনো ধাঁচের Cipher Suite-এর নাম দেখো
openssl s_client -connect example.com:443 -servername example.com -tls1_2 -brief </dev/null
# Post-quantum Hybrid Group চাও (OpenSSL 3.5 বা নতুন)
openssl s_client -connect example.com:443 -servername example.com -groups X25519MLKEM768 -brief </dev/null
# SNI ছাড়া: Shared Server ডিফল্ট হিসেবে কোন Certificate দেয় দেখো
openssl s_client -connect example.com:443 -noservername </dev/null | openssl x509 -noout -subject
# Server যে পুরো Chain পাঠায় তা দেখো (Certificate গোনো)
openssl s_client -connect example.com:443 -servername example.com -showcerts </dev/null
# Resumption: একটা Session রেখে দাও, তারপর আবার ব্যবহার করো ("Reused, TLSv1.3")
openssl s_client -connect example.com:443 -servername example.com -sess_out /tmp/s.pem </dev/null
openssl s_client -connect example.com:443 -servername example.com -sess_in /tmp/s.pem </dev/null | grep -i reused
# প্রতিটা ধাপের সময়: TCP Connect বনাম TLS Handshake
curl -so /dev/null -w "tcp %{time_connect} tls %{time_appconnect}\n" https://example.com
# Client-এর দিক থেকে Mutual TLS
curl --cert client.crt --key client.key --cacert internal-ca.pem https://api.internal.example.com/health
Wireshark-এ ClientHello দেখতে tls.handshake.type == 1 Filter দাও, আর server_name, supported_versions, key_share দেখো (X25519MLKEM768-এর Share ১২০০ Byte-এর বেশি)। একটা TLS 1.2 Capture, যেখানে Certificate Message পড়া যায়, তার সাথে একটা TLS 1.3 Capture মিলিয়ে দেখো, যেখানে ServerHello-র পরে সবই “Application Data”।
#সারসংক্ষেপ
এই Lesson-এর জন্য নোটের সারসংক্ষেপের সারিগুলো, খুঁটিনাটি যোগ করে:
| বিষয় | সারকথা |
|---|---|
| TLS 1.2 বনাম 1.3 | TLS 1.2-এ লাগে ২ RTT (ClientHello; ServerHello, Certificate, ServerKeyExchange, ServerHelloDone; ClientKeyExchange, ChangeCipherSpec, Finished; ChangeCipherSpec, Finished)। TLS 1.3-এ ১ RTT (ClientHello-তেই Key Share, ServerHello-র পরে সব Encrypt করা), আর Resumption-এ 0-RTT Early Data চলে, যা নিরাপদ শুধু Idempotent Request-এর জন্য। |
| mTLS | Client আর Server দুজনেই একে অপরের Certificate যাচাই করে (CertificateRequest, Client-এর Certificate আর CertificateVerify)। ব্যবহার হয় Microservice-এর মধ্যে, Zero Trust-এ, আর Financial ও B2B API-তে, Private CA থেকে আসা স্বল্পমেয়াদি Certificate দিয়ে। |
মূল কথাগুলো
- প্রতিটা Handshake-কে Algorithm-এ একমত হতে হয়, Key-তে একমত হতে হয়, Server-এর (আর mTLS-এ Client-এরও) পরিচয় প্রমাণ করতে হয়, আর প্রমাণ করতে হয় Transcript কেউ বদলায়নি (Finished)।
- TLS 1.2: ২ RTT। ClientHello → ServerHello, Certificate (খোলা), ServerKeyExchange (Sign করা ECDHE Key), ServerHelloDone → ClientKeyExchange, ChangeCipherSpec, Finished → ChangeCipherSpec, Finished। Pre-master → Master Secret (দুটো Random-সহ PRF) → Key Block।
- RSA Key Transport-এ Forward Secrecy নেই: পরে চুরি যাওয়া Key রেকর্ড করা Traffic খুলে দেয়। ECDHE এটা সারায়; TLS 1.3 শুধু অস্থায়ী Key Exchange চালাতে দেয়।
- TLS 1.3: ১ RTT। ClientHello-তেই Key Share; ServerHello-র পরে সব Encrypt করা (EncryptedExtensions, Certificate, CertificateVerify, Finished); Transcript-এর সাথে বাঁধা HKDF Key Schedule; HelloRetryRequest-এ একটা Round Trip বাড়ে; মাত্র ৫টা AEAD Suite; RSA Key Exchange, CBC, RC4, Compression আর Renegotiation বিদায়।
- Resumption: 1.2-এ Session ID আর Ticket, 1.3-এ PSK (Forward Secrecy-র জন্য সাথে ECDHE)। 0-RTT প্রথম চালানেই Data পাঠায়, কিন্তু Replay হতে পারে: শুধু Idempotent Request, বাকিদের জন্য
425 Too Early। - SNI Certificate বাছে আর খোলা লেখা; ECH একটা সাধারণ নামের পেছনে সেটা লুকায়; ALPN Handshake-এর ভেতরেই h2/http/1.1/h3 বাছে। X25519MLKEM768 হলো ডিফল্ট Hybrid Post-quantum Key Exchange, এতে ClientHello হয় প্রায় ১.৮ KB।
- Termination দেয় Layer 7-এর সুবিধা, ভেতরে খোলা লেখা; Re-encryption ভেতরেও Encrypt করে; Passthrough End-to-end TLS রাখে কিন্তু Layer 7 হারায়। HSTS Preload প্রথম সাধারণ HTTP Request-টাও তুলে দেয়।
- চেনা ব্যর্থতা: মেয়াদ শেষ, ঘড়ির গরমিল, হারানো Intermediate, SNI নেই, Version বা Cipher না মেলা, ALPN না মেলা, অচেনা CA, Client Certificate নেই, বড় Hello ফেলে দেওয়া Middlebox।
- mTLS: CertificateRequest → Client-এর Certificate + CertificateVerify → Server যাচাই করে, তারপর অনুমতি দেয়। স্বল্পমেয়াদি Certificate-এ SPIFFE ID, নিজে থেকে Rotate হয়; Sidecar বা Ambient Mesh কাজটা করে দেয়। Service-এর জন্য mTLS আর User-এর জন্য JWT একসাথে চালাও।
আগে নিজে উত্তর দাও, তারপর ব্যাখ্যাটা পড়ো। ঠিক হলেও পড়ো, কারণ ভুল Option-গুলো কেন ভুল, সেটাও ওখানে আছে।
নিজেকে যাচাই করোপ্রশ্ন
প্রতিটা TLS Handshake-কে কোন চারটা লক্ষ্য পূরণ করতেই হয়?
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.2-এর ECDHE Handshake-এ ServerKeyExchange Message-এ কী থাকে?
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.2-এ Server তার প্রথম চালানেই Finished পাঠাতে পারে না কেন?
নিজেকে যাচাই করোপ্রশ্ন
এক আক্রমণকারী দুই বছর ধরে একটা কোম্পানির TLS 1.2 Traffic রেকর্ড করেছে। আজ সে Server-এর RSA Private Key চুরি করল। রেকর্ড করা কোন Session-গুলো সে Decrypt করতে পারবে?
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.3 কেন RSA Key Transport বাদ দিল, তার দুটো কারণ বাছো। (দুটো বাছো।)
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.2-এর Suite TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 পড়ো। কোন কথাটা ঠিক?
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.2-এর তুলনায় TLS 1.3-এ ঠিক কোন জিনিসটা একটা Round Trip বাঁচায়?
নিজেকে যাচাই করোপ্রশ্ন
একটা FIPS-only Gateway শুধু P-256 নেয়। একটা পুরোনো Client শুধু X25519-এর Key Share পাঠায়, তবে supported_groups-এ P-256-ও রাখে। কী হবে?
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.3-এর Key Schedule নিয়ে কোন দুটো কথা ঠিক? (দুটো বাছো।)
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.3-এ কতগুলো Cipher Suite আছে, আর তারা কী ঠিক করে?
নিজেকে যাচাই করোপ্রশ্ন
কোনটা TLS 1.3-এ বাদ যায়নি?
নিজেকে যাচাই করোপ্রশ্ন
একজন Security Engineer একটা TLS 1.3 Capture খুলে অবাক: Certificate দেখা যাচ্ছে না কেন?
নিজেকে যাচাই করোপ্রশ্ন
১০০ ms Round Trip-এর পথে একদম নতুন TCP + TLS 1.2 Connection-এ প্রথম Request-এর Response কখন আসে, আর TCP + TLS 1.3-এ?
নিজেকে যাচাই করোপ্রশ্ন
একটা দল তাদের API TCP + TLS 1.3 থেকে QUIC-এ (HTTP/3) নিল। নতুন Connection-এ কোন Round Trip-টা বাঁচল?
নিজেকে যাচাই করোপ্রশ্ন
Load Balancer-এর পেছনে TLS 1.2-এর Session ID দিয়ে প্রায়ই Resume হতো না, অথচ Session Ticket দিয়ে হতো। কেন?
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.2-এর Ticket Key কয়েক ঘণ্টা পরপর বদলাতে হয় কেন?
নিজেকে যাচাই করোপ্রশ্ন
কোন দুটো Request TLS 1.3 0-RTT Early Data হিসেবে নেওয়া যুক্তিসঙ্গত? (দুটো বাছো।)
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
একটা Edge Server 0-RTT Early Data হিসেবে POST /transfer পেল। সঠিক আচরণ কী?
নিজেকে যাচাই করোপ্রশ্ন
এক আক্রমণকারী রেকর্ড করা একটা 0-RTT প্রথম চালান একই CDN-এর অন্য একটা Edge Server-এ আবার পাঠাল। এটা কেন সফল হতে পারে?
নিজেকে যাচাই করোপ্রশ্ন
একটা পুরোনো Monitoring Script ৫০টা সাইট চালানো একটা Server-এ https://203.0.113.10/health-এ Connect করে, আর Hostname না মেলার Error-এ ব্যর্থ হয়। সাইটের নাম দিয়ে Browser ঠিকই চলে। সম্ভাব্য কারণ কী?
নিজেকে যাচাই করোপ্রশ্ন
Encrypted Client Hello কী লুকায়, আর আসলে কখন কাজে লাগে?
নিজেকে যাচাই করোপ্রশ্ন
নতুন একটা Proxy-র মধ্য দিয়ে একটা gRPC Client no_application_protocol Alert নিয়ে ব্যর্থ হচ্ছে। সমাধান কী?
নিজেকে যাচাই করোপ্রশ্ন
বড় Quantum Computer আসার বহু বছর আগেই Browser কেন Hybrid Post-quantum Key Exchange (X25519MLKEM768) চালু করছে?
নিজেকে যাচাই করোপ্রশ্ন
Browser আপডেটে Hybrid Post-quantum Key Share চালু হওয়ার পরে এক Corporate Firewall-এর পেছনের User-দের HTTPS সাইট ঝুলে থাকছে, কোনো Certificate Error নেই। সবচেয়ে সম্ভাব্য কারণ কী?
নিজেকে যাচাই করোপ্রশ্ন
একটা দলের Load Balancer-এ Path দেখে Routing আর WAF দরকার, আবার Compliance-এর জন্য ভেতরের Network-ও Encrypt করা চাই। কোন Mode মানায়?
নিজেকে যাচাই করোপ্রশ্ন
একটা Partner API ALB-তে Client Certificate যাচাই করে, আর একটা Header-এ পরিচয়টা Backend-এ পাঠায়। কোন দুটো নিয়ন্ত্রণ বাধ্যতামূলক? (দুটো বাছো।)
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
TLS 1.3-এর Mutual TLS Handshake-এ Certificate যে তার, তা প্রমাণ করতে Client কী পাঠায়?
নিজেকে যাচাই করোপ্রশ্ন
orders Service-এর নতুন Deployment payments-কে Call করতে পারছে না। payments-এর Log-এ unknown_ca Alert। কোন কারণটা সবচেয়ে মেলে?
নিজেকে যাচাই করোপ্রশ্ন
reviews Service একদম বৈধ একটা Mesh Certificate দেখিয়ে payments-এ POST /charge Call করল। কী হওয়া উচিত, আর কেন?
নিজেকে যাচাই করোপ্রশ্ন
SPIFFE আর স্বল্পমেয়াদি Certificate নিয়ে কোন দুটো কথা সত্যি? (দুটো বাছো।)
বেছে নাও ২
নিজেকে যাচাই করোপ্রশ্ন
Sidecar Service Mesh আর Istio-র Ambient Mode-এর মূল পার্থক্য কী?
নিজেকে যাচাই করোপ্রশ্ন
একটা Internal API এখন একটা Shared API Key ব্যবহার করে। Security Review চাইছে এমন Caller-পরিচয়, যা Log বা Traffic থেকে ধরা পড়লেও অকেজো। কোন পদ্ধতি সবচেয়ে মানায়?
নিজেকে যাচাই করোপ্রশ্ন
নোটে বলা আছে, TLS 1.3 আবার Connect করার সময় 0-RTT দেয়। কোন সংশোধনটা সবচেয়ে গুরুত্বপূর্ণ?