VPS ফায়ারওয়াল: কেবল VPN পোর্ট খুলুন, তারপর প্রমাণ করুন
একটি পোর্ট প্রকাশ্য থাকতেই হবে, নইলে কোনো ক্লায়েন্ট সংযুক্ত হয় না। বাকিগুলো প্রত্যাখ্যান করুন, ফরওয়ার্ডিং ইনপুট থেকে আলাদা রাখুন, এবং আগে পরীক্ষা করা পুনরুদ্ধার পথ রেখে দিন।
যে ফায়ারওয়াল কেবল VPN পোর্টকে অনুমতি দেয় তা একটিমাত্র নিয়ম নয়। এটি তিনটি আলাদা সিদ্ধান্ত, যেগুলো একই পোর্ট নম্বরকে ঘিরে ঘটে: ইনপুট চেইন ঠিক করে একটি স্থানীয় প্রসেস পর্যন্ত কী পৌঁছাতে পারে, ফরওয়ার্ড চেইন ঠিক করে টানেল-ক্লায়েন্টদের হয়ে হোস্টের ভেতর দিয়ে কী যেতে পারে, আর NAT টেবিল বেরোনোর পথে সোর্স ঠিকানা আবার লেখে। এর একটিতে ভুল করলে ফলাফল বিরল ক্ষেত্রেই পরিষ্কার বিভ্রাট হয়। আপনি পান এমন হোস্ট যা ক্লায়েন্ট গ্রহণ করে কিন্তু কিছু লোড করে না, অথবা এমন হোস্ট যা কেউ চেইনের ক্রম না পড়া পর্যন্ত বন্ধ দেখায়।
যে একটিমাত্র পোর্ট বন্ধ করা যায় না
VPN লিসেনারকে এমন ঠিকানা থেকে সংযোগ নিতে হয় যা আপনি আগে থেকে জানতে পারেন না, তাই এটি সংজ্ঞা অনুসারেই একটি প্রকাশ্য সেবা। এই একটি ব্যতিক্রমকেই ঘিরে ডিজাইনটি গড়া: OpenVPN-এর জন্য একটি UDP পোর্ট, WireGuard-এর জন্য একটি UDP পোর্ট, SSL VPN-এর জন্য একটি TCP পোর্ট। বাকি সবকিছুর জায়গা টানেলের পেছনে, অর্থাৎ অ্যাপ্লিকেশন সেবাগুলোকে সব ইন্টারফেসে নয়, টানেল ঠিকানায় বা loopback-এ বাঁধা উচিত।
তবে বাঁধাই প্রয়োগ নয়। 0.0.0.0-এ বাঁধা একটি প্রসেস কেবল তখনই পৌঁছানো যায় যখন কোনো নিয়ম অনুমতি দেয়, আর ডিফল্ট পলিসি হলো এমন ট্রাফিকের জন্য ফলব্যাক যা কোনো নিয়মের সঙ্গে মেলেনি, পোর্ট নিয়ন্ত্রণকারী নিয়ম নয়। আপনার ড্রপের উপরে বসানো অ্যাকসেপ্টও অ্যাকসেপ্টই থাকে, আর সেবাকে প্রকাশ্য ঠিকানা থেকে সরানো চেইনের বিকল্প নয়, বরং স্বতন্ত্র উন্নতি।
ইনপুট, ফরওয়ার্ড ও NAT ভিন্ন প্রশ্নের উত্তর দেয়
ইনপুট ট্রাফিক হোস্টের নিজের প্রতি লক্ষ্য, তাই VPN লিসেনার ও প্রশাসনিক পথ সেখানেই থাকে। ফরওয়ার্ড ট্রাফিক হোস্টের ভেতর দিয়ে যায়, এবং টানেল-ক্লায়েন্টদের সেটি দরকার সাথে net.ipv4.ip_forward=1। চিরাচরিত অর্ধভাঙা কনফিগারেশন বহির্মুখী প্রবাহ অনুমতি দেয় আর ফেরার দিক ভুলে যায়, ফলে ক্লায়েন্ট হ্যান্ডশেক শেষ করে তারপর কিছুই লোড হয় না; established ও related ট্রাফিকের জন্য একটি conntrack নিয়ম সেই দিকটি ঢেকে দেয়।
NAT হলো তৃতীয় প্রশ্ন। postrouting পুনর্লেখন ছাড়া ফরওয়ার্ড করা প্যাকেট ব্যক্তিগত টানেল সোর্স নিয়ে বেরিয়ে যায় এবং উপরের নেটওয়ার্কে বাতিল হয়, কারণ হোস্টের বাইরে কোনো নেটওয়ার্ক জানে না কীভাবে পুলটি ফেরত রাউট করতে হয়। সেই নিয়মের সোর্স প্রিফিক্স VPN পুলের সঙ্গে মিলতে হবে, হোস্টের নিজের ঠিকানার সঙ্গে নয়, এবং ক্লায়েন্ট সাবনেট উল্লেখ করা ফরওয়ার্ড নিয়মেও একই কথা প্রযোজ্য।
IPv6 হলো দ্বিতীয় পলিসি, পরে ভাববার বিষয় নয়। কড়া IPv4 চেইন আর খোলা ip6tables পলিসি থাকা হোস্ট কিছুই বন্ধ করেনি; সেবাগুলো অন্য ফ্যামিলি দিয়েই পৌঁছানো যায়। হয় ip6tables দিয়ে নিয়মসমূহের প্রতিচ্ছবি করুন, নয়তো প্রকাশ্য ইন্টারফেসে IPv6 সচেতনভাবে নিষ্ক্রিয় করুন, এবং কোনটি বেছেছেন তা লিখে রাখুন।
একবার পড়েই বোঝা যায় এমন ভিত্তিরেখা
ড্রপ দিয়ে শুরু করুন, তারপর কেবল হোস্টের যা দরকার তা যোগ করুন। আগে loopback ও উত্তর, তারপর প্রশাসনিক পথ, তারপর টানেল লিসেনার, তারপর ক্লায়েন্টদের জন্য ফরওয়ার্ডিং পলিসি:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -p udp --dport 1194 -m conntrack --ctstate NEW -j ACCEPT
sysctl -w net.ipv4.ip_forward=1
iptables -A FORWARD -i tun0 -o eth0 -s 10.8.0.0/24 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADEইন্টারফেসের নাম, পোর্ট ও পুল হলো প্লেসহোল্ডার; সেগুলো কপি না করে সার্ভার থেকেই পড়ুন। ফলাফল সংরক্ষণ করা লেখার মতোই জরুরি, কারণ কেবল মেমরিতে বাস করা নিয়মসমূহ পরের রিবুটে মিলিয়ে যায় এবং চুপচাপ হোস্ট আবার খুলে দেয়। ডিস্ট্রিবিউশনের পদ্ধতি দিয়ে এটি স্থায়ী করুন, আর যেদিন মেশিন বুট হবে না সেদিনের জন্য মেশিনের বাইরে একটি কপি রাখুন।
হোস্ট না হারিয়ে শেষ পোর্ট বন্ধ করা
ডিজাইনে একটি ফাঁদ আছে। যদি SSH কেবল টানেলের ভেতর দিয়েই থাকে, তবে ব্যর্থ VPN সেবা SSH-কেও নিয়ে যায়, আর ফেরার একমাত্র পথ হতে পারে এমন একটি কনসোল যা আপনি কখনো খোলেননি। শেষ প্রকাশ্য পোর্ট বন্ধ করার আগে নিশ্চিত করুন সেই কনসোল আছে এবং আপনি সত্যিই এটি ব্যবহার করতে পারেন, অথবা টানেলের উপর নির্ভর করে না এমন একটি সংকীর্ণ প্রশাসনিক পথ রাখুন: নির্দিষ্ট ঠিকানা থেকে SSH, কেবল কী, পাসওয়ার্ড প্রমাণীকরণ বন্ধ।
পরিবর্তনটি এমন একটি সেশন থেকে প্রয়োগ করুন যা ইতিমধ্যে প্রতিষ্ঠিত, যে সংযোগটি আপনি ফিল্টার করতে যাচ্ছেন তার মধ্য দিয়ে নয়। রোলব্যাকের সময়সূচি দিন যাতে ভুলটি স্থায়ী না হয়ে মেয়াদোত্তীর্ণ হয়, যেমন systemd-run --on-active=10min কাজ যা আগের নিয়মসমূহ ফিরিয়ে আনে, এবং প্রথমটি পরীক্ষা করার সময় দ্বিতীয় একটি SSH সেশন খোলা রাখুন। তারপর যাচাই করুন রোলব্যাক কাজটি সত্যিই চলে, কারণ অপরীক্ষিত পুনরুদ্ধার মানে পুনরুদ্ধার না থাকা।
স্ক্রিপ্ট নয়, পথটি যাচাই করুন
লোড হওয়া নিয়মগুলো পড়ুন, যে ফাইলটি সেগুলো লোড করার কথা ছিল তা নয়। অনুমোদিত বাইরের হোস্ট থেকে নিশ্চিত করুন যে কেবল অভীষ্ট পোর্টগুলোই উত্তর দিচ্ছে; টানেলের ভেতর থেকে নিশ্চিত করুন যে আপনি প্রকাশ করতে চাওয়া সেবাগুলো পৌঁছানোর মতো। ডিফল্ট-ডিনাই পলিসি যদি টানেল ট্রাফিকও ব্লক করে, তবে কেউ ব্যবহার করতে না চাওয়া পর্যন্ত তা কাজ করা লকডাউন দেখতে একই রকম।
iptables -S
iptables -t nat -S
ss -lntup
ip -4 addr showঅনুমোদিত পোর্ট, ক্লায়েন্ট পুল, টানেল ইন্টারফেস, প্রশাসনিক সোর্স এবং কনসোল পদ্ধতি কনফিগারেশনের পাশে লিখে রাখুন। পুল বা ইন্টারফেসের নামে পরবর্তী পরিবর্তন ফিল্টার ও NAT নিয়ম—দুটোতেই মিলতে হবে, নইলে হোস্ট কেউ না জানতে ফের অর্ধখোলা অবস্থায় ফিরে যাবে।
একটি অভ্যাস নিয়মসমূহের চেয়ে বেশি মূল্যবান: প্রতিটি পরিবর্তনের পরে ক্লায়েন্ট অনুরোধ দিয়ে ফরওয়ার্ড পথ প্রমাণ করুন এবং দ্বিতীয় সেশন দিয়ে পুনরুদ্ধার পথ প্রমাণ করুন। যে লকডাউন আপনি ব্যবহার করেননি তা কেবল একটি অনুমান।