status=200/CHDIR: systemd কখনোই OpenVPN চালু করেনি
CHDIR ব্যর্থতার অর্থ হলো systemd কোনো ডিরেক্টরিতে ঢুকতে পারেনি, OpenVPN প্রোফাইল পড়তে পারেনি নয়। VPN কনফিগারেশন ছুঁয়ে দেখার আগে unit পড়ুন।
সার্ভিসটি ব্যর্থ হয়, লগে spawn আর একটি ডিরেক্টরির কথা থাকে, এবং প্রথম প্রবৃত্তি হলো VPN কনফিগারেশন পরীক্ষা করা। ওই ফাইল থেকে এখনো কিছুই পড়া হয়নি। systemd প্রসেস তৈরি করার সময়, এক্সিকিউটেবল চালু হওয়ার আগেই ব্যর্থ হয়েছিল, তাই কোনো parser, কোনো সার্টিফিকেট এবং কোনো দূরবর্তী হোস্টের পরামর্শ নেওয়া হয়নি। স্ট্যাটাস কোডটিকে OpenVPN সম্পর্কে নয় বরং systemd সম্পর্কে বিবৃতি হিসেবে পড়াই একে ছোট তদন্তে পরিণত করে।
অ্যাপ্লিকেশনের আগে স্ট্যাটাস কোড পড়ুন
সার্ভিসের নামের পরের সংখ্যাসূচক কোডটি যে ধাপটি ব্যর্থ হয়েছে তার নাম দেয়। ডিরেক্টরি ব্যর্থতা CHDIR স্ট্যাটাস হিসেবে রিপোর্ট হয়, অন্যদিকে চালানো যায়নি এমন এক্সিকিউটেবল সম্পূর্ণ ভিন্ন কোড। দুটোই সারসংক্ষেপের এক লাইনে একই রকম দেখায় এবং তাদের কারণের মধ্যে কোনো মিল নেই।
এই পার্থক্যটি গুরুত্বপূর্ণ কারণ সংশোধনগুলো আলাদা ফাইলে থাকে। CHDIR ব্যর্থতা একটি পথ এবং সার্ভিস সেটিকে কীভাবে দেখে তা নিয়ে। Exec ব্যর্থতা বাইনারি, তার ইন্টারপ্রেটার বা অসম্পর্কিত mount নিয়ে। VPN-এর দূরবর্তী পয়েন্ট, সাইফার তালিকা বা সার্টিফিকেটের পথ বদলে এগুলোর কোনোটিই সারানো যায় না।
নিশ্চিত করুন যে ব্যর্থতা শুরুতে, সফল চালনার পরে নয়। যদি সার্ভিসটি গতকাল চলত আর এখন একই ধাপে ব্যর্থ হয়, তবে ডিরেক্টরি, তার অনুমতি বা unit নিজেই কিছুটা বদলেছে, এবং সেই পরিবর্তনই খুঁজতে হবে এমন প্রমাণ।
unit-কে জিজ্ঞেস করুন সে কোথায় থাকতে চায়
কার্যকর unit পড়ুন, আপনি যেটিকে ইনস্টল করা ভাবছেন সেটি নয়, কারণ drop-in ফাইলগুলো মূল unit সম্পাদনা না করেই কাজের ডিরেক্টরি অগ্রাহ্য করতে পারে। show-এর আউটপুট প্রশ্নের সরাসরি উত্তর দেয়:
systemctl cat [email protected]
systemctl show [email protected] -p WorkingDirectory -p RootDirectory -p User -p ProtectHome
journalctl -u [email protected] -b --no-pager | tail -30
upstream সার্ভার টেমপ্লেটের জন্য কাজের ডিরেক্টরি হলো সার্ভার কনফিগারেশন ডিরেক্টরি এবং ইনস্ট্যান্সের নাম তার ভেতরের প্রোফাইল নির্বাচন করে। তাই branch নামের ইনস্ট্যান্স একই ডিরেক্টরিতে নিজের ফাইল আশা করে, আর অন্য কোথাও রাখা প্রোফাইল কাজের ডিরেক্টরির শর্ত একেবারেই পূরণ করে না।
unit যা চায় তার সঙ্গে যা আছে তার তুলনা করুন। আগে যে পথ ছিল, এখন অন্য দিকে ইশারা করা সিম্বলিক লিংক, বা আর কোনো ডিরেক্টরির সঙ্গে না মেলা ইনস্ট্যান্সের নাম—সবই সাধারণ পরিবর্তন যা ঠিক এই ব্যর্থতাই ঘটায়।
পথটি সার্ভিস যেভাবে দেখে সেভাবে পরীক্ষা করুন
আপনার shell আর সার্ভিস ফাইল সিস্টেমের একই দৃশ্য ভাগ করে না। কনফিগার করা রুট ডিরেক্টরি বা root image unit-এর ভেতরে পরম পথের অর্থ বদলে দেয়, এবং হোস্টে স্পষ্টভাবে থাকা পথ ওই নামের জায়গায় না-ও থাকতে পারে। হাতে-কলমে পরীক্ষায় ভরসা করার আগে unit-এর সেটিংস পড়ুন।
অনুমতিগুলো সমস্যা বাড়ায়। সার্ভিসটি একটি নির্দিষ্ট ব্যবহারকারী হিসেবে চলে, এবং সেই ব্যবহারকারীকে লক্ষ্যে পৌঁছাতে প্রতিটি অভিভাবক ডিরেক্টরি অতিক্রম করতে হতে হবে, শুধু লক্ষ্যটি পড়তে পারলেই হবে না। root-এর জন্য পঠনযোগ্য কিন্তু সার্ভিস ব্যবহারকারীর জন্য অতিক্রমযোগ্য নয় এমন ডিরেক্টরি এমন ব্যর্থতা ঘটায় যা অনুপস্থিত পথের মতো দেখায়।
namei -l /etc/openvpn/server
systemctl show [email protected] -p ProtectSystem -p ReadOnlyPaths
কঠোর করার সেটিংসও এই ছবির অংশ। যে unit হোম ডিরেক্টরিগুলো লুকায় বা ফাইল সিস্টেমের একটি অংশ কেবল-পঠনযোগ্য করে, সে ঠিক তার জন্যই কনফিগার করা কাজটিই করে, আর কাজের ডিরেক্টরিকে থাকতে হবে এমন জায়গায় যেখানে sandbox এখনো সেটি প্রকাশ করে।
মালিক ঠিক করুন, তারপর অন্য ত্রুটির অপেক্ষা করুন
লেআউট বা unit সংশোধন করুন সেই ব্যক্তির মাধ্যমে যার ওই কনফিগারেশনের মালিকানা আছে। প্রোফাইল প্রত্যাশিত ডিরেক্টরিতে সরানো বৈধ সংশোধন যখন লেআউট ভুল, কিন্তু এটি এমন ডিরেক্টরির ব্যাখ্যা দেয় না যেখানে ঢোকা যায় না, তাই এটিকে সাধারণ উত্তর হিসেবে নেবেন না।
কনফিগারেশন ট্রিতে অনুমতি বাড়ানো বা sandbox সরানোর শর্টকাটের প্রতিরোধ করুন। দুটোই লক্ষণ মিটিয়ে দেয় আর সঙ্গে সেই সুরক্ষাগুলোও সরায় যা সেখানে সচেতনভাবে রাখা হয়েছিল, এবং পরের ব্যর্থতাটি ব্যাখ্যা করা আরও কঠিন হবে।
ইনস্ট্যান্স পুনরায় চালু করুন এবং সফলতা ধরে নেওয়ার বদলে পরের ঘটনাটি পড়ুন। সম্ভাব্য পরের ত্রুটি হলো OpenVPN তার কনফিগারেশন ফাইল খুলতে পারছে না, যা অগ্রগতি: কাজের ডিরেক্টরিতে ঢোকা হয়েছে এবং parser এখন চলছে। সেখান থেকে unit-এর প্রকৃত ফাইল ম্যাপিং অনুসরণ করুন, নেটওয়ার্ক সমস্যা সমাধানে ফিরে যাবেন না।
systemd-এর এক্সিকিউশন রেফারেন্স নির্ধারণ করে কাজের ডিরেক্টরিকে রুট ডিরেক্টরি ও sandbox-এর সঙ্গে কীভাবে ব্যাখ্যা করা হয়। মনে রাখার প্যাটার্নটি সহজ: প্রতিটি স্ট্যাটাস কোড আলাদা ধাপের নাম দেয়, এবং কেবল অ্যাপ্লিকেশনের নিজের ত্রুটিই অ্যাপ্লিকেশনকে বর্ণনা করে।