OpenVPN-এ chroot ব্যর্থ: AppArmor নিয়ম নাকি capability?
AppArmor প্রোফাইলে পথ যোগ করলে কখনোই CAP_SYS_CHROOT দেওয়া হয় না, আর প্রত্যাখ্যাত chroot তিনটি আলাদা স্তর থেকে আসতে পারে। কোনটি বদলাবেন তা নির্ধারণ করুন।
ডেমন লগে chroot ব্যর্থতা লেখে আর প্রোফাইলটি আগেই উদার দেখাচ্ছে, তাই লোভনীয় সমাধান হলো একটি পথ-নিয়ম প্রশস্ত করে পুনরায় চালু করা। এটি সাধারণত কিছুই বদলায় না, কারণ chroot এমন একটি বিশেষাধিকার দিয়ে পাহারা দেওয়া হয় যা প্রোফাইল কখনোই হস্তান্তর করতে পারত না। কোন স্তরে হাত দিতে হবে তা ঠিক করতে তিনটি পরীক্ষা লাগে, আর সেগুলো সস্তা: প্রক্রিয়াটিকে কী রাখতে দেওয়া হয়েছে, নীতি কী অনুমতি দেয়, এবং চালক কোনোটিরই গুরুত্ব হওয়ার আগেই কী সরিয়ে দিয়েছে।
দুটি আলাদা দ্বার, আর কেবল একটি AppArmor-এর
chroot-এর জন্য প্রক্রিয়াটি যে ব্যবহারকারী-নামস্থানে চলছে সেখানে CAP_SYS_CHROOT দরকার। এটি সাধারণ Linux বিশেষাধিকার, কলটি পথ নিয়ে কিছু করার আগেই কার্নেল তা যাচাই করে। আলাদাভাবে, বলবৎ AppArmor প্রোফাইল প্রক্রিয়াটির কাছে থাকলেও capability প্রত্যাখ্যান করতে পারে, কারণ বাধ্যতামূলক নীতি পরিচয়পত্রের বদলে তার সঙ্গে অতিরিক্ত হিসেবে দেখা হয়। পার্থক্যটি বাস্তবে গুরুত্বপূর্ণ: দুটি স্তর আলাদা ফাইলে থাকে আর সাধারণত আলাদা মানুষই সেগুলো রক্ষণাবেক্ষণ করেন।
এই দুটি দ্বার একই errno দিয়ে ব্যর্থ হয়। দুটোই EPERM দেয় এবং দুটোই ডেমন লগে সাধারণ অনুমতি-অভিযোগ হিসেবে দেখা যায়, তাই প্রোফাইলের বিষয়বস্তু নিয়ে অনুমান করতে এত সময় নষ্ট হয়। আপনি যে পথ-নিয়মটি যোগ করতে যাচ্ছিলেন তা chroot সফল হওয়ার পরের ফাইল-প্রবেশ নিয়ন্ত্রণ করে; কাজটি আদৌ অনুমোদিত কি না তা নিয়ে তার কোনো ভূমিকা নেই।
তৃতীয় দ্বারটি দুটিরই আগে বসে। যদি সার্ভিস ম্যানেজার বা কোনো মোড়ক প্রক্রিয়াটি তার সীমানা-সেটে capability ছাড়াই চালু করে, তবে কোনো AppArmor পরিবর্তনই তা ফিরিয়ে আনতে পারে না, আর প্রোফাইলে capability যোগ করা কেবল এমন একটি অভিপ্রায় লিপিবদ্ধ করে যা কার্নেল মানবে না।
নীতি সম্পাদনার আগে বিশেষাধিকারের অবস্থা পড়ুন
আপনি যা সক্রিয় মনে করছেন সেই কনফিগারেশন থেকে নয়, চলমান প্রক্রিয়া থেকেই শুরু করুন। স্ট্যাটাস ফাইলটি পাঁচটি capability মাস্ক ও no-new-privileges ফ্ল্যাগ দেখায়, আর তারা আলাদা প্রশ্নের উত্তর দেয়:
grep -E '^(CapInh|CapPrm|CapEff|CapBnd|CapAmb|NoNewPrivs):' /proc/$(pidof openvpn)/status
sudo aa-status | grep -i openvpnCapEff হলো সেই সেট যা কলটির জন্য গুরুত্বপূর্ণ: CapBnd-এ থাকা কিন্তু CapEff-এ না থাকা capability সিলিং দ্বারা অনুমোদিত, তবে এখন ধরা নেই। CapAmb তখন গুরুত্বপূর্ণ যখন বাইনারিটি প্রচলিত setuid অর্থে বিশেষাধিকারপ্রাপ্ত নয়, কারণ ambient capability হলো ফাইল-ক্যাপাবিলিটি ছাড়া exec জুড়ে বিশেষাধিকার ধরে রাখার উপায়। CapInh এমন বিট ধরে যা exec জুড়ে উত্তরাধিকারসূত্রে পাওয়া যেতে পারে, কিন্তু কেবল যখন চালিত ফাইলের উত্তরাধিকার-সেট তা অনুমতি দেয়, তাই সেখানে একটি বিট নিজে থেকে কিছুই দেয় না।
তারপর নিশ্চিত করুন কোন প্রোফাইলটি সত্যিই সংযুক্ত। একটি প্রক্রিয়া এমন প্রোফাইল-নামে আবদ্ধ থাকতে পারে যা আপনি আশা করেননি, বিশেষত যখন কোনো ডিস্ট্রিবিউশন নিজের unit ফাইল ও প্রোফাইল একসঙ্গে পাঠায়, আর /proc/PID/attr/current পড়লে এক লাইনেই তা মীমাংসা হয়। আপনার সম্পাদিত ফাইলকে কার্নেল যে প্রোফাইল জানায় তার সঙ্গে তুলনা করাই কারণ সারানো আর কেউ না-লোড-করা ফাইল সম্পাদনার মধ্যে পার্থক্য।
অডিট-চিহ্ন যেখানে বলে কেবল সেখানেই capability নিয়ম যোগ করুন
কার্নেল ও অডিট রেকর্ড প্রত্যাখ্যানকারী স্তরের নাম বলে। এমন প্রত্যাখ্যান খুঁজুন যাতে অপারেশন capable ও নাম sys_chroot থাকে, সঙ্গে যে প্রোফাইল তা তৈরি করেছে। যদি সেই রেকর্ড থাকে, তবে প্রক্রিয়াটি capability আগেই ধরে ছিল আর AppArmor তা প্রত্যাখ্যান করেছে, আর লক্ষ্যযুক্ত পরিবর্তন হলো আসল প্রোফাইলের ভিতরে একটি capability নিয়ম:
capability sys_chroot,এটি সত্যিই সংযুক্ত প্রোফাইলে খণ্ড হিসেবে রাখুন, এবং অসম্পর্কিত টিউটোরিয়াল থেকে নিয়ম কপি না করে কীওয়ার্ডটি apparmor.d প্রোফাইল রেফারেন্স-এর সঙ্গে মিলিয়ে নিন। এটিকে শেয়ার্ড include-এ ফেলে দিলে যে কোনো আবদ্ধ প্রোগ্রাম যা সেই ফাইল টানে তার সবাই তা পায়, আর প্রোফাইলকে complain মোডে বদলালে এই প্রত্যাখ্যান সমাধান না হয়ে পরের প্রত্যাখ্যানটিই লুকিয়ে যায়। প্রোফাইল-নিয়ম নীতির প্রত্যাখ্যান সরায়; এটি বিশেষাধিকার তৈরি করে না, তাই যে প্রক্রিয়ার কার্যকর সেটে কখনো CAP_SYS_CHROOT ছিল না, নিয়ম থাকলেও তার ব্যর্থতা থামবে না।
যদি অডিট রেকর্ডে কোনো AppArmor প্রত্যাখ্যানই না থাকে, তবে প্রোফাইল সম্পাদনা বন্ধ করুন। আপনি পরিচয়পত্রের সমস্যার মুখোমুখি, আর বাকি কাজ unit ফাইলে বা মূল প্রক্রিয়ায়, নীতির ভাষায় নয়।
সার্ভিস ম্যানেজার নিজের সিলিং রাখে
systemd প্রতিটি সার্ভিসের জন্য একটি capability সীমানা-সেট নির্ধারণ করে, আর ডিফল্টে সেই সেট সংকীর্ণ। সেখানে বাদ পড়া কিছু প্রোফাইল যা-ই বলুক প্রক্রিয়ার জন্য অনুপলব্ধ, তাই কঠোর unit কখনো এমন কাজে ব্যর্থ হতে পারে যা ডেমন হাতে চালালে কাজ করত। সংশ্লিষ্ট নির্দেশিকাগুলো unit-এ পড়া সহজ আর অ্যাপ্লিকেশন যখন ত্রুটি জানায় তখন চোখ এড়ানোও সহজ। ডিস্ট্রিবিউশন প্যাকেজের পাঠানো drop-in-ই সাধারণত এমন সিলিংয়ের উৎস যা কেউ মনে রাখে না যে সে কনফিগার করেছিল।
সিলিং বাড়ানো আর capability দেওয়া দুটি পরিবর্তন, একটি নয়। সীমানা-সেটের এন্ট্রি বলে প্রক্রিয়া capability ধরে রাখতে পারে; এটি তা কার্যকর সেটে যোগ করে না, আর NoNewPrivs পরের কোনো উন্নয়ন সফল হওয়া আটকে দিতে পারে এমনকি সবকিছু মিললেও। কেবল কাজটির যা দরকার তাই যোগ করুন, বাকি কঠোরতা অটুট রাখুন, আর একটি কল পার করাতে সব capability দিয়ে দেওয়ার শর্টকাট প্রতিরোধ করুন।
এখানে ক্রমও গুরুত্বপূর্ণ। আগে unit-এর সিলিং বদলান, CapEff-এ এখন বিটটি আছে কি না যাচাই করুন, তারপরেই ঠিক করুন AppArmor এখনো প্রত্যাখ্যান করে কি না। দুটি পরিবর্তন একসঙ্গে করলে ব্যর্থতা চলতে থাকলে আবার অনুমানে পড়বেন।
প্রত্যাখ্যান সরে গেলে জেলখানাটি নিজেই পরীক্ষা করুন
সফল chroot রুট সরিয়ে দেয়, তাই ডেমন এরপর যে পথেই হাত দেয় তা নতুন বৃক্ষের ভিতরে সমাধান হয়। অনুপস্থিত কনফিগারেশন, নেই এমন ডিভাইস নোড বা কপি না-হওয়া সার্টিফিকেট ডিরেক্টরি এখন ফাইল-ত্রুটি হিসেবে দেখাবে, আর সেই ত্রুটি capability-র নয়, বিন্যাসের সমস্যা। আরেকটি প্রশস্ত অনুমতি যোগ না করে পরের ঘটনাটি পড়ুন। এই সরে যাওয়া আপেক্ষিক পথের অর্থও বদলায়, তাই কঠোরতা-নির্দেশিকাগুলো ডেমন কনফিগারেশনে পরম পথ জোর দেয়।
chroot কী করে না তাও মনে রাখা সহায়ক। এটি পথের সীমা, স্যান্ডবক্স নয়: যে প্রক্রিয়া বিশেষাধিকার ধরে রাখে সে তা থেকে বেরোতে পারে, তাই কলের পরে সাধারণত capability নামানো হয় আর তাই ডেমনকে ঘিরে অবরোধ চালু থাকা উচিত। AppArmor প্রোফাইল, capability সীমানা-সেট ও ফাইলসিস্টেম নিষেধাজ্ঞা একসঙ্গে ধরে রাখাই এই অনুশীলনের উদ্দেশ্য, সার্ভিস চালু হলেই সরানোর মতো উদ্বৃত্ত কিছু নয়।
সিদ্ধান্তের নিয়ম সংক্ষিপ্ত। অডিট রেকর্ড AppArmor-এর নাম বললে সংযুক্ত প্রোফাইলে একটি capability নিয়ম যোগ করুন। কার্যকর সেট খালি হলে unit-এর সিলিং ও বিশেষাধিকার নামানোর ক্রম ঠিক করুন। প্রোফাইলটি আপনার সম্পাদিতটি না হলে সম্পাদনা বন্ধ করে আসলটি খুঁজুন।