Linux-এ ফরওয়ার্ডিং চালু করার পর IPv6-এর ডিফল্ট রুট হারিয়ে গেল
IPv6 ফরওয়ার্ডিং চালু করলে কার্নেল আপলিঙ্কে রাউটার বিজ্ঞাপন উপেক্ষা করে, এবং শেখা ডিফল্ট রুটের মেয়াদ শেষ হয়। accept_ra দিয়ে ঠিক করুন।
VPN ক্লায়েন্টের ট্রাফিক পাঠাতে পারে বলে একটি Debian গেটওয়েতে net.ipv6.conf.all.forwarding=1 বসিয়েছিলাম, আর প্রায় আধা ঘণ্টা পরে মেশিনে কোনো IPv6 ডিফল্ট রুটই ছিল না। উপরের রাউটার সচল ছিল, link-local প্রতিবেশী তখনও উত্তর দিচ্ছিল, আর আপলিঙ্ক তার গ্লোবাল ঠিকানা ধরে রেখেছিল। যা থেমে গিয়েছিল তা হল কার্নেলের ওই ইন্টারফেসে রাউটার বিজ্ঞাপন গ্রহণ চালিয়ে যাওয়ার ইচ্ছা। sysctl লেখার মুহূর্তে রুটটি হারায়নি; RA থেকে শেখা ডিফল্ট রুটের আয়ু ফুরোলে তা হারিয়েছিল এবং কিছুই সেটি নবায়ন করেনি।
প্রথম দর্শনে কিছুই ভাঙা মনে হয়নি। ফরওয়ার্ডিং কাজ করছিল, পুরোনো রুট ক্যাশে থাকা পর্যন্ত ক্লায়েন্টরা পার হচ্ছিল, আর ব্যর্থতাটি যে পরিবর্তন তার কারণ ছিল তার চেয়ে দেরিতে এল। এই বিলম্বের কারণেই দোষ উপরের দিকের বা এমন ফায়ারওয়াল নিয়মের উপর পড়ে যার সঙ্গে এর কোনো সম্পর্কই ছিল না।
যে-কোনো sysctl ছোঁয়ার আগে রুটের ছক পড়ুন
ip -6 route show default দিয়ে শুরু করুন এবং কেবল গেটওয়ে নয়, বৈশিষ্ট্যগুলিও পড়ুন। RA থেকে শেখা ডিফল্ট রুটে proto ra চিহ্ন থাকে, একটি পছন্দ বহন করে এবং expires কাউন্টডাউন দেখায়। হাতে যোগ করা রুটে এগুলোর কোনোটিই থাকে না, আর এই পার্থক্যই বলে দেয় কোন প্রক্রিয়াটি রুটটির মালিক।
$ ip -6 route show default
default via fe80::1 dev eth0 proto ra metric 1024 expires 1432sec hoplimit 64 pref mediumতারপর ঠিকানাটি দেখুন: ip -6 addr show dev eth0। ঘণ্টায় মাপা পছন্দের ও বৈধ আয়ুসহ গ্লোবাল ঠিকানা এমন একটি ডিফল্ট রুটের চেয়ে বেশি টিকবে যার রাউটার আয়ু মিনিটে মাপা হয়। ঠিকানা আছে কিন্তু ডিফল্ট রুট নেই, এটি বিজ্ঞাপন সমস্যার চিহ্ন। ঠিকানাও না থাকলে প্রথমে লিঙ্ক, প্রিফিক্স তথ্য বা পুনরাবৃত্ত ঠিকানা শনাক্তকরণের পেছনে ছুটতে হবে।
কেন ফরওয়ার্ডিং RA প্রক্রিয়াকরণ বন্ধ করে
RA হল 134 ধরনের একটি ICMPv6 প্যাকেট, যা 255 হপ সীমাসহ link-local উৎস থেকে পাঠানো হয়। কার্নেল এটি ব্যবহার করার আগে ইন্টারফেসের accept_ra দেখে। ডিফল্ট মান 1, আর 1 মানে হ্যাঁ নয়। এর মানে: কেবল ততক্ষণ গ্রহণ করো যতক্ষণ এই হোস্ট ফরওয়ার্ড না করে। forwarding=1 বসান, সেই শর্ত ব্যর্থ হয়, ফলে বিজ্ঞাপনটি বাতিল হয়—তার ভেতরের কোনো প্রিফিক্স বা ডিফল্ট রাউটার বিবেচনার আগেই।
তিনটি মান আছে, আর ফরওয়ার্ডিং টিকে যায় কেবল তৃতীয়টি:
accept_ra | forwarding=0 | forwarding=1 |
|---|---|---|
| 0 | ignored | ignored |
| 1 (default) | accepted | ignored |
| 2 | accepted | accepted |
আরও দুটি ফ্ল্যাগ ঠিক করে প্রকৃতপক্ষে কী ইনস্টল হয়। accept_ra_defrtr নিয়ন্ত্রণ করে বিজ্ঞাপনের ডিফল্ট রাউটারটি রুট হয় কি না, আর accept_ra_pinfo নিয়ন্ত্রণ করে প্রিফিক্স তথ্য ঠিকানা কনফিগারেশনে ব্যবহৃত হয় কি না। accept_ra_defrtr বন্ধ করা হল ফরওয়ার্ডিং হোস্টে ডিফল্ট রুট না শিখেই SLAAC ঠিকানা রাখার স্বাভাবিক উপায়। এটি accept_ra থেকে আলাদা একটি লিভার, আর ঠিকানা চাইলে কিন্তু রুট না চাইলে এটাই ব্যবহার করা হয়। কার্নেলের IP sysctl রেফারেন্স তিনটিই তালিকাভুক্ত করে।
তিনটি কমান্ডে নিশ্চিত করুন
প্রথমে যে ফাইল লোড হয়েছে বলে ভাবছেন তার বদলে সক্রিয় মানগুলো পড়ুন:
sysctl net.ipv6.conf.eth0.forwarding net.ipv6.conf.all.forwarding \
net.ipv6.conf.eth0.accept_ra net.ipv6.conf.eth0.accept_ra_defrtrদ্বিতীয়ত, প্রমাণ করুন যে বিজ্ঞাপনগুলো এখনও আসছে। ICMPv6 ধরনের বাইটে ফিল্টার করাই যথেষ্ট, আর এটি প্রতিবেশী আবিষ্কারের ট্রাফিকের দেয়াল পড়া থেকে বাঁচায়:
tcpdump -ni eth0 'icmp6 and ip6[40] == 134'কয়েক মিনিটেও কিছু না দেখালে accept_ra আপনার সমস্যা নয়। উপরের দিক বিজ্ঞাপন দেওয়া বন্ধ করেছে, পথের কোথাও ICMPv6 ফিল্টার হচ্ছে, বা ওই ইন্টারফেসটি সত্যিই সেই সেগমেন্টে নেই যা আপনি ভাবছেন। তৃতীয়ত, নিজেই একটি বিজ্ঞাপন চান আর তার ক্ষেত্রগুলো পড়ুন:
rdisc6 eth0rdisc6 Debian ও Ubuntu-তে ndisc6 প্যাকেজে আসে। আউটপুটে অন্য কিছু বদলানোর আগে রাউটার আয়ু ও পছন্দ দেখুন। রাউটার আয়ু 0 এমন বিজ্ঞাপন হল ডিফল্ট রাউটার সরানোর নির্দেশ, আর accept_ra-এর কোনো মানই সেটিকে ব্যবহারযোগ্য রুটে পরিণত করে না। এভাবেই ব্রিজ মোডে থাকা উপরের CPE ধরা পড়ে, যা প্রিফিক্স বিলি করে কিন্তু নিজেকে কখনও রাউটার হিসেবে প্রস্তাব করে না।
আপলিঙ্ককেই একমাত্র অনুমোদনকারী ইন্টারফেস করুন
যদি উপরের দিকটিই ডিফল্ট রাউটার হওয়ার কথা হয়, ফরওয়ার্ডিং সত্ত্বেও সেখানেই বিজ্ঞাপন গ্রহণ করুন, অন্য কোথাও নয়:
# /etc/sysctl.d/60-ipv6-router.conf
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.eth0.accept_ra = 2
net.ipv6.conf.eth0.accept_ra_defrtr = 1সীমা নির্ধারণ গুরুত্বপূর্ণ, কারণ Linux-এ IPv6 ফরওয়ার্ডিং একটি বিশ্বব্যাপী সুইচ, প্রতি লিঙ্কে একটি নয়। net.ipv6.conf.wg0.forwarding-এ 1 লিখুন, তারপর net.ipv6.conf.all.forwarding পড়ুন: বিশ্বব্যাপী মান উল্টে যায় এবং প্রতিটি ইন্টারফেস ফরওয়ার্ড করা শুরু করে। আপনি টানেলে রাউটার আর LAN-এ সাধারণ হোস্ট একসঙ্গে হতে পারেন না। যা সীমাবদ্ধ করতে পারেন তা হল গ্রহণ। accept_ra=2 আপলিঙ্কে রাখুন আর টানেল ও LAN ইন্টারফেস 1 বা 0-এ ছেড়ে দিন, যাতে টানেল দিয়ে আসা পথহারা বিজ্ঞাপন তার ভেতরে যাওয়া কোনো ডিফল্ট রুট বসাতে না পারে।
সাময়িক sysctl -w পরের বুট পর্যন্ত টিকবে না, আর systemd-networkd ও NetworkManager দুটোই নিজেদের কনফিগারেশন থেকে এই মানগুলো লেখে। networkd-এ আপলিঙ্কের .network ফাইলে IPv6Forwarding=yes ও IPv6AcceptRA=yes বসান; networkd কার্নেলের একই কারণে IPv6Forwarding-কে বিশ্বব্যাপী বলে নথিভুক্ত করে। NetworkManager-এ আপলিঙ্কের ipv6.method=auto-ই accept_ra মান চালায়, তাই প্রথম পরীক্ষায় ভরসা না করে nmcli connection up-এর পরে sysctl আবার পড়ুন।
স্থির বিকল্প ip -6 route add default via fe80::1 dev eth0 সত্যিই কাজ করে, আর উপরের রাউটারের স্থিতিশীল link-local ঠিকানা থাকলে এটি যুক্তিসঙ্গত উত্তর। কী ছাড়ছেন তা পরিষ্কার থাকুন। স্থির ডিফল্ট রুট কখনও নবায়ন হয় না আর কখনও প্রত্যাহৃত হয় না, তাই উপরের দিক বদলানোর পরেও এটি মৃত প্রতিবেশীর দিকে দেখাতে থাকে। RA-র রুট নিরাপদে ব্যর্থ হয়; স্থিরটি নীরবে ব্যর্থ হয়।
ফরওয়ার্ড করা প্যাকেট পরীক্ষা করুন, গেটওয়ের নিজের নয়
গেটওয়ের নিজের পিং এমন রুটে সফল হতে পারে যা কোনো ক্লায়েন্ট ব্যবহার করতে পারে না, আর সফল হতে পারে এ কারণেও যে গেটওয়েই উৎস। সংযুক্ত ক্লায়েন্ট থেকে পরীক্ষা করুন, তারপর গেটওয়েকে জিজ্ঞাসা করুন সে ওই ক্লায়েন্টের ঠিকানার জন্য কী করবে:
# on the VPN client
ping -6 -c 3 2001:4860:4860::8888
# on the gateway, using a client address
ip -6 route get 2001:4860:4860::8888 from fd42:20::2তারপর একটি রাউটার আয়ু অপেক্ষা করে আবার দেখুন। যে স্থিতিশীল অবস্থা চান তা হল proto ra চিহ্নিত ডিফল্ট রুট যার expires মান বারবার রিসেট হয়, সঙ্গে all.forwarding=1। যদি expires কেবল কমতে থাকে, বিজ্ঞাপন এখনও কোথাও বাতিল হচ্ছে, আর সাধারণ অপরাধী হল এমন নেটওয়ার্ক ম্যানেজার যা বুটের সময়ের sysctl চলে যাওয়ার পরে accept_ra আবার লেখে।
এটি বন্ধ করার আগে চারটি বিষয় নিশ্চিত করুন: ডিফল্ট রুট proto ra এবং নবায়ন হচ্ছে, accept_ra=2 কেবল আপলিঙ্কে প্রযোজ্য, রিবুটের পরে ও ম্যানেজার রিস্টার্টের পরে ফরওয়ার্ডিং এখনও 1, এবং IPv6 পিং শেষ করে একটি ক্লায়েন্ট, গেটওয়ে নয়। সুস্থ রুট থাকা সত্ত্বেও ক্লায়েন্ট ব্যর্থ হলে পরবর্তী সন্দেহভাজন হল ফেরার পথ বা উপরের ফায়ারওয়াল, বিজ্ঞাপন নয়।