ট্রাফিক কি সত্যিই VPN দিয়ে যাচ্ছে? কীভাবে যাচাই করবেন
রুট লুকআপ, প্রথম হপ, ফিজিক্যাল অ্যাডাপ্টারে ক্যাপচার এবং বাইরে থেকে ঠিকানা যাচাই — প্রতিটি প্রশ্নের ভিন্ন অংশের উত্তর দেয়।
সিস্টেম ট্রে-র আইকন থেকে দুটি ব্যর্থতা একই দেখায়: ট্রাফিক যা টানেলে ঢোকে আর ট্রাফিক যা চুপচাপ তার পাশ কাটিয়ে যায়। ক্লায়েন্ট দুই ক্ষেত্রেই Connected দেখায়, কারণ Connected শুধু বোঝায় টানেল ইন্টারফেসটি আছে এবং ক্লায়েন্ট তার চাওয়া রুটগুলো ইনস্টল করেছে। একটি অ্যাপ্লিকেশনের একটি প্যাকেট সেই রুটগুলো ব্যবহার করেছে কি না, সেটি আলাদা প্রশ্ন, যার উত্তর স্ট্যাকের অন্য জায়গায়। চারটি পরিমাপ এর বেশিরভাগটা ঠিক করে দেয় — রুট লুকআপ, প্রথম হপ, ফিজিক্যাল অ্যাডাপ্টারে ক্যাপচার এবং বাইরে থেকে পর্যবেক্ষণ — আর সার্ভারের নিজের সেশন ভিউ বাকিটা ঢেকে দেয়।
প্যাকেট যে রুটে যাবে সেখান থেকেই শুরু করুন
রাউটিং টেবিলটাই সিদ্ধান্ত, তাই পুরোটা পড়ে অনুমান করার বদলে একটি গন্তব্য সম্পর্কে জিজ্ঞাসা করুন। Linux-এ ip route get কার্নেল যে ইন্টারফেস আর সোর্স ঠিকানা বেছে নিয়েছে তা দেখায়:
ip route get 203.0.113.10
ip route get 10.20.5.7Windows-এ একই কারণে route print -4-এর চেয়ে Find-NetRoute -RemoteIPAddress 203.0.113.10 বেশি কাজে লাগে: এটি কোন রুট জিতেছে তা জানায়, সব রুট নয়। তবুও টেবিলটা একবার পড়ুন এর 0.0.0.0 সারির জন্য। সেখানে একটি /1 জোড়া মানে ফুল-টানেল ক্লায়েন্ট ডিফল্ট রুটটি আবার লিখেছে: OpenVPN-এর redirect-gateway def1 টানেলের মধ্য দিয়ে 0.0.0.0/1 আর 128.0.0.0/1 ইনস্টল করে, যা সবচেয়ে দীর্ঘ প্রিফিক্স মিলে বিদ্যমান 0.0.0.0/0-কে হারায়, ফিজিক্যাল ডিফল্ট না মুছেই। এজন্যই দুটি ডিফল্ট একসঙ্গে থাকতে পারে, অথচ সবকিছু তখনও টানেলে যায়।
দুটি বিষয় টেবিলটিকে মিথ্যে বানায়। প্রথমত, কতগুলো ডিফল্ট রুট আছে তা নয়, কোন প্রিফিক্স মিলেছে তা দেখুন, কারণ ইন্টারফেস মেট্রিক বা /1 জোড়াই বিজয়ী ঠিক করে। দ্বিতীয়ত, যে সংযোগ আগে থেকেই আছে সে যে পথে প্রতিষ্ঠিত হয়েছিল সেটাই ধরে রাখে; টানেল ওঠার পর খোলা সেশন রিসেট না হওয়া পর্যন্ত পুরনো রুট ব্যবহার করতে পারে, এজন্যই আবার সংযোগ দেওয়ায় রাউটিং সমস্যা ঠিক হয়েছে মনে হয়। চলমান ক্লায়েন্ট — ps ax | grep openvpn — কেবল প্রমাণ করে প্রসেসটা শুরু হয়েছে।
একটি অভ্যন্তরীণ আর একটি পাবলিক নাম ট্রেস করুন
রুট লুকআপ অভিপ্রায় দেখায়; পথ দেখায় বিতরণ। সংযুক্ত থাকা অবস্থায় এমন একটি নাম ট্রেস করুন যা অবশ্যই অভ্যন্তরীণ আর একটি যা অবশ্যই নয়, এবং প্রথম হপ তুলনা করুন:
traceroute intranet.corp.example
traceroute 1.1.1.1দুটির জন্য একই প্রথম হপ মানে অভ্যন্তরীণ নামটি কখনোই টানেলে ঢোকেনি এবং ত্রুটি তার উপরে, সাধারণত এমন নাম যা পাবলিক ঠিকানায় রিজলভ হয় বা এমন রুট যা কখনো ইনস্টল হয়নি। অভ্যন্তরীণ ট্রাফিক 10.8.0.1 দিয়ে বেরোচ্ছে আর পাবলিক ট্রাফিক 192.168.1.1 দিয়ে বেরোচ্ছে মানে স্প্লিট টানেলিং ঠিক যা করার জন্য কনফিগার করা হয়েছিল তাই করছে। যে ট্রেস VPN গেটওয়ে পর্যন্ত পৌঁছে তারপর কেবল টাইমআউট ফেরায় সেটি সাধারণত রিটার্ন-পাথ বা সার্ভার ফায়ারওয়ালের সমস্যা, অনুপস্থিত ফরওয়ার্ড রুট নয়।
ফিল্টার করা ICMP এই পরীক্ষাকে মিথ্যে বানায়: দুই ট্রেসেই তারা-চিহ্ন মৃত টানেলের মতো দেখায় আর সাধারণত সেটি ফায়ারওয়াল। যেখানে সম্ভব TCP পোর্ট পরীক্ষা করুন — Linux-এ traceroute -T -p 443 — এবং মনে রাখুন ট্রেস কিছুই বলে না কোন রিজলভার উত্তর দিয়েছে: একটি নাম স্থানীয়ভাবে রিজলভ হয়ে এখনও টানেল দিয়েও পৌঁছাতে পারে।
টানেলে নয়, ফিজিক্যাল অ্যাডাপ্টারে ক্যাপচার করুন
ফিজিক্যাল লিংকই একমাত্র জায়গা যা দেখায় নেটওয়ার্ক আসলে কী দেখতে পায়। টানেল ওঠা অবস্থায় অফিসে যাওয়া একটি সেশন VPN সার্ভারে পাঠানো এনক্রিপ্টেড পেলোড হিসেবে দেখা উচিত, 10.20.5.7-এ সংযোগ হিসেবে নয়:
sudo tcpdump -ni eth0 udp port 53
sudo tcpdump -ni eth0 host 10.20.0.5প্রথম ফিল্টার স্থানীয়ভাবে বেরিয়ে যাওয়া নাম রিজলভিং ধরে, যা সবচেয়ে সাধারণ আর সবচেয়ে নীরব লিক — পাতা তবুও লোড হয়, রিজলভার কেবল কোয়েরিটা দেখেছে। দ্বিতীয়টি অভ্যন্তরীণ ঠিকানায় সাধারণ ট্রাফিক ধরে, যা কেবল টানেলের ভেতরে থাকা উচিত। Windows-এ pktmon ড্রাইভার ছাড়াই একই কাজ করে: pktmon filter add -p 53, তারপর pktmon start --capture --pkt-size 128, তারপর pktmon stop আর pktmon format pktmon.etl -o capture.txt। এসব ফ্ল্যাগ Windows বিল্ডভেদে একটু আলাদা, তাই সিনট্যাক্সে ভরসা করার আগে pktmon filter add /? দেখুন।
লিক খুঁজতে ফিজিক্যাল ইন্টারফেসে ক্যাপচার করুন; টানেলে ক্যাপচার সেই প্যাকেটগুলোই ধরে যেগুলো ইতিমধ্যে সেখানে আছে বলে আপনি ভাবেন, আর সার্ভারে তা ধরে অপাঠযোগ্য বাইরের প্যাকেট, যাদের সোর্স গেটওয়ে। যেকোনো ইন্টারফেসের বাইট কাউন্টার প্যাকেট বর্ণনা করে, প্রোগ্রাম নয়; ট্রাফিককে কোনো প্রসেসে আরোপ করতে দরকার এমন মনিটর যা সকেটকে প্রসেসের সঙ্গে মেলায়।
বাইরের সেবাকে জিজ্ঞাসা করুন, তারপর প্রতিটি অ্যাপ্লিকেশনের জন্য আবার জিজ্ঞাসা করুন
একমাত্র পরীক্ষা যা এক্সিট প্রমাণ করে তা বাইরে থেকে আসা উত্তর: এমন সেবা যা তার দেখা সোর্স ঠিকানা ফেরত দেয়। এটি শেল থেকে চালান, যেখানে ইন্টারফেস বাছাই করতে পারেন, এবং দুইবার চালান:
sudo curl --interface tun0 https://example.net/ip
sudo curl --interface eth0 https://example.net/ipআলাদা উত্তর আপনাকে দুই পথের প্রমাণ আর নির্দিষ্ট অ্যাপ্লিকেশন পরীক্ষা করার উপায় দেয়: এটিকে বাইন্ড করুন, বা এক রুটের নেটওয়ার্ক নেমস্পেসে চালান, আর দেখুন দূরের প্রান্ত কোন ঠিকানা রেকর্ড করে। একই উত্তরই মজার ব্যর্থতা: হয় বাইন্ড কাজ করেনি, নয়তো হোস্ট আর দূরের প্রান্তের মধ্যে কিছু সোর্স ঠিকানা পৌঁছানোর আগেই আবার লিখে দিচ্ছে। Windows-এ curl --interface অ্যাডাপ্টারের নাম নয়, ঠিকানা চায়।
VPN ঠিকানা জানানো ব্রাউজার ব্রাউজারকেই প্রমাণ করে। মেইল ক্লায়েন্ট, প্যাকেজ ম্যানেজার, ব্যাকআপ এজেন্ট বা দ্বিতীয় ব্রাউজার প্রোফাইল — প্রত্যেকে আলাদা পথ নিতে পারে, বিশেষত যখন প্রক্সি সেটিং বা স্প্লিট-টানেল রুট তাদের একটিকে ঢেকে দেয়। ঠিকানা বদল নিজে থেকেই লিকের প্রমাণ নয়: লোড ব্যালেন্সার যে ইগ্রেস দেখেছে তার ভিত্তিতে ভিন্নভাবে উত্তর দিতে পারে, তাই পাতা নয়, রেকর্ড করা সোর্স ঠিকানা তুলনা করুন।
পিয়ার নিশ্চিত করতে সার্ভারের ভিউ ব্যবহার করুন
সার্ভার অন্য প্রশ্নের উত্তর দেয়: কোনো পিয়ার সংযুক্ত কি না, কতটা বহন করেছে এবং সেশন রিস্টার্ট হয়েছে কি না। সার্ভারে পিয়ার সচল অথচ ক্লায়েন্ট কাউন্টার প্রায় নড়ছে না মানে অ্যাপ্লিকেশনের ট্রাফিক টানেলে ঢুকছে না, ক্লায়েন্ট টেবিল যা-ই বলুক। আর যে পিয়ার এমন ব্যবহারকারীর জন্য অনেক ডেটা সরাচ্ছে যিনি বলেন কিছুই কাজ করছে না, সেটি ভিন্ন তদন্ত।
এখানে দুটি ফাঁদ আছে। মাস্কারেড টানেল প্রতিটি ফ্লোকে গেটওয়ে থেকে আসা মনে করায়, ফলে লগ আর প্রতি-ক্লায়েন্ট হিসাব এক ঠিকানায় মিলে যায়। আর ক্লায়েন্টকে লোকাল হোস্ট ধরা হয়, তাই কেউ VPN দিয়ে ফাইল কপি করছে কি না প্রশ্নের উত্তর মেলে সার্ভারে ফাইল-শেয়ার ট্রাফিক বা সার্ভারে হোস্ট অডিট থেকে — টানেল দেখলে এন্ডপয়েন্ট আর ভলিউম পাওয়া যায়, ফাইলের নাম নয়।
ডিজাইন সিদ্ধান্ত আর লিক আলাদা করুন
টানেলের বাইরের সবকিছুই লিক নয়। লিংক-লোকাল আর ব্রডকাস্ট ট্রাফিক ডিজাইনমতই স্থানীয় থাকে, মাল্টিকাস্টে পাওয়া প্রিন্টার LAN-এ ঘোষণা চালিয়ে যায়, আর DHCP-কে স্থানীয়ভাবেই বেরোতে হয়। নির্দিষ্ট ইন্টারফেসে বাইন্ড করা অ্যাপ্লিকেশন ইচ্ছাকৃতভাবে রাউটিং টেবিল পাশ কাটায়, আর তা বদলায় কেবল ফায়ারওয়াল নিয়ম, নেমস্পেস বা পলিসি রুট।
IPv6 চেকলিস্টে নিজের জন্য একটি আলাদা লাইন দাবি করে। যে টানেল কেবল IPv4 বহন করে, সে দ্বৈত-স্ট্যাক হোস্টকে আরেকটি ব্যবহারযোগ্য পথ রেখে দেয়, আর দ্বৈত-স্ট্যাক গন্তব্য সেটিকেই পছন্দ করবে — DNS সহ, যদি রিজলভার IPv6 দিয়ে পৌঁছানো যায়। IPv4 ফলাফলকে সম্পূর্ণ ধরার আগে অ্যাডাপ্টারে IPv6 বন্ধ করুন বা টানেল তা বহন করে কি না নিশ্চিত করুন।
যখন পরীক্ষাগুলো মিলে না, অমিলটাই সাধারণত ত্রুটির নাম বলে দেয়:
| What you see | What it means | Next step |
|---|---|---|
| The route picks tun0 but the capture shows cleartext to 10.20.5.7 | Something bypassed the table: a bound app, a policy route or a session older than the tunnel | Reset the flow, check the app bind, check the ip rule list |
| The route picks eth0 for an internal name | The name resolves to a public address, or the route was never installed | Compare the resolved address with the routes the server pushes |
| The capture shows DNS to the LAN resolver | Resolver leak: data is tunneled, lookups are not | Point the resolver inside, or push it from the server |
| All four checks agree and one app still fails | Path selection is fine; suspect MTU, a per-app proxy or the far end | Test the same destination from a known-good client |
যে ক্রম কাজ করে: সংযোগের আগে ও পরে রাউটিং টেবিল সংরক্ষণ করুন, একটি অভ্যন্তরীণ আর একটি পাবলিক নাম ট্রেস করুন, ফিজিক্যাল অ্যাডাপ্টারে DNS ক্যাপচার করুন, নির্দিষ্ট অ্যাপ্লিকেশনের জন্য শেল থেকে এক্সিট ঠিকানা ফেরত নিন, তারপর ভলিউমের জন্য সার্ভার পড়ুন। প্রথম চারটি মিললে, টানেল আপনি যা ভাবছেন তাই বহন করছে আর বাকি সমস্যা তার উপরে। দুটি না মিললে, যে জোড়া মিলছে না সেটাই ত্রুটি, আইকন নয়।