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

কারণ দিয়ে শুরু করুন। হয় কর্পোরেট ক্লায়েন্ট কেবল গেস্টের ভেতরে ইনস্টল হয়, নয় নীতি সেটিকে সেখানেই রাখে, আর আপনার তখনও হোস্ট থেকে ভেতরের বিল্ড সার্ভার দরকার। হোস্টকে নিজের ক্লায়েন্ট রাখতে দেওয়া হলে সেটাই করুন: হোস্টে একটি টানেল প্রতিবার দুই নেটওয়ার্ক আর একটি NAT-এর চেয়ে ভালো।

যাচাই 1: হোস্টের এমন লিংক দরকার যাকে সে ঠিকানা দিতে পারে

হোস্টের এমন একটি ইন্টারফেস থাকতে হবে যা গেস্টের দ্বিতীয় অ্যাডাপ্টারের একই প্রিফিক্সে বসে। VirtualBox-এ host-only, VMware Workstation-এ host-only বা কাস্টম VMnet, QEMU/KVM-এ অভ্যন্তরীণ ব্রিজ বা tap ডিভাইস, আর Hyper-V-এ Internal সুইচ সবই গ্রহণযোগ্য। গেস্ট 192.168.56.2, হোস্ট 192.168.56.1, প্রিফিক্স 192.168.56.0/24 হলো সেই বিন্যাস যা আমি ল্যাবে ব্যবহার করি।

QEMU-র ইউজার-মোড নেটওয়ার্কিং (-netdev user, ডিফল্ট SLIRP ব্যাকএন্ড) আর VirtualBox NAT এই যাচাইয়ে সোজা ফেল করে। গেস্টের প্যাকেট হোস্টের একটি প্রক্সি প্রসেসে পৌঁছায়, তাই হোস্ট কখনও গেস্টের ঠিকানা বহনকারী ডিভাইস দেখে না এবং রুট দেখানোর মতো কিছু পায় না। Hyper-V-এর Default Switch-ও একই গল্প। হোস্ট থেকে ping 192.168.56.2 ব্যর্থ হলে থামুন: পরে যোগ করা কোনো রুট এটি সারাবে না।

যাচাই 2: গেস্ট ফরওয়ার্ড করে এবং অনুবাদ করে

হোস্ট থেকে আসা প্যাকেটের উৎস ঠিকানা host-only নেটওয়ার্কের আর গন্তব্য অভ্যন্তরীণ, তাই গেস্টকে সেগুলো ফরওয়ার্ড করতে হয় এবং তারপর নিজের টানেল ঠিকানার পিছনে লুকাতে হয়। Linux গেস্টে এর মানে ফরওয়ার্ডিং, একটি FORWARD accept জোড়া, আর টানেলের দিকে source NAT:

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -A FORWARD -i eth1 -o tun0 -j ACCEPT
sudo iptables -A FORWARD -i tun0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o tun0 -j MASQUERADE

MASQUERADE নিয়মটাই সেই অংশ যা মানুষ বাদ দেয়। কর্পোরেট রাউটার খুব কমই জানে যে 192.168.56.0/24 আছে; নিয়মটি থাকলে অভ্যন্তরীণ সার্ভার গেস্টের টানেল ঠিকানা দেখে এবং তার উত্তর দেয়, আর উত্তরটি গেস্টের কাছে ফিরে আসার পথ খুঁজে পায়।

Windows গেস্ট আরও আনাড়ি। SYSTEM\CurrentControlSet\Services\Tcpip\Parameters-এর অধীনে IPEnableRouter=1 অনুবাদ ছাড়াই ফরওয়ার্ডিং চালু করে, তাই এটি কেবল সেখানে কাজ করে যেখানে কর্পোরেট রাউটিং আগেই আপনার host-only প্রিফিক্সের দিকে ফিরে যায়। Internet Connection Sharing অনুবাদ করে, কিন্তু ভাগ করা অ্যাডাপ্টারকে 192.168.137.1-এ পুনঃনম্বর দেয়, তাই হোস্ট রুট লেখার আগে সে আসলে যে ঠিকানা নিয়েছে তা পড়ুন।

যাচাই 3: হোস্ট রুট গেস্টের নাম বলে, টানেলের নয়

গেস্টের ওপর দিয়ে কেবল সেই প্রিফিক্সগুলো পাঠান যেগুলো হোস্টের দরকার। Linux-এ প্রতি প্রিফিক্সে একটি রুটই যথেষ্ট এবং সেটি পরিষ্কারভাবে ফিরে আসে:

sudo ip route add 10.20.0.0/16 via 192.168.56.2
ip route get 10.20.30.40

Windows-এ সমতুল্য হলো route add 10.20.0.0 mask 255.255.0.0 192.168.56.2। পরীক্ষার সময় -p বাদ দিন, যাতে খারাপ রুট রিবুটে মরে যায়, আর পথ কাজ করলে সেটি যোগ করুন। হোস্টের ডিফল্ট রুট সরাবেন না যদি না হোস্টের প্রতিটি অ্যাপ্লিকেশন টানেল ব্যবহার করা উচিত; যদি সত্যিই ফুল-টানেল দরকার হয়, দুটি /1 রুট যোগ করুন এবং হাইপারভাইজার নেটওয়ার্কের সরাসরি রুটটি রাখুন:

sudo ip route add 0.0.0.0/1 via 192.168.56.2
sudo ip route add 128.0.0.0/1 via 192.168.56.2

Windows হোস্টে ইন্টারফেস মেট্রিকও দেখুন। host-only অ্যাডাপ্টার নিষ্ক্রিয় থাকার সময় যোগ করা রুট টেবিলে থাকে কিন্তু কখনও ট্রাফিক বহন করে না, আর কম মেট্রিকের দ্বিতীয় অ্যাডাপ্টার একই প্রিফিক্সের জন্য লুকআপে জিতে যেতে পারে।

যাচাই 4: DNS রুট অনুসরণ করে, টানেলের ডিফল্ট নয়

রুট প্যাকেট সরায়; রিজলভার ঠিক করে কোন নামগুলো প্যাকেট তৈরি করে। হোস্টের রিজলভার বদলানোর বদলে কর্পোরেট রিজলভারকে কর্পোরেট জোনে সীমাবদ্ধ করুন এবং সেটি এমন DNS সার্ভারের দিকে দেখান যেখানে নতুন রুট আগেই পৌঁছায়। হোস্টে systemd-resolved থাকলে:

resolvectl dns eth1 10.20.0.53
resolvectl domain eth1 '~corp.example.com'

Windows-এ নেম রিজলিউশন পলিসি টেবিলের একটি এন্ট্রি একই কাজ করে: Add-DnsClientNrptRule -Namespace ".corp.example.com" -NameServers 10.20.0.53। গেস্ট যদি host-only ঠিকানায় নিজের রিজলভার চালায়, তবে সেই ঠিকানাই ব্যবহার করুন, কিন্তু আগে নিশ্চিত করুন যে সে loopback-এ নয়, 192.168.56.2-এ উত্তর দেয়।

তারপর ধীর পেজের জন্য DNS-কে দোষারোপ করার আগে MTU দেখুন। টানেল ইন্টারফেস হোস্টের 1500-বাইট ইন্টারফেসের চেয়ে ছোট, তাই DF বিট সেট করা পূর্ণ-আকারের সেগমেন্ট পাঠানো হোস্ট সেগুলো গেস্টের ভেতরে কোথাও ফেলে দেয়। চিরাচরিত লক্ষণ হলো কাজ করা ping আর একটি অভ্যন্তরীণ ওয়েব অ্যাপ যা TLS হ্যান্ডশেকের পরে আটকে যায়। গেস্টের ফরওয়ার্ড পথে MSS ক্ল্যাম্প করুন:

sudo iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

যাচাই 5: দুই প্রান্ত থেকেই যাচাই করুন

হোস্ট থেকে অভ্যন্তরীণ ঠিকানায় traceroute বা tracert প্রথম হপ হিসেবে ভৌত গেটওয়ে নয়, 192.168.56.2 দেখানো উচিত। গেস্টে একই চেষ্টা বেরোনো দেখুন: tcpdump -ni any host 10.20.30.40 host-only দিকে ফরওয়ার্ড হওয়া অনুরোধ আর টানেলে অনূদিত অনুরোধ দেখায়। যে অনুরোধ বেরিয়ে ফিরে আসে অথচ হোস্টকে নীরব রেখে যায়, সেটি ফেরার পথের দিকে ইঙ্গিত করে।

দুটি ব্যর্থতাই এর বেশিরভাগ ব্যাখ্যা করে। হয় গেস্টের টানেল host-only প্রিফিক্সের জন্য ফেরার রুট বহন করে না কারণ NAT নিয়ম নেই, নয় হোস্ট রুট এমন ঠিকানা দেখায় যা রিস্টার্টের পরে গেস্ট আর ধরে না। গত সেশনের নোটে ভরসা না করে ip -br addr আর ip route get দিয়ে ঠিকানাগুলো আবার পড়ুন।

যাচাই 6: রিবুট আর হাইপারভাইজার আপগ্রেড কাটিয়ে উঠুন

দুই অংশই স্থায়ী করুন: হোস্টে netplan বা NetworkManager রুট কনফিগারেশন, Windows-এ route add ... -p, আর /etc/sysctl.d/-এ net.ipv4.ip_forward=1 এবং গেস্টে পুনরায় লোড হওয়া ফায়ারওয়াল নিয়মের সেট। কনফিগারেশন যাচাই হওয়ার পরেই, পরবর্তী কর্পোরেট ক্লায়েন্ট আপডেট আসার আগে গেস্টের snapshot নিন।

হাইপারভাইজার তার অ্যাডাপ্টার নতুন করে তৈরি করলে host-only নেটওয়ার্ক পুনঃনম্বর হয়, যা 192.168.56.0/24-এর ওপর গড়া প্রতিটি রুট আর NAT নিয়ম নীরবে অকার্যকর করে দেয়। আপগ্রেডের পরে প্রথম তিনটি যাচাই ক্রমানুসারে আবার চালান; এটি এক মিনিট নেয় আর সেই অবস্থাটি ধরে যেখানে হোস্টের রুট এখনও আছে অথচ গেস্ট নতুন সাবনেটে চলে গেছে।

IPv6-এর জন্য আলাদা পাস দরকার। ip6tables নিয়ম, AAAA রেকর্ড আর দ্বিতীয় হোস্ট রুট পরিবার IPv4 সেটআপ অনুসরণ করে না, আর IPv6 দিয়ে পৌঁছানো কর্পোরেট সেবা IPv4 কাজ করার সময় পুরোপুরি ভাঙা দেখাবে।

পাস বা ফেল, ক্রমানুসারে: হোস্ট গেস্টের host-only ঠিকানা পিং করতে পারে; গেস্ট টানেলের দিকে ফরওয়ার্ড ও MASQUERADE করে; ip route get অভ্যন্তরীণ প্রিফিক্সের গেটওয়ে হিসেবে গেস্টকে ফেরত দেয়; কর্পোরেট নাম সীমিত রিজলভার দিয়ে রিজলভ হয়; traceroute গেস্টকে প্রথমে দেখায়; আর একই ছয়টি উত্তর রিবুট কাটিয়ে টিকে থাকে।

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