PAM প্রমাণীকরণ হাতে চালালে কাজ করে, কিন্তু OpenVPN সেবা হিসেবে ব্যর্থ হয়
root শেল থেকে কাজ করা এবং systemd-এর অধীনে ব্যর্থ হওয়া একটি PAM লগইন পাসওয়ার্ড নয়, হেল্পারকে নির্দেশ করে। সুবিধা, ফাইল অ্যাক্সেস ও SELinux আলাদা করুন।
PAM-এর মাধ্যমে প্রমাণীকরণ সফল হতে পারে যখন আপনি ক্লায়েন্টটি হাতে চালান, আর systemd একই প্রোফাইল চালু করলে AUTH_FAILED নিয়ে ব্যর্থ হয়। ওই চালানোর মধ্যে পাসওয়ার্ড বদলায় না; বদলায় PAM-কে প্রশ্ন করা প্রক্রিয়াটির চারপাশের সীমাবদ্ধতার সেট। PAM একটি হেল্পারের মাধ্যমে উত্তর দেয়, যার নিজের ক্রেডেনশিয়াল বদলানোর ক্ষমতাই একটি কঠোরভাবে সুরক্ষিত unit সরিয়ে দেয়। ক্ষমতার তালিকায় হাত দেওয়ার আগে সেই হেল্পার ও তার প্রয়োজনীয় সীমান্ত খুঁজে বের করুন।
unix_chkpwd হলো সেই বাইনারি যা PAM-এর প্রশ্নের উত্তর দেয়
স্থানীয় পাসওয়ার্ড প্রমাণীকরণে, pam_unix খুব কমই নিজে হ্যাশ ফাইল পড়ে। এটি unix_chkpwd চালায়, যা ডিস্ট্রিবিউশনগুলো setuid root বা setgid shadow হিসেবে ইনস্টল করে, যাতে এমন একটি প্রক্রিয়ার পক্ষে একটি পাসওয়ার্ড যাচাই করা যায় যার /etc/shadow পড়ার কোনো কাজ নেই। সেই পরিচয় অর্জনের ক্ষমতা সরিয়ে দিলে হেল্পার যাচাই সম্পূর্ণ করতে পারে না, তাই মডিউলটি সাধারণ প্রমাণীকরণ ব্যর্থতা ফেরত দেয়।
এরপর ব্যর্থতাটি ক্লায়েন্টের দেখা প্রতিটি লগে ক্রেডেনশিয়াল সমস্যার মতো দেখায়। এটাই ফাঁদ: ক্লায়েন্ট জানায় PAM তাকে কী বলেছে, আর PAM জানায় কেবল যে স্ট্যাক না বলেছে। root হিসেবে হাতে হেল্পার চালানোও কিছু প্রমাণ করে না, কারণ তা একটি সুবিধার পথ পরীক্ষা করে যা সেবাটি কখনো ব্যবহার করে না। systemd আসলে যে unit লোড করেছে তা পড়ুন, তারপর যে চেষ্টা এটি করেছে তার জন্য সিস্টেম লগ পড়ুন। এই দুই দৃষ্টিভঙ্গি স্যান্ডবক্স সমস্যাকে ভুল পাসওয়ার্ড সমস্যা থেকে আলাদা করে।
পাসওয়ার্ড লগ পড়ার আগে unit পড়ুন
একটি প্যাকেজকৃত unit-এ এমন drop-in থাকতে পারে যা আপনি লেখেননি, আর কার্যকর কনফিগারেশন হলো মিলিত ফলাফল। systemd যেভাবে দেখে সেভাবে unitটি প্রিন্ট করুন, সঙ্গে সেই স্যান্ডবক্স সেটিংস যা নির্ধারণ করে হেল্পার নিজেকে উন্নীত করতে পারে কি না। এই পর্যায়ে শুধু-পড়ার পরিদর্শনই যথেষ্ট।
systemctl cat [email protected]
systemctl show [email protected] -p User -p Group -p CapabilityBoundingSet -p AmbientCapabilities -p NoNewPrivileges
journalctl -u [email protected] -b
প্রথম কমান্ডটি দেখায় unit ও তার drop-in কোথা থেকে আসে, যা গুরুত্বপূর্ণ কারণ মাস আগে যোগ করা একটি override কেন আছে সেই স্মৃতির চেয়ে বেশি দিন বাঁচে। দ্বিতীয়টি সেই স্যান্ডবক্স মানগুলো প্রিন্ট করে যার উপর পরের দুই বিভাগ নির্ভর করে।
আপনি যা দেখছেন তা একই ডিস্ট্রিবিউশন ও সংস্করণের একটি সক্রিয় হোস্টের সঙ্গে তুলনা করুন। User, CapabilityBoundingSet বা NoNewPrivileges-এ পার্থক্য একটি সুনির্দিষ্ট সূত্র; গদ্য মন্তব্যে পার্থক্য নয়। কিছু বদলানোর আগে মানগুলো লিখে রাখুন, কারণ চলমান লক্ষ্যের সঙ্গে পরবর্তী তুলনা কিছু প্রমাণ করে না। সেবাটি যদি খালি bounding সেটসহ অ-সুবিধাভোগী অ্যাকাউন্টে চলে, তবে হেল্পারের কাজ করার মতো প্রায় কিছুই থাকে না।
ক্রেডেনশিয়াল রূপান্তর, ফাইল অ্যাক্সেস ও নীতি তিনটি সীমান্ত
exec-এর সময় কী ঘটে তা দিয়ে শুরু করুন। একটি setuid বাইনারি বা ফাইল capabilities বহনকারী ফাইল ক্রেডেনশিয়াল রূপান্তর ঘটায়, তাই ফলস্বরূপ পরিচয়টি আহ্বানকারীর ধারাবাহিকতা নয়। bounding সেট সীমিত করে এমন বাইনারি কী অর্জন করতে পারে, আর NoNewPrivileges setuid, setgid ও ফাইল-capability অর্জন সম্পূর্ণভাবে বন্ধ করে। এই তিনটির যেকোনো একটি হেল্পারকে থামাতে পারে, অথচ সেবার বাকি সব কার্যকারিতা অক্ষত থাকে।
এরপর বিস্তৃত বিবেচনামূলক বাইপাসকে সংকীর্ণ পঠন-অ্যাক্সেস থেকে আলাদা করুন। CAP_DAC_OVERRIDE প্রায় সব জায়গায় বিবেচনামূলক যাচাই এড়িয়ে যায়, আর CAP_DAC_READ_SEARCH নিজস্ব অতিরিক্ত ক্ষমতাসহ পঠন ও ডিরেক্টরি ট্রাভার্সাল কভার করে। এগুলো ভিন্ন প্রভাব-ব্যাসার্ধের ভিন্ন সরঞ্জাম, এবং কোনোটিই ‘PAM-কে shadow ফাইল পড়তে দাও’ কথাটির বানান নয়।
শেষে জিজ্ঞাসা করুন, বাধ্যতামূলক নীতিটি কাজটির অনুমতি দেয় কি না। Linux capability SELinux-কে অগ্রাহ্য করে না, আর একটি ধারণ করা type enforcement নিয়ম সম্পর্কে কিছুই প্রমাণ করে না। ফাইল-অ্যাক্সেস প্রত্যাখ্যান ও capability প্রত্যাখ্যানকে ভিন্ন প্রমাণ হিসেবে ধরুন, কারণ তারা ভিন্ন সমাধান ও প্রায়ই ভিন্ন মালিকের নাম বলে। রেকর্ডের প্রতিটি ক্ষেত্র পড়ুন, কেবল denied শব্দটি নয়। কোন এক্সিকিউটেবল কাজটি করেছে, কোন ডোমেইনে চলেছে, কী ধরনের লক্ষ্যে হাত দিয়েছে, কোন শ্রেণির অবজেক্ট জড়িত ছিল এবং নীতি কোন অনুমতি প্রত্যাখ্যান করেছে—প্রতিটি ভিন্নভাবে উত্তরটিকে সংকুচিত করে।
অডিট লগ থেকে প্রত্যাখ্যানটি বের করুন
প্রয়োগকারী হোস্টে অডিট ট্রেইলই একমাত্র জায়গা যা প্রত্যাখ্যান রেকর্ড করে। সাম্প্রতিক ঘটনাগুলো জিজ্ঞাসা করুন এবং ব্যর্থ লগইনের টাইমস্ট্যাম্পের সাপেক্ষে পড়ুন, তদন্ত শুরু করার সময়ের সাপেক্ষে নয়।
ausearch -m AVC,USER_AVC -ts recent
খালি ফলাফল নির্দোষতার প্রমাণ নয়। এর অর্থ হয় অডিটিং সংগ্রহ করছে না, নয়তো আপনার উইন্ডো চেষ্টাটি মিস করেছে, এবং নীতিকে বাদ দেওয়ার আগে দুই সম্ভাবনাই বাদ দিতে হবে।
Red Hat-এর SELinux সমস্যা সমাধানের নির্দেশনা লেবেল ও কনফিগারেশন যাচাইকে allow নিয়ম তৈরির আগে রাখে, যা এই সমস্যার জন্যও সঠিক ক্রম। ভুল লেবেলযুক্ত হেল্পার বাইনারি ও নীতির ফাঁক একই রকম প্রত্যাখ্যান তৈরি করে কিন্তু ভিন্ন মেরামত দরকার। লেবেলিং ভুলের জন্য allow নিয়ম তৈরি করা ত্রুটিটি লুকায় ও পরের প্যাকেজ আপডেটকে তা আবার আনতে দেয়। কোনো নীতি লেখার আগে ইনস্টল করা হেল্পারের লেবেল নিশ্চিত করুন।
একটি গৃহীত ও একটি প্রত্যাখ্যাত লগইন দিয়ে পরিবর্তনটি প্রমাণ করুন
আপনি যে সীমান্তটি প্রদর্শন করেছেন কেবল সেটিই বদলান, তারপর দুই ফলাফলই পরীক্ষা করুন। যে অ্যাকাউন্টের প্রমাণীকরণ হওয়া উচিত তা সফল হতে হবে, আর ভুল পাসওয়ার্ডের অ্যাকাউন্ট এখনো ব্যর্থ হতে হবে। যে পরিবর্তন প্রতিটি চেষ্টাকে সফল করে তোলে তা প্রমাণীকরণ মেরামত নয়, সরিয়ে দিয়েছে।
একটি প্রকৃত সংযোগের চেষ্টা করুন এবং সঙ্গে সঙ্গে জার্নাল পড়ুন। যে লাইনটি সমাধান প্রমাণ করে তা হলো ওই চেষ্টার pam_unix(openvpn:auth) এন্ট্রি: সেখানে প্রমাণীকরণ সফল লেখা থাকা উচিত, এবং কোনো AVC রেকর্ড একই সেকেন্ডে থাকা উচিত নয়।
journalctl -u [email protected] -n 30 --no-pager
ss -tnp | grep openvpn
সক্রিয় টানেলের পুনঃসংযোগও দরকার, কারণ স্যান্ডবক্স পরিবর্তন প্রথমটির চেয়ে দ্বিতীয় সংযোগটিই বেশি ভাঙে। পুনঃসংযোগের পর প্রতিষ্ঠিত সকেটটি পরীক্ষা করুন এবং নিশ্চিত করুন একই unit এখনো এটি সেবা দিচ্ছে।