VPN-এ অভ্যন্তরীণ হোস্টনেম dig-এ কেন সমাধান হয় কিন্তু curl-এ ব্যর্থ হয়
dig উত্তর দেয়, কিন্তু curl জানায় যে সে হোস্টটি সমাধান করতে পারছে না। দুটি লুকআপ শৃঙ্খল তুলনা করুন, তারপর nsswitch, প্রতি-লিংক DNS বা ভুল সার্চ সাফিক্স ঠিক করুন।
আপনার ল্যাপটপ VPN-এ আছে, dig service.internal.example 10.x ঠিকানা দিয়ে উত্তর দেয়, আর curl তবুও Could not resolve host নিয়ে বেরিয়ে যায়। টানেল সমস্যা নয়: এটি dig-এর কোয়েরি কোনো অভিযোগ ছাড়াই পৌঁছে দিয়েছে। পার্থক্য হলো প্রশ্নটি কে করে। dig আপনার নাম দেওয়া একটি সার্ভারে একটি কোয়েরি পাঠায়, অন্যদিকে curl অপারেটিং সিস্টেমের লুকআপ শৃঙ্খল দিয়ে যায়, আর সেই শৃঙ্খলের নিজস্ব নিয়ম আছে কোন সার্ভারকে জিজ্ঞাসা করা হবে।
একই নামের জন্য দুটি লুকআপ
dig নিজস্ব stub resolver। এটি /etc/resolv.conf পড়ে, একটি নেমসার্ভার বেছে নেয়, একটি A বা AAAA কোয়েরি পাঠায় এবং উত্তর ছাপে। এটি nsswitch সম্পূর্ণ এড়িয়ে যায় এবং ওই ফাইলের বাইরে systemd-resolved বা NetworkManager যে প্রতি-লিংক অবস্থা রাখে সে সম্পর্কে কিছুই জানে না, তাই dig-এর উত্তর সঠিক হতে পারে এবং তবুও আপনার অ্যাপ্লিকেশন কী দেখবে সে সম্পর্কে কিছু বলতে পারে না।
অ্যাপ্লিকেশন getaddrinfo কল করে, আর getaddrinfo দীর্ঘ শৃঙ্খল দিয়ে যায়: nsswitch-এর মডিউলের ক্রম, তারপর নামটি সামলানো মডিউল, এবং শেষে বর্তমান লিংক কনফিগারেশন থেকে গড়া resolver। systemd মেশিনে কোয়েরি 127.0.0.53-এ যায় এবং systemd-resolved tun ইন্টারফেসে যুক্ত রাউটিং ডোমেইন অনুযায়ী প্রতিটি লিংকের জন্য উপরিস্থ সার্ভার বেছে নেয়।
দুটি কমান্ড এই স্তরগুলিকে অনুমান না করে আলাদা করে:
getent ahosts service.internal.example
resolvectl query service.internal.example
getent curl-এর মতোই একই পথ ব্যবহার করে, তাই চালু dig-এর পাশে getent-এর ব্যর্থতা ত্রুটিকে প্যাকেট রাউটিংয়ে নয়, লুকআপ নীতিতে চিহ্নিত করে। resolvectl query উত্তর দেওয়া ইন্টারফেস ও উপরিস্থ সার্ভারও ছাপে, যা দেখায় টানেলের লিংক জিতেছে নাকি ভৌত লিংক।
অ্যাপ্লিকেশন যে resolver সত্যিই ব্যবহার করে তা পড়ুন
/etc/resolv.conf বেশিরভাগ ডেস্কটপে তৈরি হয়, এবং VPN ক্লায়েন্টের এটি সামলানোর তিনটি উপায় আছে: নেমসার্ভার সামনে যোগ করা, ফাইলটি উপরে লেখা, বা নিজের সার্ভারগুলি NetworkManager-কে দিয়ে ডেমনকে পুনরায় লিখতে দেওয়া। কেবল তৃতীয় নমুনা প্রতি-লিংক DNS রাখে, কারণ সার্ভারগুলি একটি বৈশ্বিক তালিকায় সমতল হওয়ার বদলে ইন্টারফেসে যুক্ত থাকে।
NetworkManager সিস্টেমে ফলাফল /etc/NetworkManager/NetworkManager.conf-এ backend-এর উপর নির্ভর করে:
[main]
dns=systemd-resolved
dns=default দিয়ে ক্লায়েন্টের সার্ভারগুলি যে ক্রমে জেতে সেই ক্রমে resolv.conf-এ মিশে যায়, এবং একটি ব্যক্তিগত কোয়েরি তবুও সার্বজনীন resolver-এ যেতে পারে। লিংক বোঝে এমন backend-এর সঙ্গে, systemd-resolved বা dnsmasq, টানেলের সার্ভারগুলি টানেলে সীমাবদ্ধ থাকে এবং সেখানে কেবল তার রাউটিং ডোমেইনের সঙ্গে মেলে এমন নাম যায়। এই সীমাবদ্ধতাই বাস্তবে split DNS-এর অর্থ, এবং ক্লায়েন্ট যখন এটি সমর্থন করার দাবি করে তখন প্রায়ই এই অংশটিই অনুপস্থিত।
কিছু বদলানোর আগে অবস্থা পড়ুন:
resolvectl status
resolvectl dns tun0
আপনি tun ইন্টারফেসটি DNS সার্ভার এবং ব্যক্তিগত সাফিক্সের জন্য রাউটিং ডোমেইনসহ তালিকাভুক্ত দেখতে চান, ~internal.example হিসেবে দেখানো। লিংকে কোনো সার্ভার না থাকা মানে ক্লায়েন্ট কিছু পাঠায়নি। ডোমেইনহীন সার্ভার মানে কোয়েরিগুলি হয় সব সেখানে যায় বা একটিও না, ক্লায়েন্টের উপর নির্ভর করে, এবং এর কোনোটিই split DNS নয়।
যেখানে nsswitch লুকআপ তাড়াতাড়ি শেষ করে
ডেস্কটপের সাধারণ লাইনটি এমন দেখায়:
hosts: files mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] dns myhostname
mdns4_minimal মাল্টিকাস্ট DNS সামলায় এবং .local-এ শেষ হওয়া প্রতিটি নামের উপর দাবি করে। api.infra.svc.cluster.local-এর মতো Kubernetes সেবাও .local-এ শেষ হয়। যখন mDNS মডিউল NOTFOUND জানায়, তখন ক্রিয়া [NOTFOUND=return] dns মডিউলের দিকে এগোনোর বদলে পুরো লুকআপ শেষ করে, তাই নামটি কখনও VPN resolver-এ পাঠানো হয় না। dig ফাইলটি সম্পূর্ণ এড়িয়ে যায়, এবং এজন্যই দুটি সরঞ্জাম একমত নয়।
এটি এই সমস্যার সবচেয়ে তীক্ষ্ণ বৈপরীত্য, এবং এটি আপনার VPN-এর চেয়ে পুরনো একটি কনফিগারেশন ফাইলের একটি শব্দে এসে দাঁড়ায়। ক্রিয়া [NOTFOUND=continue]-এ বদলালে প্রিন্টার ও স্থানীয় ডিভাইসের জন্য mDNS থাকে আর DNS নামটি দেখতে পায়। লাইনটি hosts: files dns দিয়ে বদলানোও কাজ করে এবং আরও অমসৃণ: এটি যে প্রিন্টার আপনি সত্যিই ব্যবহার করেন তার .local সমাধান বাদ দেয়।
যে নামগুলি ঠিক একটি নেটওয়ার্কেই বাস করে
ব্যক্তিগত জোন ঠিক এক জায়গায় কর্তৃত্বপূর্ণ। ip-10-0-4-31.eu-west-1.compute.internal-এর মতো AWS নাম সেই অঞ্চলের VPC resolver-এর মাধ্যমে উত্তর পায়, এবং কেবল ততক্ষণ যতক্ষণ আপনার VPN এন্ডপয়েন্ট সেই অঞ্চলে থাকে যেখানে সম্পদটি আছে। ফ্রাঙ্কফুর্টের এন্ডপয়েন্টে সংযোগ করুন, আয়ারল্যান্ডের compute.internal নাম জিজ্ঞাসা করুন, এবং কোনো স্থানীয় সেটিং সাহায্য করবে না: রেকর্ডটি ধরে রাখা জোনটি সেখান থেকে পৌঁছানোর বাইরে।
সার্চ ডোমেইন উল্টো চিত্র তৈরি করে। খালি service সেই সাফিক্স দিয়ে পূর্ণ হয় যা resolver প্রযোজ্য মনে করে, এবং VPN লিংক থাকলে স্থানীয় ডোমেইন কর্পোরেট ডোমেইনকে হারাতে পারে। অনুমান সরাতে শেষে বিন্দু দিয়ে জিজ্ঞাসা করুন, getent ahosts service.internal.example., এবং যদি তা কাজ করে অথচ ছোট নাম ব্যর্থ হয়, সংশোধন হলো টানেলে সার্চ ডোমেইন, সার্ভারের ঠিকানা নয়।
ব্যবস্থাপিত ক্লায়েন্ট সিস্টেম resolver-এর উপরে তৃতীয় স্তর যোগ করে। Windows VPN প্রোফাইল নিজের নাম-সমাধান নীতি, প্রতি-অ্যাপ নিয়ম এবং একটি NRPT সারণি বহন করতে পারে যা টানেল বন্ধ থাকলেও প্রযোজ্য। নিজস্ব DNS ক্যাশ থাকা অ্যাপ্লিকেশন, যা .NET ও Java রানটাইমে সাধারণ, শৃঙ্খল ঠিক হওয়ার পরেও পুরনো ব্যর্থতা দীর্ঘকাল ধরে রাখে। Apple ক্লায়েন্ট DNS সেটিংসে মিলে যাওয়া ডোমেইনের মাধ্যমে split DNS সেট করে, resolv.conf-এর মাধ্যমে নয়, এবং Chromium বা Firefox নিরাপদ DNS মোডে সার্বজনীন নামের জন্য সিস্টেম resolver এড়িয়ে যেতে পারে। VPN নাম-সমাধান সম্পর্কে Microsoft-এর রেফারেন্স সেই নীতি-স্তরের Windows দিক বর্ণনা করে।
কোন স্তর ঠিক করবেন তা নির্ধারণ করুন
সংশোধনগুলি ক্রমে পরখ করার বদলে লক্ষণ থেকে স্তরের দিকে এগোন:
| Symptom | What it means | Check first |
|---|---|---|
| dig answers, getent fails | lookup chain, not the packet path | nsswitch line and resolvectl status |
| Timeout rather than NXDOMAIN | private resolver unreachable through the tunnel | resolvectl dns tun0, route to that address |
| NXDOMAIN | an authority answered and does not know the name | zone owner, endpoint region |
| FQDN works, short name fails | search suffix mismatch | resolvectl domain on the tun link |
| getent works, app fails | app cache or its own resolver | restart the app, check secure DNS |
দুটি সারি বেশিরভাগ ভার বহন করে। টাইমআউট পৌঁছানোর সমস্যা: ব্যক্তিগত resolver টানেল দিয়ে উত্তর দেয় না, তাই তার ঠিকানার পথ এবং লিংকের DNS সার্ভার আপনি যা ভাবছেন তা-ই কি না দেখুন। NXDOMAIN কর্তৃত্বের সমস্যা: কিছু উত্তর দিয়েছে এবং নামটি জানে না, যা জোন, অঞ্চল বা এমন resolver-এর দিকে ইঙ্গিত করে যার এই কোয়েরি কখনও পাওয়া উচিত ছিল না।
শেষ সারিটি লোকে বাদ দেয় কারণ দুই অর্ধেই সাফল্য মনে হয়। FQDN থেকে আলাদাভাবে সমাধান হওয়া ছোট নাম সাফিক্সের অসঙ্গতি, এবং টানেল আবার যুক্ত করলে ক্লায়েন্ট কোন সাফিক্স পাঠায় তা বদলাবে না।
কনফিগারেশন ফাইল সম্পাদনার আগে অবস্থা লিখে রাখুন, যাতে বলতে পারেন সম্পাদনা কিছু করেছে কি না:
resolvectl status > before.txt
getent ahosts service.internal.example >> before.txt
পরীক্ষাগুলি এই ক্রমে চালান এবং প্রথম ব্যর্থতায় থামুন। getent ও resolvectl query মিলতে হবে; যদি getent ব্যর্থ হয় আর dig উত্তর দেয়, তবে লুকআপ শৃঙ্খলেই থাকুন এবং রাউটিং স্পর্শ করবেন না। resolvectl status-কে tun ইন্টারফেসে DNS সার্ভার ও রাউটিং ডোমেইন দেখাতে হবে। nsswitch পরীক্ষাধীন সাফিক্সের জন্য NOTFOUND-এ তাড়াতাড়ি ফিরবে না। নামটি যে নেটওয়ার্কে আপনার এন্ডপয়েন্ট যুক্ত সেখানে কর্তৃত্বপূর্ণ হতে হবে, শেষে বিন্দু দিয়ে পরীক্ষিত। অ্যাপ্লিকেশন নিজের ক্যাশ বা নিরাপদ DNS-এর ওভাররাইড রাখবে না।
কেবল প্রথম ব্যর্থ স্তরটি ঠিক করুন, তারপর একই কমান্ড আবার চালান। একসঙ্গে দুটি পরিবর্তন কোনটি গুরুত্বপূর্ণ ছিল তা বলতে দেয় না, এবং পরের ব্যর্থতা তদন্ত শূন্য থেকে শুরু করে।