OpenVPN-এ root না দিয়েই CAP_NET_ADMIN দেওয়া
অসুবিধাহীন ব্যবহারকারী হিসেবে শুরু হওয়া একটি ইউনিটের তবুও সঠিক ক্যাপাবিলিটি সেট দরকার। ইউনিট, চালু প্রক্রিয়া ও exec সীমা এই ক্রমেই যাচাই করুন।
সার্ভিসটি শুরু হয়, লগ অভিযোগ করে যে এটি tun ডিভাইস খুলতে পারছে না, আর রুট কখনও দেখা যায় না। আপনার শেলে capsh --print চালান এবং cap_net_admin ঠিক সেখানেই আছে, যা ব্যর্থতাকে অসম্ভব দেখায়। আপনার শেল ও ইউনিটের মধ্যে পার্থক্য হলো সুবিধা হস্তান্তর, কার্নেলের ক্যাপাবিলিটি দেওয়ার ইচ্ছা নয়। নিচের চারটি যাচাই ক্রমে করুন এবং যে প্রথমটি ব্যবধানটি ব্যাখ্যা করে সেখানেই থামুন।
অনুপস্থিত ক্যাপাবিলিটিকে লুকানো ডিভাইস থেকে আলাদা করুন
লগ লাইন থেকে দুটি ব্যর্থতা একই রকম দেখায়। CAP_NET_ADMIN ছাড়া একটি প্রক্রিয়া টানেল ইন্টারফেস তৈরি বা কনফিগার করতে পারে না, আর যে প্রক্রিয়ার স্যান্ডবক্স /dev/net/tun লুকায় সে এটি শুরুতেই খুলতে পারে না। ক্যাপাবিলিটি যোগ করলে দ্বিতীয়টি ঠিক হবে না।
কিছু সম্পাদনা করার আগে ডিভাইসটি সার্ভিসের নেমস্পেসের ভিতরে আছে কি না দেখুন। PrivateDevices=yes একটি সাধারণ হার্ডেনিং লাইন যা tun নোড সম্পূর্ণ সরিয়ে দেয়, আর কঠোর ProtectSystem কনফিগারেশন পথকে এমনভাবে শুধু-পঠনযোগ্য করে যা অনুমতি ত্রুটির মতো পড়া যায়। দুটিই টানেলের কথা বলা লগ লাইন তৈরি করে, তাই দোষ ক্যাপাবিলিটির উপর পড়ে। আগে নিশ্চিত করুন নোডটি আছে ও খোলা যায়, তারপর এগিয়ে যান।
আপনি কোন ক্যাপাবিলিটি সেট দেখছেন তা জানুন
Linux অনুমোদিত, কার্যকর, উত্তরাধিকারযোগ্য, সীমাবদ্ধ ও অ্যাম্বিয়েন্ট সেট রাখে, এবং অ্যাম্বিয়েন্ট সেটই অ-রুট ব্যবহারকারীর exec-এর পর টিকে থাকে। বাইনারির ফাইল ক্যাপাবিলিটি exec-এ অনুমোদিত ও কার্যকর অধিকার হস্তান্তর করতে পারে, কিন্তু কেবল তখনই যখন শৃঙ্খলে কিছুই সেই হস্তান্তর আটকায় না।
এখানেই sudo মানুষকে বিভ্রান্ত করে। sudo -u দিয়ে চালানো কমান্ড নতুন সুবিধা হস্তান্তর শুরু করে এবং অ্যাম্বিয়েন্ট সেট আর থাকে না, তাই root হিসেবে সফল একই যাচাই সেখানে ব্যর্থ হয়। সার্ভিস ম্যানেজার আরেকটি হস্তান্তর, এবং ইউনিট না বললে এটি অ্যাম্বিয়েন্ট কিছুই দেয় না।
ক্যাপাবিলিটি ইউনিটে দিন, আলাদা মোড়কে নয়
একটি ডিভাইস তৈরি ও রুট ইনস্টল করতে হওয়া টানেলের জন্য ন্যূনতম সার্ভিস অংশ এমন দেখায়।
[Unit]
Description=OpenVPN client, office profile
After=network-online.target
[Service]
Type=notify
User=openvpn
Group=openvpn
NoNewPrivileges=yes
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN
ExecStart=/usr/sbin/openvpn --config /etc/openvpn/office.confAmbientCapabilities প্রক্রিয়া শুরু হওয়ার আগেই অধিকারটি অ্যাম্বিয়েন্ট সেটে রাখে, আর CapabilityBoundingSet প্রক্রিয়াকে সেই তালিকার বাইরে কিছু রাখতে দেয় না। NoNewPrivileges=yes setuid বা ফাইল ক্যাপাবিলিটির মাধ্যমে সুবিধা অর্জন আটকায়, অথচ ইউনিট যে ক্যাপাবিলিটি স্পষ্টভাবে দেয় তা তখনও প্রযোজ্য। CAP_NET_BIND_SERVICE কেবল তখনই যোগ করুন যখন সার্ভিসকে নিম্ন পোর্ট বাঁধতে হয়, আর কেবল একটি ফোরাম থ্রেড তাই করেছে বলে কখনও CAP_SYS_ADMIN যোগ করবেন না।
ইউনিট যদি বাইনারিকে sudo-এ মুড়ে রাখে, মোড়কটি সরান। systemd ইতিমধ্যে User= প্রয়োগ করে, আর সেই অতিরিক্ত স্তরই অ্যাম্বিয়েন্ট সেট খালি থাকার সবচেয়ে সম্ভাব্য কারণ।
ইউনিট ফাইলে নয়, চালু প্রক্রিয়ার বিপরীতে যাচাই করুন
ম্যানেজার আসলে কী প্রয়োগ করেছে তা পড়ুন, তারপর যে প্রক্রিয়া এটি তৈরি করেছে তা পড়ুন।
unit=openvpn-client@office
systemctl show -p User -p AmbientCapabilities "$unit"
systemctl show -p MainPID --value "$unit" | xargs -r getpcaps
grep -E '^Cap(Eff|Amb)' /proc/$(systemctl show -p MainPID --value "$unit")/statusইউনিট যদি ক্যাপাবিলিটি তালিকাভুক্ত করে আর CapEff-এ তা না থাকে, তবে কোনো drop-in সেটিংটিকে অগ্রাহ্য করছে বা কোনো ExecStartPre ধাপ পরিবেশ বদলাচ্ছে। মূল ফাইলই কর্তৃত্বপূর্ণ ধরে নেওয়ার আগে drop-in ডিরেক্টরিগুলোতে ইউনিটের নাম খুঁজুন, কারণ পরের ফাইল নিঃশব্দে জিতে যায়। ইউনিট ও প্রক্রিয়া দুটিই ক্যাপাবিলিটি দেখালেও টানেল ব্যর্থ হলে সীমাবদ্ধ সেট বাড়ানোর বদলে ডিভাইস ও পাথ যাচাইয়ে ফিরে যান। এটি বাড়ালে আসল কারণ ঢাকা পড়ে এবং সার্ভিস আগের চেয়ে বেশি সুবিধাভোগী হয়ে থাকে।
শুরু হওয়ার পরে সুবিধা ছাড়তে পছন্দ করুন
OpenVPN নিজের user ও group অপশন দিয়ে সুবিধাসহ শুরু করে পরে অসুবিধাহীন অ্যাকাউন্টে নামতে পারে, আর persist-key ও persist-tun টানেলটিকে পরে ব্যবহারযোগ্য রাখে। এই বিন্যাস প্রক্রিয়াটি অধিকার ধরে রাখার সময়সীমা সংকুচিত করে, এবং স্থায়ী ক্যাপাবিলিটিসহ পুরো ডেমনকে অসুবিধাহীনভাবে শুরু করার চেয়ে এটি প্রায়ই বেশি উপযুক্ত।
যে মডেলই বেছে নিন, ইউনিটটি পুনরায় চালু করুন এবং রিবুটের পরে যাচাইগুলো পুনরাবৃত্তি করুন, কারণ ইন্টারঅ্যাকটিভ root শেল থেকে কাজ করা অথচ বুটে ব্যর্থ হওয়া সার্ভিস সাধারণত ক্যাপাবিলিটি, ডিভাইস বা ফাইল-অনুমতির পার্থক্য। ইউনিট সেটিংসগুলো প্রক্রিয়ার ক্যাপাবিলিটি আউটপুটের পাশে লিখে রাখুন, যাতে পরবর্তী পর্যালোচক দেখতে পারেন কোনো প্যাকেজ আপডেট বা drop-in সীমাটি সরিয়েছে কি না।