WireGuard cryptokey routing কীভাবে কাজ করে?
WireGuard-এর cryptokey routing কীভাবে কাজ করে তা জানুন। AllowedIPs কীভাবে রাউটিং টেবিল ও অ্যাক্সেস লিস্ট হিসেবে কাজ করে এবং Noise হ্যান্ডশেক প্রক্রিয়ার বিস্তারিত ব্যাখ্যা এখানে রয়েছে।
WireGuard কীভাবে কাজ করে, এক কথায়
WireGuard প্রতিটি প্যাকেটকে একটি public key-এর সাথে যুক্ত করে কাজ করে। এই মেকানিজমটির একটি নাম আছে, cryptokey routing, এবং এটিই এর সম্পূর্ণ ডিজাইন: কোনো peer-এর পাশে থাকা AllowedIPs লাইনটি আপনার মেশিন থেকে বেরিয়ে যাওয়া প্যাকেটের জন্য রাউটিং টেবিল এবং সেই peer থেকে আসা প্যাকেটের জন্য অ্যাক্সেস কন্ট্রোল লিস্ট হিসেবে কাজ করে। একটি সেটিং, দুটি কাজ। AllowedIPs-কে এই দৃষ্টিভঙ্গিতে দেখুন, তাহলেই প্রতিটি WireGuard কনফিগারেশন ফাইল সহজবোধ্য হয়ে উঠবে।
এখানে IP address ভিত্তিক কোনো সেশন টেবিল বা ইউজার ডাটাবেস নেই। একজন peer মানে হলো একটি public key এবং সেই key-টি যে ঠিকানাগুলো ব্যবহার করতে পারবে তার একটি সেট। নেটওয়ার্কের পরিবর্তন সত্ত্বেও এই বাইন্ডিং ঠিক রাখার জন্যই হ্যান্ডশেক এবং টাইমারগুলো কাজ করে। আপনি যদি তত্ত্বের আগে একটি কার্যকরী টানেল তৈরি করতে চান, তবে আপনার নিজস্ব VPS-এ একটি self-hosted WireGuard VPN তৈরি করুন, তারপর কোনো কনফিগারেশন লাইন বুঝতে সমস্যা হলে এখানে ফিরে আসুন।
AllowedIPs একটি রাউটিং টেবিল এবং অ্যাক্সেস লিস্ট
প্রথমে আউটবাউন্ড বা বহির্গামী ট্র্যাফিকের বিষয়টি দেখা যাক। আপনার কার্নেল সাধারণ রাউটিং টেবিলের মাধ্যমে একটি প্যাকেটকে wg0 ডিভাইসের দিকে পাঠায়। এরপর WireGuard সেই প্যাকেটের গন্তব্য (destination) ঠিকানাকে প্রতিটি পিয়ারের (peer) জন্য নির্ধারিত AllowedIPs তালিকার সাথে মিলিয়ে দেখে, যেখানে দীর্ঘতম প্রিফিক্স (longest prefix) অগ্রাধিকার পায়। যদি কোনো পিয়ারের সাথে মিলে যায়, তবে সেই পিয়ারের পাবলিক কি (public key), সেশন কি (session key) এবং UDP এন্ডপয়েন্ট শনাক্ত করা হয়। প্যাকেটটি সেই পিয়ারের জন্য এনক্রিপ্ট করা হয় এবং সেখানে পাঠানো হয়।
যদি কোনো পিয়ারের AllowedIPs গন্তব্য ঠিকানাকে কভার না করে, তবে প্যাকেটটি পাঠানো হয় না, কারণ এটি এনক্রিপ্ট করার জন্য কোনো কি (key) পাওয়া যায় না।
ping: sendmsg: Required key not availableএই ত্রুটির অর্থ হলো: আপনি যে ঠিকানায় পৌঁছানোর চেষ্টা করছেন তা কোনো পিয়ারের তালিকায় নেই। অন্য একটি ত্রুটি, ping: sendmsg: Destination address required, এর অর্থ হলো একটি পিয়ারের সাথে মিল পাওয়া গেছে কিন্তু WireGuard-এর কাছে তার কোনো এন্ডপয়েন্ট নেই, কারণ সেটি কনফিগার করা হয়নি অথবা এখনো জানা সম্ভব হয়নি।
এখন ইনবাউন্ড বা আগত ট্র্যাফিকের বিষয়টি দেখা যাক। একটি UDP প্যাকেট লিসেন পোর্টে পৌঁছায়। WireGuard হেডারে থাকা রিসিভার ইনডেক্স থেকে সেশন খুঁজে বের করে, স্লাইডিং রিপ্লে উইন্ডোর বিপরীতে কাউন্টার চেক করে, এবং তারপর পেলোড ডিক্রিপ্ট ও অথেন্টিকেট করে। এর পরেই এটি ভেতরের প্যাকেটটি পড়ে এবং সেই প্যাকেটের উৎস (source) ঠিকানাকে অবশ্যই প্রেরক পিয়ারের AllowedIPs-এর ভেতরে থাকতে হবে। যদি তা না হয়, তবে প্যাকেটটি ড্রপ করা হয়। ডাইনামিক ডিবাগ চালু থাকলে, কার্নেল নিচের লাইনের মতো করে কারণটি প্রিন্ট করে:
wg0: Packet has unallowed src IP (10.8.0.9) from peer 2 (203.0.113.10:51820)এ কারণেই সার্ভার সাইডের একটি পিয়ার /32 পায়। AllowedIPs = 10.8.0.2/32 দিয়ে কনফিগার করা একটি পিয়ার শুধুমাত্র 10.8.0.2 থেকে প্যাকেট পাঠাতে পারে, অন্য কোনো ঠিকানা থেকে নয়। সেখানে 0.0.0.0/0 লিখলে সেই ক্লায়েন্ট আপনার টানেলের ভেতরের যেকোনো সোর্স অ্যাড্রেস ব্যবহার করে প্যাকেট পাঠাতে পারবে, এমনকি অন্য কোনো ক্লায়েন্টের ঠিকানাও।
ওভারল্যাপিং প্রিফিক্সের ক্ষেত্রে সুনির্দিষ্ট প্রিফিক্স অগ্রাধিকার পায়, কারণ এখানে দীর্ঘতম প্রিফিক্স ম্যাচ (longest prefix match) পদ্ধতি কাজ করে। দুটি পিয়ারে একই প্রিফিক্স থাকলে ভিন্ন আচরণ দেখা যায়: এন্ট্রিটি সর্বশেষ কনফিগার করা পিয়ারে চলে যায় এবং প্রথম পিয়ার সেই ট্র্যাফিক পাওয়া বন্ধ করে দেয়, তবে কোথাও কোনো ত্রুটি প্রদর্শিত হয় না। wg show wg0 allowed-ips কমান্ডটি কার্নেলে বর্তমানে কার্যকর টেবিলটি দেখায়, যা ডিস্কের ফাইল এবং চলমান অবস্থার মধ্যে অমিল থাকলে যাচাই করার জন্য গুরুত্বপূর্ণ।
ক্রিপ্টোকি রাউটিং বিবেচনায় কনফিগ ফাইল পড়া
সার্ভার সাইড:
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = <server private key>
[Peer]
PublicKey = <laptop public key>
AllowedIPs = 10.8.0.2/32ক্লায়েন্ট সাইড:
[Interface]
Address = 10.8.0.2/32
PrivateKey = <laptop private key>
[Peer]
PublicKey = <server public key>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
PersistentKeepalive = 25একই কিওয়ার্ড দুই পাশে বিপরীত ভূমিকা পালন করে। ক্লায়েন্টের ক্ষেত্রে এটি নির্দেশ করে "সব গন্তব্যের ট্রাফিক এই পিয়ারের কাছে পাঠাও"। সার্ভারের ক্ষেত্রে এটি নির্দেশ করে "এই পিয়ার থেকে শুধুমাত্র এই একটি অ্যাড্রেস গ্রহণ করো"। এই অসামঞ্জস্যতা মানগুলোর মধ্যে বিদ্যমান, কোনো নির্দিষ্ট রোলের মধ্যে নয়।
এই কিগুলোর অর্ধেক আসলে প্রোটোকলের অংশ নয়। Address, DNS, MTU, PostUp এবং SaveConfig হলো wg-quick-এর অংশ, যা একটি শেল স্ক্রিপ্ট এবং ইন্টারফেস সচল করার কাজ করে। কার্নেল এগুলো কখনোই দেখতে পায় না। wg-quick strip wg0 সেই সংক্ষিপ্ত কনফিগটি প্রিন্ট করে যা wg টুলটি মূলত লোড করে, এবং এই বিভাজনটি দেখার সবচেয়ে দ্রুত উপায় হলো এটি।
হ্যান্ডশেক আসলে যা করে
WireGuard-এর হ্যান্ডশেক হলো Noise Protocol Framework থেকে নেওয়া Noise_IKpsk2। IK অংশটি একজন সিস্টেম অ্যাডমিনিস্ট্রেটরের জন্য সবচেয়ে গুরুত্বপূর্ণ: ইনিশিয়েটরের কাছে রেসপন্ডারের স্ট্যাটিক পাবলিক কি আগে থেকেই জানা থাকে, কারণ এটি আপনার [Peer] ব্লকের PublicKey। এছাড়া ইনিশিয়েটর তার নিজের স্ট্যাটিক পাবলিক কি প্রথম মেসেজের ভেতরে এনক্রিপ্ট করে পাঠায়। তাই এখানে কোনো সার্টিফিকেট বিনিময় বা আইডেন্টিটি রাউন্ড ট্রিপের প্রয়োজন হয় না। কোনো প্যাসিভ পর্যবেক্ষক এটি বুঝতে পারে না যে কোন কি কল করছে, যদি না তার কাছে রেসপন্ডারের প্রাইভেট কি থাকে।
এর খরচ হলো একটি রাউন্ড ট্রিপ। ইনিশিয়েশন মেসেজটি 148 বাইটের এবং রেসপন্সটি 92 বাইটের, এরপরই ডেটা আদান-প্রদান শুরু হয়। প্রতিটি পক্ষ প্রতি হ্যান্ডশেকের জন্য একটি নতুন ephemeral Curve25519 কি-পেয়ার তৈরি করে এবং সেশন কিগুলো Diffie-Hellman ফলাফলের একটি চেইন থেকে আসে, যা স্ট্যাটিক এবং ephemeral কিগুলোকে মিশ্রিত করে। এরপর ephemeral প্রাইভেট কিগুলো মুছে ফেলা হয়, যা ফরোয়ার্ড সিক্রেসি নিশ্চিত করে: কেউ যদি আজ আপনার ট্রাফিক রেকর্ড করে এবং আগামী বছর সার্ভারের প্রাইভেট কি চুরিও করে, তবুও সে রেকর্ড করা ট্রাফিক পড়তে পারবে না।
একটি হ্যান্ডশেক ইনিশিয়েশনে TAI64N টাইমস্ট্যাম্প থাকে এবং প্রতিটি পিয়ার অপর প্রান্ত থেকে পাওয়া সবচেয়ে বড় টাইমস্ট্যাম্পটি মনে রাখে, তাই পুনরায় পাঠানো (replayed) ইনিশিয়েশন প্রত্যাখ্যান করা হয়। ডেটা প্যাকেটগুলো ননস (nonce) হিসেবে একটি 64-বিট কাউন্টার বহন করে এবং রিসিভার সম্প্রতি দেখা কাউন্টারগুলোর একটি স্লাইডিং উইন্ডো বজায় রাখে। ফলে TCP-এর মতো কোনো কানেকশন স্টেট ছাড়াই রিপ্লে এবং প্যাকেট এলোমেলো হয়ে যাওয়ার সমস্যাগুলো সমাধান করা হয়।
সেশন কিগুলো বেশিক্ষণ স্থায়ী হয় না এবং টাইমারগুলো কনফিগার করার পরিবর্তে কোডের ভেতরেই কম্পাইল করা থাকে।
The data behind this chart
[
{
"label": "REKEY_TIMEOUT",
"seconds": 5,
"notes": "resend a handshake initiation that got no answer"
},
{
"label": "KEEPALIVE_TIMEOUT",
"seconds": 10,
"notes": "send a keepalive after receiving data and sending none back"
},
{
"label": "REKEY_ATTEMPT_TIME",
"seconds": 90,
"notes": "give up on the handshake and report the peer as down"
},
{
"label": "REKEY_AFTER_TIME",
"seconds": 120,
"notes": "sender begins a fresh handshake for a new session key"
},
{
"label": "REJECT_AFTER_TIME",
"seconds": 180,
"notes": "the old session key is refused and traffic stops"
}
]এগুলো প্রোটোকল স্পেসিফিকেশনের ধ্রুবক, কোনো পরিমাপ নয়। এদের 5 টি পুরো সেশনের জীবনচক্র নিয়ন্ত্রণ করে। 120 সেকেন্ড ব্যবহারের পর প্রেরক নতুন হ্যান্ডশেক শুরু করে এবং 180 সেকেন্ড পর পুরনো কি সরাসরি প্রত্যাখ্যান করা হয়, তাই নতুন হ্যান্ডশেক সম্পন্ন না হওয়া পর্যন্ত ট্রাফিক বন্ধ থাকে। যে ইনিশিয়েশনের কোনো উত্তর পাওয়া যায় না, তা প্রতি 5 সেকেন্ড পরপর পুনরায় পাঠানো হয় এবং 90 সেকেন্ড পর তা বাতিল করা হয়। এই কারণেই wg show, latest handshake-কে আপেক্ষিক বয়স হিসেবে প্রদর্শন করে এবং একটি ব্যস্ত ও সুস্থ টানেলে এই বয়স কম থাকে। আপনি সক্রিয়ভাবে ট্রাফিক পাঠানোর সময়ও যদি এই বয়স বাড়তে থাকে, তবে বুঝতে হবে হ্যান্ডশেক ব্যর্থ হচ্ছে, টানেলটি অলস বসে নেই।
কেন একটি পিয়ারের কোনো ক্লায়েন্ট বা সার্ভার ভূমিকা নেই
উভয় প্রান্তেই একই কোড এবং একই কনফিগারেশন ফরম্যাট চলে। এখানে কোনো সার্ভার মোড নেই। আপনি যে অসামঞ্জস্যতা অনুভব করেন তা Endpoint থেকে আসে এবং Endpoint ঐচ্ছিক।
একটি কনফিগার করা এন্ডপয়েন্টসহ পিয়ার হ্যান্ডশেক শুরু করতে পারে। যার কোনো এন্ডপয়েন্ট নেই সে অপেক্ষা করে, তারপর প্রথম সঠিকভাবে অথেন্টিকেট হওয়া প্যাকেট থেকে অন্য প্রান্তের অ্যাড্রেস এবং পোর্ট জেনে নেয়। সেই জানা এন্ডপয়েন্টটি সংরক্ষিত থাকে এবং নতুন কোনো অ্যাড্রেস থেকে বৈধ প্যাকেট আসলে তা আপডেট হয়। রোমিং এভাবেই কাজ করে: একটি ল্যাপটপ ওয়াইফাই থেকে মোবাইল নেটওয়ার্কে চলে গেলেও একই টানেল বজায় থাকে, কারণ সেশনটি IP অ্যাড্রেসের পরিবর্তে কি (key) এবং ইনডেক্স দ্বারা চিহ্নিত হয়। কোনো কিছুই পুনরায় কানেক্ট হয় না, কারণ TCP-এর অর্থে কোনো কিছুই আগে কানেক্টেড ছিল না।
একই মেকানিজম একটি গুরুত্বপূর্ণ তথ্য তৈরি করে: পাবলিক অ্যাড্রেসধারী পিয়ার সবসময় অন্য প্রান্তের সর্বশেষ জানা পাবলিক IP ধরে রাখে এবং wg show তা প্রিন্ট করে।
স্থির প্রিমিটিভ, এবং আলোচনার কোনো সুযোগ নেই
WireGuard-এ কোনো ciphersuite তালিকা নেই। authenticated encryption-এর জন্য ChaCha20-Poly1305, key agreement-এর জন্য Curve25519, hashing-এর জন্য BLAKE2s এবং key derivation-এর জন্য HKDF ব্যবহৃত হয়। প্রতিটি ডেপ্লয়মেন্টে এগুলোই ব্যবহৃত হয়, তাই এখানে কোনো negotiation phase নেই যা বিশ্লেষণ করতে হবে এবং দুর্বল কোনো অপশনে নেমে যাওয়ার (downgrade) কোনো পথ নেই। এর বিনিময়ে যা পাওয়া যায় তা স্পষ্ট: যদি এই প্রিমিটিভগুলোর কোনো একটি ভেঙে পড়ে, তবে এর সমাধান হলো পুরো প্রোটোকলের একটি নতুন ভার্সন এবং উভয় প্রান্তে আপডেট করা, কোনো কনফিগারেশন পরিবর্তন নয়। এই একটি সিদ্ধান্ত TLS-ভিত্তিক টানেলের অধিকাংশ কোড এবং ব্যর্থতার কারণ দূর করে, যা WireGuard বনাম OpenVPN-এর তুলনার মূল বিষয়।
কেন পোর্টটি কোনো স্ক্যানারের উত্তর দেয় না
প্রতিটি হ্যান্ডশেক মেসেজে mac1 নামে একটি ফিল্ড থাকে। এটি একটি MAC (মেসেজ অথেন্টিকেশন কোড), যা রেসপন্ডারের স্ট্যাটিক পাবলিক কি (public key) থেকে প্রাপ্ত একটি কি (key) দিয়ে মেসেজের ওপর গণনা করা হয়। যে প্রেরক ওই পাবলিক কি জানে না, সে বৈধ mac1 তৈরি করতে পারে না। ফলে রিসিভার কোনো উত্তর না দিয়েই প্যাকেটটি ফেলে দেয়। কোনো এরর, রিসেট বা ICMP মেসেজ পাঠানো হয় না।
এর দৃশ্যমান ফলাফল হলো একটি UDP স্ক্যান, যা কোনো উত্তর পায় না।
sudo nmap -sU -p 51820 vpn.example.comnmap open|filtered রিপোর্ট করে, যা ফায়ারওয়াল দ্বারা নীরবে ড্রপ করা পোর্টের ক্ষেত্রেও একই উত্তর দেয়। WireGuard লিসেনিং মোডে থাকুক বা না থাকুক, পোর্টটি একইভাবে আচরণ করে; অন্তত তাদের জন্য যাদের কাছে আপনার পাবলিক কি নেই।
mac2 নামে একটি দ্বিতীয় ফিল্ড ডিনায়াল অফ সার্ভিস (DoS) চাপ সামলায়। রিসিভার যখন চাপের মুখে থাকে, তখন সে প্রেরকের সোর্স অ্যাড্রেসের সাথে যুক্ত একটি 64-বাইট কুকি রিপ্লাই পাঠায়। প্রেরক সেই কুকি ফেরত না পাঠানো পর্যন্ত রিসিভার কোনো ব্যয়বহুল পাবলিক কি সংক্রান্ত কাজ করতে অস্বীকার করে। এটি নিশ্চিত করে যে সোর্স অ্যাড্রেসটি আসল, এবং এটি শুধুমাত্র চাপের মুখেই সক্রিয় হয়।
কেন 0.0.0.0/0 একটি পিয়ারকে আপনার ডিফল্ট রাউট হিসেবে সেট করে
কারণ AllowedIPs হলো রাউটিং টেবিল, তাই AllowedIPs = 0.0.0.0/0, ::/0 ওই পিয়ারের জন্য প্রতিটি গন্তব্য দাবি করে। এটিই হলো সম্পূর্ণ ফুল টানেল সেটিংস।
যে রাউটিংয়ের মাধ্যমে এটি কাজ করে তা লাইনটির চেয়েও বেশি গুরুত্বপূর্ণ। wg0-এর মাধ্যমে একটি সাধারণ ডিফল্ট রাউট লুপ তৈরি করবে, কারণ আপনার ট্রাফিক বহনকারী এনক্রিপ্ট করা UDP প্যাকেটটিকেও মেশিন থেকে বের হতে হয় এবং এটি তার নিজস্ব ডিফল্ট রাউটের সাথে মিলে যায়। wg-quick পলিসি রাউটিং ব্যবহার করে এটি এড়িয়ে চলে। এটি WireGuard-এর নিজস্ব আউটগোয়িং প্যাকেটগুলোকে একটি fwmark দিয়ে চিহ্নিত করে, টানেল ডিফল্ট রাউটটিকে একটি আলাদা রাউটিং টেবিলে রাখে এবং এমন নিয়ম যোগ করে যাতে শুধুমাত্র চিহ্নবিহীন ট্রাফিকই সেখানে পৌঁছাতে পারে। ip rule show কমান্ডটি চালালে আপনি ফলাফল দেখতে পাবেন:
32764: from all lookup main suppress_prefixlength 0
32765: not from all fwmark 0xca6c lookup 51820
32766: from all lookup main0xca6c হলো হেক্সাডেসিমেলে 51820 এবং 51820 হলো টেবিল নম্বর। suppress_prefixlength 0 নিয়মটি মেইন টেবিলকে তার নিজস্ব ডিফল্ট রাউট এড়িয়ে চলতে বাধ্য করে, ফলে আপনার লোকাল সাবনেটের মতো নির্দিষ্ট রাউটগুলো কার্যকর থাকে এবং বাকি সবকিছু টানেল টেবিলে চলে যায়। স্প্লিট টানেলের ক্ষেত্রে এর কোনোটিরই প্রয়োজন হয় না: AllowedIPs = 10.8.0.0/24, 10.20.0.0/16-এর মতো একটি সংকীর্ণ তালিকা মেইন টেবিলে সাধারণ রাউট হিসেবে গণ্য হয়।
ফুল টানেল নিজে থেকে নেম রেজোলিউশন সমস্যার সমাধান করে না, কারণ আপনার ক্লায়েন্ট লোকাল নেটওয়ার্ক থেকে যে রেজলভারটি শিখেছে তা সাধারণত অপরিবর্তিত থাকে এবং তার রাউটটি বেশি নির্দিষ্ট হয়। এটি একটি আলাদা কাজ, যা WireGuard টানেলের বাইরে DNS লিক অংশে আলোচনা করা হয়েছে।
PersistentKeepalive আসলে কী কাজে লাগে
WireGuard-এ কোনো ট্রাফিক না থাকলে এটি কিছুই পাঠায় না। কোনো হার্টবিট, সেশন রিফ্রেশ বা নেটওয়ার্কে কোনো সিগন্যাল থাকে না। এই নীরবতা ব্যাটারির স্থায়িত্ব বাড়ায় এবং উপরে উল্লিখিত স্ক্যানার পরিস্থিতির ক্ষেত্রে সহায়ক, তবে এটি একটি নির্দিষ্ট সেটআপে সমস্যা তৈরি করে।
NAT (network address translation) বা stateful firewall-এর পেছনে থাকা কোনো পিয়ার কেবল তখনই বাইরে থেকে অ্যাক্সেসযোগ্য হয়, যখন সেই ডিভাইসে কোনো ম্যাপিং বিদ্যমান থাকে এবং সেই ম্যাপিংটি কোনো আউটগোয়িং প্যাকেট দ্বারা তৈরি হয়। সাধারণ UDP ম্যাপিংয়ের স্থায়িত্ব সাধারণত 30 সেকেন্ড থেকে শুরু হয়। একবার ম্যাপিংয়ের মেয়াদ শেষ হয়ে গেলে, পাবলিক সাইড থেকে আসা প্যাকেটগুলো মিডলবক্স দ্বারা ড্রপ করা হয় এবং NAT-এর পেছনে থাকা পিয়ার কিছু না পাঠানো পর্যন্ত টানেলটিকে অকার্যকর মনে হয়। PersistentKeepalive = 25 প্রতি 25 সেকেন্ডে একটি খালি অথেনটিকেটেড প্যাকেট পাঠায়, যা সবচেয়ে কম সময়ের সাধারণ লাইফটাইমের নিচে থাকে, ফলে ম্যাপিংটি সচল থাকে।
এটি NAT-এর পেছনে থাকা পিয়ারে সেট করুন। পাবলিক অ্যাড্রেস এবং ওপেন UDP পোর্ট থাকা কোনো সার্ভারে এটির প্রয়োজন নেই এবং সেখানে এটি সেট করলে কেবল অপ্রয়োজনীয় ট্রাফিক তৈরি হয়। এটিকে স্বয়ংক্রিয় কিপ-অ্যালাইভ (automatic keepalive)-এর সাথে গুলিয়ে ফেলবেন না, যা কোনো পিয়ার ডেটা রিসিভ করার 10 সেকেন্ড পর সক্রিয় হয় যদি তার নিজের পাঠানোর মতো কিছু না থাকে। সেটি সবসময় চালু থাকে এবং তা কনফিগার করা যায় না।
আপনার LAN-কে টানেলের মধ্য দিয়ে রাউট করা WireGuard-এর কোনো ফিচার নয়
ধরা যাক, peer B একটি হোম নেটওয়ার্ক 192.168.50.0/24-এ আছে এবং peer A-কে সেখানে পৌঁছাতে হবে। দুটি আলাদা সিস্টেমকে এই বিষয়ে একমত হতে হবে, যার মধ্যে কেবল একটি হলো WireGuard।
WireGuard-এর অংশ: A-এর AllowedIPs-এ 192.168.50.0/24 যোগ করুন। এটি A-কে ওই প্রিফিক্সটি B-এর দিকে রাউট করতে বাধ্য করে এবং B থেকে আসা ওই সোর্স অ্যাড্রেসযুক্ত প্যাকেটগুলো গ্রহণ করতে দেয়। এটি ছাড়া, ক্রিপ্টোকি রাউটিংয়ের কাছে গন্তব্যের জন্য কোনো কি (key) থাকে না এবং সোর্সের জন্য কোনো অনুমতি থাকে না।
কার্নেলের অংশ: B-এর ক্ষেত্রে net.ipv4.ip_forward অবশ্যই 1 হতে হবে, অন্যথায় কার্নেল প্রতিটি ডিক্রিপ্ট করা প্যাকেট ফেলে দেবে যা সরাসরি B-এর উদ্দেশ্যে নয়। B-এর ফায়ারওয়ালের ফরওয়ার্ড চেইনকে এই ট্রাফিক অনুমতি দিতে হবে। LAN-এর হোস্টগুলোর কাছে 10.8.0.0/24-এর দিকে ফিরে যাওয়ার একটি রুট থাকতে হবে, অথবা B-কে সোর্স NAT প্রয়োগ করতে হবে যাতে রিপ্লাইগুলো B-এর মাধ্যমেই ফিরে আসে।
WireGuard-এর কাজ শেষ হয় যখন এটি ডিক্রিপ্ট করা প্যাকেটটি কার্নেলের হাতে তুলে দেয়। এর পরের সবকিছু সাধারণ Linux রাউটিং এবং ফিল্টারিংয়ের বিষয়, আর এই কারণেই এই ব্যর্থতা nft list ruleset কাউন্টারে বা ip -s link show wg0-এ দেখা যায়, wg show-এ নয়। আপনি যদি ওয়েব ইন্টারফেসের মাধ্যমে পিয়ার ম্যানেজ করতে চান, তবে Docker-এ wg-easy চালানো আপনার জন্য পিয়ার এন্ট্রি তৈরি করে দেবে, যদিও ফরওয়ার্ডিং রুলগুলো হোস্টের দায়িত্বেই থাকে।
কেন WireGuard কার্নেলের ভেতরে থাকে
wg0 একটি নেটওয়ার্ক ডিভাইস ড্রাইভার। প্যাকেটগুলো সাধারণ রাউটিং স্ট্যাকের মাধ্যমে এতে পৌঁছায়, softirq কনটেক্সটে এনক্রিপ্ট হয় এবং ইউজারস্পেসে প্রবেশ না করেই একটি UDP সকেটের মাধ্যমে বেরিয়ে যায়। এই কারণেই এটি উচ্চ থ্রুপুট প্রদান করে এবং এই কারণেই মডিউলটির কোড মাত্র চার হাজার লাইনের মতো, যা পর্যালোচনা করার জন্য যথেষ্ট ছোট এবং 2020 সালের মার্চ মাসে মূলধারার Linux 5.6-এ মার্জ করা সম্ভব হয়েছে। Ubuntu 24.04 এবং Debian 13-এ এটি বিল্ট-ইন থাকে, তাই শুধুমাত্র wireguard-tools প্যাকেজটিই আলাদাভাবে প্রয়োজন হয়।
একটি সাধারণ ইন্টারফেস হওয়ার কিছু ব্যবহারিক সুবিধা রয়েছে। tcpdump -ni wg0 প্লেইনটেক্সট ইনার প্যাকেটগুলো দেখায়, অন্যদিকে tcpdump -ni eth0 udp port 51820 এনক্রিপ্ট করা আউটার প্যাকেটগুলো দেখায়; এই দুটির তুলনা করলে আপনি তাৎক্ষণিকভাবে বুঝতে পারবেন কোন দিকে সমস্যা হচ্ছে। netfilter এবং ট্রাফিক শেপিং wg0-কে অন্য যেকোনো লিংকের মতোই বিবেচনা করে। যেখানে কার্নেল মডিউলটি উপলব্ধ নয়, যেমন কন্টেইনার ভার্চুয়ালাইজেশনের ক্ষেত্রে যা হোস্ট কার্নেল শেয়ার করে, সেখানে wireguard-go একটি TUN ডিভাইসের মাধ্যমে ইউজারস্পেসে একই প্রোটোকল বাস্তবায়ন করে। এতে থ্রুপুটের ক্ষেত্রে প্রকৃত ক্ষতি হয়, কারণ প্রতিটি প্যাকেটকে দুইবার কার্নেল বাউন্ডারি অতিক্রম করতে হয়।
WireGuard আপনাকে যা থেকে রক্ষা করে না
এর থ্রেট মডেলটি ইচ্ছাকৃতভাবে সংকীর্ণ রাখা হয়েছে এবং এই প্রোটোকলটি এতটাই নিরব যে এটি ভুল ধারণার জন্ম দিতে পারে। বিষয়টি স্পষ্টভাবে নিচে দেওয়া হলো।
- এটি গোপন করে না যে আপনি WireGuard ব্যবহার করছেন। হ্যান্ডশেক মেসেজগুলোর আকার নির্দিষ্ট, প্রথম বাইটটি মেসেজের ধরন নির্দেশ করে এবং ট্রান্সপোর্ট প্রোটোকলটি হলো UDP। ডিপ প্যাকেট ইন্সপেকশন (DPI) সহজেই এটি শনাক্ত করতে পারে এবং যে নেটওয়ার্ক VPN পছন্দ করে না, তারা এটি ব্লক করতে পারে। ইচ্ছাকৃতভাবেই এতে কোনো অবফাসকেশন (obfuscation) রাখা হয়নি।
- এটি ডেটার পরিমাণ বা সময় গোপন করে না। পেলোডগুলো শুধুমাত্র 16-বাইট বাউন্ডারি পর্যন্ত প্যাড করা হয়, তাই একজন পর্যবেক্ষক এখনও দেখতে পায় আপনি কখন ডেটা পাঠাচ্ছেন এবং মোটামুটি কী পরিমাণ ডেটা পাঠাচ্ছেন।
- এটি সর্বশেষ পরিচিত এন্ডপয়েন্ট সংরক্ষণ করে। পাবলিক অ্যাড্রেস থাকা পিয়ারটি অন্য প্রান্তের বর্তমান পাবলিক IP সংরক্ষণ করে এবং
wg showতা প্রদর্শন করে। কনফিগারেশনে নির্দিষ্ট করা টানেল অ্যাড্রেসের সাথে এটি একটি স্থিতিশীল শনাক্তকারী হিসেবে কাজ করে, যা ব্যবহারকারীকে বিভিন্ন নেটওয়ার্কের মধ্যে অনুসরণ করে। আপনার নিজের VPS-এর ক্ষেত্রে এটি ঠিক আছে। বাণিজ্যিক পরিষেবাগুলো কেন এই প্রোটোকলের উপরে বাড়তি একটি স্তর যোগ করে, এটি তারও একটি কারণ। - এটি কোনো ব্যক্তিকে নয়, বরং একটি কি (key) অথেন্টিকেট করে। যার কাছে প্রাইভেট কি ফাইলটি আছে, সেই পিয়ার।
/etc/wireguard-কে মোড 700 এবং কি ফাইলগুলোকে 600 মোডে রাখুন। - এতে কোনো রিভোকেশন লিস্ট বা এক্সপায়ারি নেই। যখন আপনি প্রতিটি সার্ভার থেকে পিয়ার এন্ট্রি মুছে ফেলবেন, তখনই অ্যাক্সেস শেষ হবে এবং স্ট্যাটিক কিগুলো মুছে না ফেলা পর্যন্ত কার্যকর থাকবে।
এর কোনোটিই WireGuard-কে দুর্বল করে না। বরং এটি একে ছোট রাখে এবং ছোট হওয়াই এর মূল উদ্দেশ্য: এটি অথেন্টিকেশন এবং এনক্রিপশন নিশ্চিত করে, আর আইডেন্টিটি ম্যানেজমেন্ট ও অ্যাড্রেস অ্যালোকেশনের দায়িত্ব আপনার তৈরি করা ওপরের স্তরের ওপর ছেড়ে দেয়। WireGuard বনাম Tailscale-এ বর্ণিত কোঅর্ডিনেশন লেয়ারটি ঠিক সেই শূন্যস্থান পূরণ করার জন্যই বিদ্যমান, যা আপনি এইমাত্র পড়েছেন সেই একই ডেটা প্লেন ব্যবহার করে।
FAQ
WireGuard-এ cryptokey routing কী?
Cryptokey routing হলো এমন একটি নিয়ম যা প্রতিটি প্যাকেটকে একটি public key-এর সাথে যুক্ত করে। প্রতিটি peer এন্ট্রিতে AllowedIPs-এ প্রিফিক্সের একটি তালিকা থাকে। আউটবাউন্ড ট্রাফিকের ক্ষেত্রে, WireGuard প্যাকেটের গন্তব্যস্থলের সাথে প্রতিটি peer-এর তালিকার মিল খুঁজে বের করে (সবচেয়ে দীর্ঘ প্রিফিক্সকে অগ্রাধিকার দিয়ে), তাই এই তালিকাটি একটি রাউটিং টেবিল হিসেবে কাজ করে। ইনবাউন্ড ট্রাফিকের ক্ষেত্রে, প্যাকেটটি ডিক্রিপ্ট এবং অথেন্টিকেট হওয়ার পর, এর ভেতরের সোর্স অ্যাড্রেসটিকে অবশ্যই সেই peer-এর তালিকার অন্তর্ভুক্ত হতে হয়, অন্যথায় প্যাকেটটি ড্রপ করা হয়; অর্থাৎ এই তালিকাটি একটি অ্যাক্সেস কন্ট্রোল লিস্ট হিসেবেও কাজ করে। WireGuard-এ আলাদা কোনো রাউটিং কনফিগারেশন বা ইন্টারনাল ফায়ারওয়াল নেই, কারণ এই একটি তালিকাই উভয় কাজ সম্পন্ন করে।
আমার কি উভয় peer-এ PersistentKeepalive সেট করা প্রয়োজন?
না। এটি শুধুমাত্র NAT (network address translation) বা স্টেটফুল ফায়ারওয়ালের পেছনে থাকা সাইডে সেট করুন, যা সাধারণত ক্লায়েন্ট হয়ে থাকে। WireGuard নিষ্ক্রিয় অবস্থায় কোনো ডেটা পাঠায় না, তাই যে ম্যাপিংয়ের মাধ্যমে অপর প্রান্ত থেকে peer-এর সাথে যোগাযোগ করা হয় তা সাধারণত এক মিনিটের মধ্যে মেয়াদোত্তীর্ণ হয়ে যায় এবং টানেলটি একমুখীভাবে অকার্যকর মনে হয়। PersistentKeepalive = 25 প্রতি 25 সেকেন্ডে একটি খালি অথেন্টিকেটেড প্যাকেট পাঠায় এবং ম্যাপিংটিকে সচল রাখে। পাবলিক অ্যাড্রেস এবং ওপেন UDP পোর্ট থাকা কোনো peer-এর ক্ষেত্রে এর প্রয়োজন নেই।
টানেলের ভেতর ping করলে "Required key not available" কেন দেখায়?
কারণ গন্তব্যস্থলের অ্যাড্রেসটি কোনো peer-এর AllowedIPs-এর অন্তর্ভুক্ত নয়, তাই cryptokey routing প্যাকেটটি এনক্রিপ্ট করার জন্য কোনো কি (key) খুঁজে পায়নি এবং কার্নেল তা পাঠাতে অস্বীকৃতি জানিয়েছে। wg show wg0 allowed-ips চালান এবং এর আউটপুটের সাথে আপনার ping করা অ্যাড্রেসটি মিলিয়ে দেখুন। একই ধরনের ত্রুটি Destination address required একটি ভিন্ন সমস্যা নির্দেশ করে: এক্ষেত্রে একটি peer মিলেছে, কিন্তু WireGuard-এর কাছে এর জন্য কোনো endpoint নেই, কারণ কোনো endpoint কনফিগার করা হয়নি এবং সেই peer থেকে এখনো কোনো অথেন্টিকেটেড প্যাকেট আসেনি।
ফায়ারওয়াল কি WireGuard শনাক্ত এবং ব্লক করতে পারে?
হ্যাঁ। WireGuard আপনার ট্রাফিককে অথেন্টিকেট এবং এনক্রিপ্ট করে, তবে এটি নিজেকে আড়াল করার কোনো চেষ্টা করে না। হ্যান্ডশেক মেসেজগুলো নির্দিষ্ট 148 এবং 92 বাইটের হয়, প্রতিটি মেসেজের প্রথম বাইট এর ধরন শনাক্ত করে এবং ট্রান্সপোর্ট প্রোটোকল হিসেবে UDP ব্যবহৃত হয়, তাই ডিপ প্যাকেট ইন্সপেকশন (DPI) সহজেই এই প্রোটোকলটি শনাক্ত করতে পারে। যে নেটওয়ার্কগুলো UDP ব্লক করে বা প্রোটোকল ফিঙ্গারপ্রিন্টিং ব্যবহার করে, তারা এটিকে আটকে দেবে। টানেলটিকে আড়াল করতে হলে সেটিকে অন্য কোনো কিছুর ভেতর দিয়ে র্যাপ (wrap) করতে হবে, যা WireGuard-এর কোনো সেটিং নয় বরং একটি আলাদা টুলের কাজ।