উভয় সাইট একই LAN রেঞ্জ ব্যবহার করে, এবং ওভারল্যাপটিই আসলে ডিজাইনটি ভাঙে না। হাবকে কেবল গন্তব্য ঠিকানা ব্যবহার করে একটি সাইট বেছে নিতে হবে, আর দুটি অভিন্ন গন্তব্য তাকে বেছে নেওয়ার কিছুই দেয় না। একটি চালু অফিসকে টানেলের জন্য নতুন নম্বর দিয়ে সাজানো সাধারণত প্রতিটি প্রকাশিত সেবাকে টানেল বহন করতে পারে এমন আলাদা ঠিকানা দেওয়ার চেয়ে খারাপ লেনদেন। নিচের ডিজাইনটি প্রতি সাইটে একটি HTTPS সেবা প্রকাশ করে এবং আর কিছুই নয়।

কেন ওভারল্যাপটিই আসল সমস্যা নয়

WireGuard গন্তব্য অনুযায়ী ফরওয়ার্ড করে: একটি peer-এর AllowedIPs নির্ধারণ করে কোন peer প্যাকেট পাবে। দুটি peer একসাথে 10.10.7.0/24 ঘোষণা করতে পারে না, যদি না তাদের একটিকে প্রতিটি লুকআপে জিততে হয়। এটি peer টেবিলের বৈশিষ্ট্য, টানেলের নয়, তাই এখানে সমাধান হলো একটি ঠিকানা পরিকল্পনা, রাউটিং কৌশল নয়।

পরিকল্পনা হলো LAN একেবারেই ঘোষণা করা বন্ধ করা। বদলে প্রতি সেবার জন্য একটি alias ঘোষণা করুন, প্রতি সাইটে একটি ঠিকানা, এবং প্রতিটি সাইটের গেটওয়ে সেই alias-টি তার আসল অ্যাপ্লিকেশনে অনুবাদ করবে।

ব্যবহারকারী দুটি অনন্য ঠিকানা রাউট করে, দ্ব্যর্থক প্রিফিক্সটি কখনো দেখে না, এবং দুই অফিসের কোনোটিতেই কিছু বদলায় না। এটি সীমাটিও সৎভাবে বলে: আপনি প্রতিটি সাইট থেকে একটি HTTPS সেবা প্রকাশ করছেন, দুটি নেটওয়ার্ক মিলিয়ে দিচ্ছেন না। নিচে যে নিয়মগুলি আসে সেগুলি ছোট থাকে কারণ বিবৃতিটি সংকীর্ণ। আরও প্রশস্ত বিবৃতিতে আরও প্রশস্ত নিয়ম লাগত, আর এভাবেই এই ডিজাইনগুলি জটিল হয়ে ওঠে।

প্রতিটি সাইটকে এমন একটি alias দিন যা ব্যবহারকারী রাউট করতে পারে

এমন রেঞ্জ থেকে ঠিকানা বেছে নিন যা ব্যবহারকারীর মেশিনে, হাবে বা যেকোনো LAN-এ কোনো কিছুর সঙ্গে সংঘর্ষ করে না। এখানে হাব 10.66.0.1, ব্যবহারকারী 10.66.0.10, গেটওয়েগুলি 10.66.0.21 এবং 10.66.0.22, আর দুটি alias হলো 10.77.1.20 এবং 10.77.2.20। হাব প্রতিটি alias এমন peer-এর মাধ্যমে প্রকাশ করে যে এটি ধারণ করে, তাই একটি alias-এ ঠিকানা দেওয়া বহির্গামী প্যাকেট কেবল মিলে যাওয়া সাইট দিয়েই বেরোতে পারে:

[Interface]
Address = 10.66.0.1/32
ListenPort = 51820
PrivateKey = HUB_KEY

[Peer]
PublicKey = USER_PUBLIC_KEY
AllowedIPs = 10.66.0.10/32

[Peer]
PublicKey = SITE_A_PUBLIC_KEY
AllowedIPs = 10.66.0.21/32, 10.77.1.20/32

[Peer]
PublicKey = SITE_B_PUBLIC_KEY
AllowedIPs = 10.66.0.22/32, 10.77.2.20/32

ব্যবহারকারীর দিকে কেবল দুটি alias দরকার, যা ক্লায়েন্ট কনফিগারেশনকে দুটি LAN প্রিফিক্স থেকেই মুক্ত রাখে। সেই কনফিগারেশনে কিছুই কোনো আসল LAN-এর উল্লেখ করে না:

[Interface]
Address = 10.66.0.10/32
PrivateKey = USER_KEY

[Peer]
PublicKey = HUB_PUBLIC_KEY
Endpoint = hub.example.net:51820
AllowedIPs = 10.77.1.20/32, 10.77.2.20/32
PersistentKeepalive = 25

প্রতিটি গেটওয়ে হাব এবং ব্যবহারকারীর সোর্স ঘোষণা করে, আর কিছুই নয়, তাই একটি সাইট কখনো অন্য সাইটের LAN জানতে পারে না। Keepalive সাইটের আপলিংকে একটি NAT ম্যাপিং বজায় রাখে; এটি ট্র্যাফিক অনুমোদন করে না, এবং ফায়ারওয়ালই ঠিক করে কী গৃহীত হবে। একটি গেটওয়ের কনফিগারেশন অন্যটিতে কপি করা ঠিক আছে, যতক্ষণ প্রাইভেট কী, ইন্টারফেস ঠিকানা এবং alias সবই বদলায়।

হাবকে তার দুই peer-এর মধ্যে কী অনুমোদন করতে হবে

হাব তার নিজের দুই peer-এর মধ্যে প্যাকেট ফরওয়ার্ড করে, যা forward চেইনের সিদ্ধান্ত, ইনপুট সিদ্ধান্ত নয়। প্ল্যাটফর্মের স্বাভাবিক ব্যবস্থায় IPv4 ফরওয়ার্ডিং চালু করুন, তারপর ডিজাইনের প্রয়োজনীয় জোড়াগুলোই অনুমোদন করুন।

নিচের নিয়মটি ব্যবহারকারীকে একটি alias ও একটি পোর্টে অনুমতি দেয়, এবং কানেকশন ট্র্যাকিংয়ের মাধ্যমে ফেরত ট্র্যাফিক অনুমোদন করে। এটি forward পথে বাকি সবকিছু বাদ দেয়, আর সেটাই উদ্দেশ্য:

nft add table inet hub_transit
nft add chain inet hub_transit forward '{ type filter hook forward priority 0 ; policy drop ; }'
nft add rule inet hub_transit forward ct state established,related accept
nft add rule inet hub_transit forward iifname wg0 oifname wg0 tcp dport 443 ip saddr 10.66.0.10 ip daddr 10.77.1.20 accept

দুটি বিষয় উল্লেখ করার যোগ্য, কারণ তারা নীরব ব্যর্থতা ঘটায়। একটি বেস চেইনে accept অন্য চেইনের drop-কে অতিক্রম করে না, তাই এটি বিদ্যমান পলিসির সঙ্গে মিলিয়ে দিন, পাশাপাশি লোড করবেন না। আর সোর্স ঠিকানা ডিভাইস চিহ্নিত করে, ব্যক্তি নয়; অ্যাপ্লিকেশন প্রমাণীকরণকে নেটওয়ার্ক অনুমোদন থেকে আলাদা রাখুন।

যেখানে alias সত্যিকারের ঠিকানা হয়

সাইট A 10.77.1.20-এর জন্য একটি অনুরোধ পায়, গন্তব্যটি আসল অ্যাপ্লিকেশনে নতুন করে লেখে, এবং সোর্সটি নিজের LAN ঠিকানায় নতুন করে লেখে যাতে উত্তরটি টানেলে রুট ছাড়াই ফিরে আসতে পারে। দুই অনুবাদই এক জায়গায় করলে বাকি নেটওয়ার্ক alias সম্পর্কে অজ্ঞ থাকে। নিচের নিয়মগুলিই পুরো ব্যবস্থা:

nft add table ip site_a_nat
nft add chain ip site_a_nat pre '{ type nat hook prerouting priority -100 ; policy accept ; }'
nft add chain ip site_a_nat post '{ type nat hook postrouting priority 100 ; policy accept ; }'
nft add rule ip site_a_nat pre iifname wg0 tcp dport 443 ip saddr 10.66.0.10 ip daddr 10.77.1.20 dnat to 10.10.7.20:443
nft add rule ip site_a_nat post iifname wg0 oifname lan0 tcp dport 443 ip saddr 10.66.0.10 ip daddr 10.10.7.20 snat to 10.10.7.2

তারপর সাইট A-এর forward পলিসিকে টানেল ইন্টারফেস থেকে LAN ইন্টারফেসে অনূদিত ফ্লো অনুমোদন করতে হবে, সাথে ফিরতি দিকটিও। forward hook গন্তব্য অনুবাদের পরে এবং সোর্স পুনর্লেখনের আগে গন্তব্যটি দেখে, তাই নিয়মটি আসল অ্যাপ্লিকেশন ঠিকানা উল্লেখ করে। কোনো নিয়ম যখন কিছুর সঙ্গে মেলে না বলে মনে হয়, তখনই এই দুটি hook এই ক্রমে পড়ুন। alias-এর বিপরীতে লেখা forward নিয়ম কখনো মেলাতে পারে না, কারণ ওই hook-এ alias আর নেই।

সাইট B নিজের alias ও নিজের কী দিয়ে এটি পুনরাবৃত্তি করে। এটি সাইট A-এর প্রাইভেট কী পুনরায় ব্যবহার করা উচিত নয়, কারণ দুই peer-এর এক পরিচয় ভাগ করা একটি কনফিগারেশন ত্রুটি যা দেখতে কঠিন এবং ফাইল কপি করে তৈরি করা সহজ। দুই গেটওয়ে নথি অভিন্ন রাখুন কেবল সেই মানগুলি ছাড়া যা আলাদা হওয়া উচিত, যাতে পর্যালোচনায় পার্থক্যটি স্পষ্ট হয়। কপি করা ফাইলই সেই ত্রুটির স্বাভাবিক উৎস।

সোর্স পুনর্লেখনের একটি মূল্য আছে। অ্যাপ্লিকেশন গেটওয়েকে তার ক্লায়েন্ট হিসেবে দেখে, তাই তার লগ আর দেখায় না কোন ব্যবহারকারী সংযুক্ত হয়েছিল। গেটওয়ের অডিট ট্রেইল রাখুন, এবং অনুবাদ যে নেটওয়ার্ক পরিচয় সরিয়ে দিয়েছে তার ক্ষতিপূরণে অ্যাপ্লিকেশন লগইন দুর্বল করবেন না।

কীভাবে প্রমাণ করবেন যে দুটি প্রকাশিত নামই উত্তর দেয়

প্রতিটি alias-কে একটি DNS নাম দিন এবং সেই নামের জন্য অ্যাপ্লিকেশন ও সার্টিফিকেট কনফিগার করুন, কারণ অনুবাদ রিডাইরেক্ট বা এমবেড করা পরম URL নতুন করে লেখে না। প্রতি সাইটে একটি নাম ব্যবহার করুন যাতে সার্টিফিকেটের অমিল কখনো রাউটিং ত্রুটি হিসেবে ভুল না হয়।

আসল ক্লায়েন্ট থেকে পরীক্ষা করুন, কোন সাইট উত্তর দিয়েছে নিশ্চিত করুন, এবং একটি অননুমোদিত পোর্টও পরীক্ষা করুন। যেকোনো NAT পরিবর্তনের পরে নতুন সংযোগ ব্যবহার করুন, কারণ প্রতিষ্ঠিত অবস্থা পুরোনো ম্যাপিং ধরে রাখে:

wg show wg0 allowed-ips
sudo nft list ruleset
curl -sS -o /dev/null -w "%{http_code}\n" https://site-a.example.net/

প্রথম কমান্ডে খালি বা অপ্রত্যাশিত alias মানে কোনো ফায়ারওয়াল নিয়ম গুরুত্বপূর্ণ হওয়ার আগেই peer নির্বাচন ভুল। alias ঠিক থাকলে এবং নামটি তবুও ব্যর্থ হলে সমস্যা DNS ও সার্টিফিকেটে সরে গেছে। দুটি নামই উত্তর দেওয়া শুরু করলে এবং তৃতীয় পোর্ট বন্ধ থাকলে, ডিজাইনটি যা দাবি করে তাই করে: দুটি সংকীর্ণভাবে প্রকাশিত সেবা, দুটি মিলিত LAN নয়।

সম্পর্কিত নিবন্ধ