একটি পোর্ট VPN-এর বাইরে নিতে হলে পলিসি রাউটিং দরকার
NAT নিয়ম ঠিকানা পুনর্লিখন করে, বহির্গমন লিঙ্ক বেছে নেয় না। এখানে সেই নিয়ম, টেবিল ও মার্ক দেওয়া হলো যা সত্যিই একটি TCP পোর্টকে টানেলের বাইরে রাখে।
অনুরোধটি সবসময় একই বাক্যের একটি রূপ: ব্রাউজিংয়ের জন্য VPN রাখুন, কিন্তু SSH বা কোনো ব্যাকআপ কাজ স্বাভাবিক সংযোগ ব্যবহার করুক. এ নিয়ে যে পরামর্শ ঘোরে, অর্থাৎ iptables NAT নিয়ম দিয়ে পোর্ট ফরওয়ার্ড করা, তা এ কাজ করে না। NAT নিয়ম একটি ফ্লো-এর ভেতরের ঠিকানা ও পোর্ট পুনর্লিখন করে; প্যাকেট কোন ইন্টারফেস দিয়ে বেরোবে তা এটি কখনোই বেছে নেয় না। সেই সিদ্ধান্ত রাউটিং লুকআপের, আর রাউটিং লুকআপের একটি পোর্ট দেখতে সাহায্য দরকার।
কেন সাধারণ রুট একটি পোর্টের সঙ্গে মেলে না
Linux একটি টেবিলে গন্তব্য ঠিকানা খুঁজে রুট বেছে নেয়, আগে পলিসি নিয়ম দিয়ে প্রার্থী টেবিলগুলো ছেঁকে নেওয়ার পরে। সেই নিয়মগুলো ফায়ারওয়াল মার্ক, সোর্স ঠিকানা, আগমনকারী ইন্টারফেস বা UID-এর সঙ্গে মিলতে পারে। রুট এন্ট্রির নিজের কোনো পোর্ট ফিল্ড নেই, কারণ ট্রান্সপোর্ট হেডার গুরুত্বপূর্ণ হওয়ার আগেই রুট বেছে নেওয়া হয়।
আধুনিক iproute2 ও কার্নেল নিয়মের সিলেক্টর প্রশস্ত করেছে: ipproto, sport এবং dport গৃহীত হয়, তাই ip rule add ipproto tcp dport 22 table 100 এক লাইনেই উদ্দেশ্য প্রকাশ করে। প্রকৃত হোস্টে ip rule add help চালিয়ে দেখুন আপনার বিল্ড dport তালিকাভুক্ত করে কি না। যদি করে, এক কমান্ডেই কাজ শেষ; যদি না করে, নিচের মার্ক পথটিই সমতুল্য।
যেভাবেই হোক, নিয়মটি কেবল একটি সংকেত। টেবিল 100-এর এখনো একটি রুট দরকার, আর মানুষ ঠিক এই অংশটাই ভুলে যায়।
তিনটি অংশ, নাকি একটি
আধুনিক রূপটি হলো উপরের একক নিয়ম আর বিকল্প টেবিলে একটি রুট। ধ্রুপদী রূপটি মাঝখানে netfilter যোগ করে: প্যাকেটে মার্ক দিন, তারপর নিয়মে মার্ক মেলান। দুটোই একই লুকআপে শেষ হয়; পার্থক্য কেবল পোর্ট কোথায় পড়া হয় তাতে।
মার্ক পদ্ধতিটি আছে কারণ netfilter ট্রান্সপোর্ট হেডার দেখে, আর রাউটিং কোড ঐতিহাসিকভাবে দেখত না। পুরো কার্যপ্রণালী এটাই, এবং এটিই ব্যাখ্যা করে কেন বিকল্পটি একটি চতুর কমান্ড নয়, বরং তিনটি সহযোগী অংশ।
তিনটি অংশ ক্রমে
প্রথমে, যে ফ্লোগুলো ঘুরিয়ে নিতে চান সেগুলোতে মার্ক দিন, এমন একটি চেইনে যা রুট সিদ্ধান্তের আগেই মার্ক তৈরি হওয়ার মতো যথেষ্ট আগে চলে:
nft add table inet vpnexempt
nft 'add chain inet vpnexempt out { type route hook output priority mangle; }'
nft add rule inet vpnexempt out tcp dport 22 meta mark set 0x1দ্বিতীয়ে, মার্ক দেওয়া প্যাকেট একটি আলাদা টেবিলে পাঠান:
ip rule add fwmark 0x1/0x1 table 100তৃতীয়ে, সেই টেবিলকে ভৌত লিঙ্ক দিয়ে একটি ডিফল্ট রুট দিন। ঠিকানাগুলো উদাহরণমাত্র; নিজের ঠিকানা বসান:
ip route add default via 192.168.1.1 dev wlan0 table 100তৃতীয় ধাপ বাদ দিলে মার্ক দেওয়া প্যাকেট টেবিল 100-এ কোনো রুট পায় না, তাই ব্যর্থ হয়। উপসর্গটি এমন দেখায় যেন নিয়মটি নেটওয়ার্ক ভেঙেছে, অথচ বাস্তবে এটি প্যাকেটের বাকি থাকা একমাত্র পথটিই সরিয়েছে।
প্রথম প্যাকেটের পরেও যা এটিকে চালু রাখে
মার্ক বহির্গামী প্যাকেটে প্রযোজ্য। উত্তরটি ভৌত ইন্টারফেসে সেই লিঙ্কের দেওয়া ঠিকানা নিয়ে আসে, আর মূল টেবিল ওই গন্তব্যের জন্য এখনো টানেলকে প্রাধান্য দিতে পারে। দুটি ব্যবস্থা উত্তরপথ স্থির রাখে: লিঙ্ক ঠিকানার জন্য সোর্সভিত্তিক নিয়ম, এবং কানেকশন ট্র্যাকিং যা ফ্লোর আয়ুষ্কালজুড়ে সিদ্ধান্তটি ধরে রাখে। conntrack-এ মার্ক সংরক্ষণ করে উত্তরে তা পুনরুদ্ধার করাই অবস্থাভিত্তিক ব্যতিক্রম স্থির রাখার স্বাভাবিক উপায়।
রিভার্স-পাথ ফিল্টারিং আরেকটি নীরব ঘাতক। কার্নেল যদি ফেরতপথ কঠোরভাবে যাচাই করে আর উত্তরটি এমন ইন্টারফেসে আসে যা মূল টেবিল বাছত না, তবে প্যাকেটটি কোনো বার্তা ছাড়াই ফেলে দেওয়া হয়। rp_filter -এর ডিফল্ট মান ডিস্ট্রিভেদে এবং ইন্টারফেস ফরওয়ার্ড হচ্ছে কি না তার ভিত্তিতে ভিন্ন, তাই বন্ধ আছে ধরে না নিয়ে কার্যকর মানটি পড়ুন।
টানেলের নিজের ট্রান্সপোর্টে মার্ক দেবেন না। WireGuard বা UDP OpenVPN টানেল TCP 22 নয়, তাই উপরের রেসিপিটি নিরাপদ, তবে টানেল গন্তব্য ছাড়া বাকি সবকিছু হিসেবে লেখা ব্যতিক্রম এনক্রিপ্টেড প্যাকেট ধরে ফেলে টানেল ভেঙে দিতে পারে, যা রাউটিং লুপের মতো দেখায়।
ধরে না নিয়ে যাচাই করুন
কার্নেলকে জিজ্ঞাসা করুন সে কোন পথ নেবে, গন্তব্য ও পোর্টের জন্য, তারপর প্রকৃত স্থানান্তর চালান:
ip route get 203.0.113.10
ip rule show
nft list rulesetমার্ক থাকলে কিন্তু কাউন্টার কখনো নড়ে না, তবে নিয়মটি মিলছে না। কাউন্টারই আপনার লেখা কনফিগারেশন আর কার্নেল যে পলিসি প্রয়োগ করছে তার পার্থক্য।
কখন এটি ভুল যন্ত্র
পোর্টভিত্তিক ব্যতিক্রম স্বভাবতই ভঙ্গুর। সেবাগুলো পোর্ট বদলায়, HTTP/3 আসে UDP 443 হিসেবে, আর একটি অ্যাপ্লিকেশন বিভিন্ন ধরনের একাধিক ফ্লো খুলতে পারে। আসল চাহিদা যদি হয় এই প্রোগ্রামটি স্বাভাবিক লিঙ্ক ব্যবহার করবে, তবে রাউটিং স্তর ভুল জায়গা; নেটওয়ার্ক নেমস্পেস বা প্রতি-অ্যাপ্লিকেশন প্রক্সি বেশি মানানসই।
চাহিদা যদি হয় এই সাবনেট স্বাভাবিক লিঙ্ক ব্যবহার করবে, তবে মার্ক সম্পূর্ণ বাদ দিন এবং আরও নির্দিষ্ট একটি রুট যোগ করুন। এটি সরল, একটি টেবিলেই দৃশ্যমান, আর পরের ব্যক্তি নিয়মসমাহার না পড়েই এটি যাচাই করতে পারবে।
ফায়ারওয়াল ছোঁয়ার আগে লিখে নিন তিনটি চাহিদার কোনটি আপনার। উপরের কার্যপ্রণালী নিখুঁত, আর ভুল স্তরে প্রয়োগ করা নিখুঁততা কেবল আরও দীর্ঘ বিভ্রাট।