SELinux ডিফল্টভাবে ডিনাই (deny) মোডে সেট করা থাকে, যার মানে হলো কার্নেলে এর হুক থাকা প্রতিটি অ্যাক্সেসকে অবশ্যই পলিসির মাধ্যমে সুস্পষ্টভাবে অনুমতি দিতে হয়। এর ফলে একটি পলিসি ফাইলে রুল, টাইপ, ক্লাস, পারমিশন এবং আরও অনেক কিছু সম্পর্কিত প্রচুর তথ্য থাকে। SELinux-এর সম্পূর্ণ আলোচনা এই ডকুমেন্টের আওতার বাইরে, কিন্তু নতুন অ্যান্ড্রয়েড ডিভাইস চালু করার সময় পলিসি রুল কীভাবে লিখতে হয় সে সম্পর্কে ধারণা থাকা এখন অপরিহার্য। SELinux সম্পর্কে ইতিমধ্যেই প্রচুর তথ্য পাওয়া যায়। প্রস্তাবিত রিসোর্সের জন্য সাপোর্টিং ডকুমেন্টেশন দেখুন।
মূল ফাইল
SELinux সক্রিয় করতে, সর্বশেষ অ্যান্ড্রয়েড কার্নেলটি ইন্টিগ্রেট করুন এবং তারপরে system/sepolicy ডিরেক্টরিতে থাকা ফাইলগুলি অন্তর্ভুক্ত করুন। কম্পাইল করা হলে, এই ফাইলগুলি SELinux কার্নেল নিরাপত্তা নীতি গঠন করে এবং আপস্ট্রিম অ্যান্ড্রয়েড অপারেটিং সিস্টেমকে সুরক্ষিত রাখে।
সাধারণত, আপনার সরাসরি system/sepolicy ফাইলগুলো পরিবর্তন করা উচিত নয়। এর পরিবর্তে, /device/ manufacturer / device-name /sepolicy ডিরেক্টরিতে আপনার নিজস্ব ডিভাইস-নির্দিষ্ট পলিসি ফাইল যোগ বা সম্পাদনা করুন। Android 8.0 এবং তার উপরের সংস্করণগুলোতে, এই ফাইলগুলোতে আপনার করা পরিবর্তনগুলো শুধুমাত্র আপনার vendor ডিরেক্টরির পলিসিকেই প্রভাবিত করবে। Android 8.0 এবং তার উপরের সংস্করণগুলোতে পাবলিক sepolicy-এর পৃথকীকরণ সম্পর্কে আরও বিস্তারিত জানতে, Customizing SEPolicy in Android 8.0+ দেখুন। Android সংস্করণ যাই হোক না কেন, আপনি এই ফাইলগুলোই পরিবর্তন করছেন:
নীতি ফাইল
যে ফাইলগুলির শেষে *.te থাকে, সেগুলি হলো SELinux পলিসি সোর্স ফাইল, যা ডোমেইন এবং তাদের লেবেল নির্ধারণ করে। আপনার /device/ manufacturer / device-name /sepolicy তে নতুন পলিসি ফাইল তৈরি করার প্রয়োজন হতে পারে, তবে যেখানে সম্ভব বিদ্যমান ফাইলগুলি আপডেট করার চেষ্টা করা উচিত।
প্রসঙ্গ ফাইল
কন্টেক্সট ফাইলে আপনি আপনার অবজেক্টগুলোর জন্য লেবেল নির্দিষ্ট করেন।
-
file_contextsফাইলগুলিতে লেবেল নির্ধারণ করে এবং এটি বিভিন্ন ইউজারস্পেস কম্পোনেন্ট দ্বারা ব্যবহৃত হয়। আপনি যখন নতুন পলিসি তৈরি করবেন, তখন ফাইলগুলিতে নতুন লেবেল নির্ধারণ করার জন্য এই ফাইলটি তৈরি বা আপডেট করুন। নতুনfile_contextsপ্রয়োগ করতে, ফাইলসিস্টেম ইমেজটি রিবিল্ড করুন অথবা যে ফাইলটির লেবেল পরিবর্তন করতে হবে সেটির উপরrestoreconচালান। আপগ্রেডের সময়,file_contextsএর পরিবর্তনগুলি আপগ্রেডের অংশ হিসাবে সিস্টেম এবং ইউজারডেটা পার্টিশনে স্বয়ংক্রিয়ভাবে প্রয়োগ করা হয়। পার্টিশনটি রিড-রাইট হিসেবে মাউন্ট করার পরে আপনার board ফাইলেrestorecon_recursiveকল যোগ করে আপগ্রেডের সময় অন্যান্য পার্টিশনেও পরিবর্তনগুলি স্বয়ংক্রিয়ভাবে প্রয়োগ করা যেতে পারে। -
genfs_contextsসেইসব ফাইলসিস্টেমকে লেবেল প্রদান করে, যেমনprocবাvfatযেগুলো এক্সটেন্ডেড অ্যাট্রিবিউট সমর্থন করে না। এই কনফিগারেশনটি কার্নেল পলিসির অংশ হিসেবে লোড করা হয়, কিন্তু পরিবর্তনগুলো ইন-কোর ইনোডগুলোর জন্য কার্যকর নাও হতে পারে। পরিবর্তনটি সম্পূর্ণরূপে প্রয়োগ করার জন্য রিবুট অথবা ফাইলসিস্টেমটি আনমাউন্ট ও রি-মাউন্ট করার প্রয়োজন হতে পারে।context=mountঅপশনটি ব্যবহার করে নির্দিষ্ট মাউন্ট, যেমনvfat, নির্দিষ্ট লেবেলও প্রদান করা যেতে পারে। -
property_contextsঅ্যান্ড্রয়েড সিস্টেম প্রপার্টিগুলোতে লেবেল নির্ধারণ করে, যার মাধ্যমে কোন প্রসেসগুলো সেগুলো সেট করতে পারবে তা নিয়ন্ত্রণ করা হয়। স্টার্টআপের সময়initপ্রসেস এই কনফিগারেশনটি পড়ে নেয়। -
service_contextsঅ্যান্ড্রয়েড বাইন্ডার সার্ভিসগুলোকে লেবেল প্রদান করে, যা নিয়ন্ত্রণ করে কোন প্রসেসগুলো সেই সার্ভিসের জন্য একটি বাইন্ডার রেফারেন্স যোগ (রেজিস্টার) এবং খুঁজে (লুকআপ) নিতে পারবে। এই কনফিগারেশনটি স্টার্টআপের সময়servicemanagerপ্রসেস দ্বারা পঠিত হয়। -
seapp_contextsঅ্যাপ প্রসেস এবং/data/dataডিরেক্টরিগুলোতে লেবেল নির্ধারণ করে। এই কনফিগারেশনটি প্রতিটি অ্যাপ চালুর সময়zygoteপ্রসেস দ্বারা এবং স্টার্টআপের সময়installdদ্বারা পঠিত হয়। -
mac_permissions.xmlঅ্যাপগুলোর সিগনেচার এবং ঐচ্ছিকভাবে তাদের প্যাকেজ নামের উপর ভিত্তি করে একটিseinfoট্যাগ নির্ধারণ করে। এরপর সেইseinfoট্যাগযুক্ত সমস্ত অ্যাপকে একটি নির্দিষ্ট লেবেল দেওয়ার জন্যseapp_contextsফাইলে এইseinfoট্যাগটিকে একটি কী (key) হিসেবে ব্যবহার করা যায়। স্টার্টআপের সময়system_serverএই কনফিগারেশনটি পড়ে নেয়। -
keystore2_key_contextsফাইলটি Keystore 2 নেমস্পেসগুলোকে লেবেল প্রদান করে। এই নেমস্পেসগুলোkeystore2ডেমন দ্বারা বলবৎ করা হয়। Keystore বরাবরই UID/AID ভিত্তিক নেমস্পেস সরবরাহ করে আসছে। Keystore 2 অতিরিক্তভাবে sepolicy দ্বারা সংজ্ঞায়িত নেমস্পেসগুলোও বলবৎ করে। এই ফাইলের ফরম্যাট এবং প্রচলিত নিয়মাবলীর একটি বিস্তারিত বিবরণ এখানে পাওয়া যাবে।
BoardConfig.mk মেকফাইল
পলিসি এবং কনটেক্সট ফাইল সম্পাদনা বা যোগ করার পরে, sepolicy সাবডিরেক্টরি এবং প্রতিটি নতুন পলিসি ফাইলকে রেফারেন্স করার জন্য /device/ manufacturer / device-name /BoardConfig.mk মেকফাইলটি আপডেট করুন। BOARD_SEPOLICY ভেরিয়েবল সম্পর্কে আরও তথ্যের জন্য, system/sepolicy/README ফাইলটি দেখুন।
BOARD_SEPOLICY_DIRS += \
<root>/device/manufacturer/device-name/sepolicy
BOARD_SEPOLICY_UNION += \
genfs_contexts \
file_contexts \
sepolicy.te
পুনর্গঠনের পর, আপনার ডিভাইসে SELinux সক্রিয় হয়ে যাবে। এখন আপনি কাস্টমাইজেশন অংশে বর্ণিত পদ্ধতি অনুযায়ী অ্যান্ড্রয়েড অপারেটিং সিস্টেমে আপনার নিজস্ব সংযোজনগুলোর জন্য SELinux পলিসিগুলো কাস্টমাইজ করতে পারেন, অথবা ভ্যালিডেশন অংশে বর্ণিত পদ্ধতি অনুযায়ী আপনার বিদ্যমান সেটআপ যাচাই করতে পারেন।
যখন নতুন পলিসি ফাইল এবং BoardConfig.mk আপডেটগুলো ইনস্টল করা হয়, তখন নতুন পলিসি সেটিংসগুলো স্বয়ংক্রিয়ভাবে চূড়ান্ত কার্নেল পলিসি ফাইলে অন্তর্ভুক্ত হয়ে যায়। ডিভাইসে sepolicy কীভাবে তৈরি হয় সে সম্পর্কে আরও তথ্যের জন্য, Building sepolicy দেখুন।
বাস্তবায়ন
SELinux দিয়ে শুরু করতে:
- কার্নেলে SELinux সক্রিয় করুন:
CONFIG_SECURITY_SELINUX=y - kernel_cmdline অথবা bootconfig প্যারামিটারটি এমনভাবে পরিবর্তন করুন যাতে:
অথবাBOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
এটি শুধুমাত্র ডিভাইসের জন্য পলিসির প্রাথমিক বিকাশের উদ্দেশ্যে। আপনার একটি প্রাথমিক বুটস্ট্র্যাপ পলিসি তৈরি হয়ে গেলে, এই প্যারামিটারটি সরিয়ে ফেলুন, যাতে আপনার ডিভাইসটি তা কার্যকর করে, নতুবা এটি CTS পরীক্ষায় ব্যর্থ হবে।BOARD_BOOTCONFIG := androidboot.selinux=permissive
- সিস্টেমটি পারমিসিভ মোডে বুট করুন এবং দেখুন বুট করার সময় কী কী ডিনায়াল (প্রত্যাখ্যান) দেখা দেয়:
উবুন্টু ১৪.০৪ বা তার পরবর্তী সংস্করণে: উবুন্টু ১২.০৪-এ:adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
adb pull /sys/fs/selinux/policy adb logcat -b all | audit2allow -p policy
- আউটপুটে
init: Warning! Service name needs a SELinux domain defined; please fix!নির্দেশাবলী এবং সরঞ্জামগুলির জন্য ভ্যালিডেশন দেখুন। - ডিভাইস এবং অন্যান্য নতুন ফাইলগুলো শনাক্ত করুন যেগুলোতে লেবেল লাগানো প্রয়োজন।
- আপনার অবজেক্টগুলোর জন্য বিদ্যমান বা নতুন লেবেল ব্যবহার করুন। পূর্বে বিষয়গুলোকে কীভাবে লেবেল করা হয়েছিল তা দেখতে
*_contextsফাইলগুলো দেখুন এবং লেবেলের অর্থ সম্পর্কে আপনার জ্ঞান ব্যবহার করে একটি নতুন লেবেল নির্ধারণ করুন। আদর্শগতভাবে, এটি এমন একটি বিদ্যমান লেবেল হওয়া উচিত যা নীতির সাথে সামঞ্জস্যপূর্ণ, কিন্তু কখনও কখনও একটি নতুন লেবেলের প্রয়োজন হয় এবং সেই লেবেলে অ্যাক্সেসের জন্য নিয়মেরও প্রয়োজন হয়। আপনার লেবেলগুলো উপযুক্ত কনটেক্সট ফাইলগুলোতে যুক্ত করুন। - সেইসব ডোমেইন/প্রসেস শনাক্ত করুন যাদের নিজস্ব সিকিউরিটি ডোমেইন থাকা উচিত। সম্ভবত আপনাকে প্রতিটির জন্য একটি সম্পূর্ণ নতুন পলিসি লিখতে হবে। উদাহরণস্বরূপ,
initথেকে তৈরি হওয়া সমস্ত সার্ভিসের নিজস্ব ডোমেইন থাকা উচিত। নিম্নলিখিত কমান্ডগুলো চলমান সার্ভিসগুলোকে খুঁজে বের করতে সাহায্য করে (কিন্তু সমস্ত সার্ভিসের জন্যই এই ধরনের ব্যবস্থা প্রয়োজন):adb shell su -c ps -Z | grep init
adb shell su -c dmesg | grep 'avc: '
init. device .rcপর্যালোচনা করে এমন ডোমেইনগুলো শনাক্ত করুন যেগুলোর কোনো ডোমেইন টাইপ নেই। আপনার ডেভেলপমেন্ট প্রক্রিয়ার শুরুতেই সেগুলোকে একটি ডোমেইন দিন, যাতেinitএ নতুন নিয়ম যোগ করা এড়ানো যায় অথবাinitঅ্যাক্সেসকে তাদের নিজস্ব পলিসির অ্যাক্সেসের সাথে গুলিয়ে ফেলা না হয়।-
BOARD_SEPOLICY_*ভেরিয়েবল ব্যবহার করার জন্যBOARD_CONFIG.mkসেট আপ করুন। এটি কীভাবে সেট আপ করতে হয় তার বিস্তারিত জানতেsystem/sepolicyতে থাকা README দেখুন। - device এবং device ফাইল দুটি পরীক্ষা করুন এবং নিশ্চিত করুন যে
mountএর প্রতিটি ব্যবহার একটি যথাযথভাবে লেবেলযুক্ত ফাইলসিস্টেমের সাথে সঙ্গতিপূর্ণ অথবা একটিcontext= mountঅপশন নির্দিষ্ট করা আছে। - প্রতিটি অস্বীকৃতি পর্যালোচনা করুন এবং সেগুলোকে যথাযথভাবে পরিচালনা করার জন্য SELinux পলিসি তৈরি করুন। কাস্টমাইজেশন অংশে উদাহরণগুলো দেখুন।
আপনার AOSP-তে থাকা পলিসিগুলো দিয়ে শুরু করা উচিত এবং তারপর নিজের কাস্টমাইজেশনের জন্য সেগুলোর উপর ভিত্তি করে কাজ করা উচিত। পলিসি স্ট্র্যাটেজি সম্পর্কে আরও তথ্যের জন্য এবং এই ধাপগুলোর কয়েকটি বিশদ বিবরণের জন্য, "Writing SELinux Policy" দেখুন।
ব্যবহারের ক্ষেত্র
আপনার নিজের সফ্টওয়্যার এবং সংশ্লিষ্ট SELinux পলিসি তৈরি করার সময় বিবেচনা করার মতো কিছু এক্সপ্লয়েটের নির্দিষ্ট উদাহরণ নিচে দেওয়া হলো:
সিমলিঙ্ক: যেহেতু সিমলিঙ্কগুলো ফাইল হিসেবে প্রদর্শিত হয়, তাই এগুলোকে প্রায়শই ফাইল হিসেবেই পড়া হয়, যা এক্সপ্লয়েটের কারণ হতে পারে। উদাহরণস্বরূপ, init মতো কিছু প্রিভিলেজড কম্পোনেন্ট নির্দিষ্ট কিছু ফাইলের পারমিশন পরিবর্তন করে দেয়, যা কখনও কখনও অতিরিক্ত উন্মুক্ত হয়ে যায়।
এরপর আক্রমণকারীরা সেই ফাইলগুলোকে তাদের নিয়ন্ত্রিত কোডের সিমলিঙ্ক দিয়ে প্রতিস্থাপন করতে পারে, যার ফলে আক্রমণকারী যেকোনো ফাইল ওভাররাইট করতে পারে। কিন্তু যদি আপনি জানেন যে আপনার অ্যাপ কখনোই কোনো সিমলিঙ্ক ব্যবহার করে না, তাহলে আপনি SELinux ব্যবহার করে এটিকে তা করতে নিষেধ করতে পারেন।
সিস্টেম ফাইল: এমন এক শ্রেণীর সিস্টেম ফাইলের কথা ভাবুন যা শুধুমাত্র সিস্টেম সার্ভার দ্বারা পরিবর্তিত হওয়া উচিত। তবুও, যেহেতু netd , init , এবং vold রুট হিসেবে চলে, তাই তারা সেই সিস্টেম ফাইলগুলো অ্যাক্সেস করতে পারে। সুতরাং, যদি netd হ্যাক হয়, তবে এটি সেই ফাইলগুলোকে এবং সম্ভবত স্বয়ং সিস্টেম সার্ভারকেও হ্যাক করতে পারে।
SELinux-এর সাহায্যে, আপনি ঐ ফাইলগুলোকে সিস্টেম সার্ভার ডেটা ফাইল হিসেবে শনাক্ত করতে পারেন। তাই, একমাত্র সিস্টেম সার্ভার ডোমেইনেরই সেগুলোতে রিড/রাইট অ্যাক্সেস আছে। এমনকি netd হ্যাক হলেও, এটি রুট হিসেবে চললেও সিস্টেম সার্ভার ডোমেইনে সুইচ করে ঐ সিস্টেম ফাইলগুলো অ্যাক্সেস করতে পারবে না।
অ্যাপ ডেটা: আরেকটি উদাহরণ হলো সেই শ্রেণীর ফাংশন, যেগুলোকে অবশ্যই রুট হিসেবে চালাতে হবে কিন্তু অ্যাপ ডেটা অ্যাক্সেস করার সুযোগ দেওয়া উচিত নয়। এটি অত্যন্ত কার্যকর, কারণ এর মাধ্যমে ব্যাপক পরিসরের দাবি করা যেতে পারে, যেমন অ্যাপ ডেটার সাথে সম্পর্কহীন নির্দিষ্ট ডোমেইনকে ইন্টারনেট অ্যাক্সেস থেকে নিষিদ্ধ করা।
setattr: chmod এবং chown মতো কমান্ডের জন্য, আপনি সেই ফাইলগুলির সেট নির্দিষ্ট করতে পারেন যেখানে সংশ্লিষ্ট ডোমেইন setattr চালাতে পারে। এর বাইরের যেকোনো কিছুকে এই পরিবর্তনগুলি থেকে নিষিদ্ধ করা যেতে পারে, এমনকি রুটের দ্বারাও। তাই একটি অ্যাপ app_data_files লেবেলযুক্ত ফাইলগুলির বিরুদ্ধে chmod এবং chown চালাতে পারে, কিন্তু shell_data_files বা system_data_files বিরুদ্ধে নয়।