প্রমাণক একটি নতুন ছয়-সংখ্যার কোড দেখায়, VPN তা প্রত্যাখ্যান করে, আর একই কোড আপনার নিজের শেল থেকে পরীক্ষা করলে নিখুঁতভাবে যাচাই হয়। এই ফাঁকই পুরো গল্প। যে PAM মডিউল নথিভুক্তির গোপন তথ্য খুলতে পারে না, সে ভুল কোডের মতোই দেখতে এক ব্যর্থতা ফেরত দেয়, আর হোম ডিরেক্টরি লুকিয়ে রাখা পরিষেবার পরিবেশ এর সাধারণ কারণ। কোনো অনুমতি শিথিল করার আগে নির্ধারণ করুন আপনি তিনটি পরিস্থিতির কোনটিতে আছেন।

তিনটি ব্যর্থতার মধ্যে কোনটি?

প্রথমটি এমন গোপন তথ্য যা মডিউল একেবারেই পড়তে পারে না। দ্বিতীয়টি এমন গোপন তথ্য যা সে পড়তে পারে কিন্তু হালনাগাদ করতে পারে না। তৃতীয়টি সত্যিই ভুল একটি কোড, সাধারণত ঘড়ির বিচ্যুতি বা পুনরায় ব্যবহৃত মানের কারণে।

একটি ব্যর্থ প্রচেষ্টার জন্য পরিষেবা জার্নাল ও সিস্টেম প্রমাণীকরণ লগ পড়ে এদের আলাদা করুন, তারপর নিশ্চিত করুন প্লাগইন কোন PAM পরিষেবা লোড করে এবং সেই পরিষেবা কোন মডিউল লাইন ব্যবহার করে। সাধারণ প্রমাণীকরণ ব্যর্থতার বার্তা এদের আলাদা করে না, সফল হাতে-কলমে পরীক্ষাও না, কারণ আপনার শেল পরিষেবার পরিবেশ নয়।

কেবল পরিষেবাই ব্যর্থ হলে ইউনিটের ফাইলসিস্টেম দৃশ্যই সাধারণ অপরাধী।

systemctl show -p ProtectHome -p ProtectSystem -p ReadWritePaths [email protected]
ls -l /var/lib/vpn-otp/*/.google_authenticator 2>/dev/null | head -n 20

বিকল্প A: গোপন তথ্য হোমের বাইরে সরান

যখন পরিষেবা /home লুকায় আর আপনি সেই সুরক্ষা রাখতে চান, তখন গোপন তথ্য এমন জায়গায় রাখুন যেখানে সে তা দেখতে পারে। মডিউল secret= পথ এবং ফাইল পরিচালনা করা user= অ্যাকাউন্ট গ্রহণ করে, যা একটি কেন্দ্রীয় ভাণ্ডারকে অনেক পরিচয় পরিবেশন করতে দেয়।

এটি পরিচ্ছন্ন বিকল্প, আর এটিই সবচেয়ে বেশি যত্ন চায়, কারণ ভাগ করা ভাণ্ডার একটি ডিরেক্টরিকেই প্রতিটি অ্যাকাউন্টের নিরাপত্তা সীমা বানায়।

auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otp

বিশ্বাস করার আগে তিনটি জিনিস পরীক্ষা করুন: অ্যাকাউন্টটি বিদ্যমান, মডিউল কর্মী এতে রূপান্তরিত হতে পারে, এবং ফাইলগুলো কঠোর মোডে তার মালিকানাধীন। user=-এর সঙ্গে ~ বা হোম-ভেরিয়েবল পথ ব্যবহার করবেন না, এবং পথ কাজ করানোর জন্য মডিউলের মালিকানা পরীক্ষা বন্ধ করবেন না। পাসওয়ার্ড ধাপ ও বাকি স্ট্যাক অক্ষত রাখুন।

বিকল্প B: ফাইল রেখে একটি পথ খুলুন

গোপন তথ্য ব্যবহারকারীর হোমে থাকতেই হলে, ইউনিটের এমন দৃশ্য দরকার যা হোস্টের প্রতিটি হোম না খুলে ওই একটি ডিরেক্টরি অন্তর্ভুক্ত করে। একটি drop-in স্যান্ডবক্স করা হোমের নিচে সংকীর্ণ পরিসরের বাইন্ড মাউন্ট যোগ করতে পারে।

এটি ব্যবহারকারীপ্রতি মালিকানাকে মডেল হিসেবে রাখে, কিন্তু স্যান্ডবক্স বদলালে ইউনিট পরিবর্তন পর্যালোচনা করতে হয়।

দুটি সীমা সহজে বাদ পড়ে। স্যান্ডবক্স যে ডিরেক্টরি লুকায় তার নিচে যোগ করা কেবল-পাঠযোগ্য পথ তা উন্মুক্ত করে না, কারণ মূল ডিরেক্টরিটি সেখানে নেই। আর মডিউলকে অবস্থা হালনাগাদ করতে হলে মাউন্টটি লিখনযোগ্য হতে হবে, যা পরের বিকল্পটি চালু করে। /usr/lib-এর নিচের প্যাকেজযুক্ত ইউনিট সম্পাদনা না করে drop-in আলাদা ফাইল হিসেবে লিখুন, যাতে প্যাকেজ আপগ্রেড তা নীরবে বাতিল না করে।

বিকল্প C: স্যান্ডবক্স রাখুন এবং অবস্থা লেখা ঠিক করুন

গোপন তথ্য পড়া প্রমাণীকরণের অর্ধেক মাত্র। মডিউল সময়-বিচ্যুতির তথ্য, পুনরাবৃত্তি সুরক্ষা বা একটি কাউন্টার পুনর্লিখন করতে পারে, আর পাঠ পরীক্ষায় উত্তীর্ণ ফাইল লেখায় ব্যর্থ হতে পারে।

সেই ব্যর্থতা এই প্রচেষ্টায় নয়, পরের প্রচেষ্টায় খারাপ কোডের মতো দেখায়, তাই একে ঘড়ির বিচ্যুতি ভাবা হয়।

পুরো হোম লিখনযোগ্য না করে তাকে নিজস্ব লিখনযোগ্য ডিরেক্টরি দিন এবং গোপন তথ্যের পথ সেখানে নির্দেশ করুন। ডিরেক্টরির মালিক, ফাইলসিস্টেমের খালি জায়গা এবং ইউনিট অন্যত্র লেখা সীমিত করে কি না নিশ্চিত করুন। তারপর পরপর দুটি লগইন পরীক্ষা করুন, কারণ দ্বিতীয়টি লেখার পথ প্রমাণ করে আর প্রথমটি কেবল পড়া।

নিজের বদলে পরিষেবা হিসেবে যাচাই করুন

প্রতিটি গুরুত্বপূর্ণ পরীক্ষা ইউনিটের স্যান্ডবক্সে ইউনিটের পরিচয়ে চলতে হবে।

root হিসেবে সফল কমান্ড শুধু বলে ফাইলটি আছে, আর কিছু নয়। প্রকৃত পরিষেবার মধ্য দিয়ে লগইন বলে মডিউল গোপন তথ্য পড়তে, ব্যবহার করতে ও প্রয়োজনীয় কিছু ফিরে লিখতে পারে কি না।

শেষে, প্রয়োজনীয়তাটি অক্ষত রাখুন। শূন্য-পাসওয়ার্ড বিকল্প যোগ করা, কেবল-পাঠ ব্যর্থতা মেনে নেওয়া বা স্যান্ডবক্স সরানো—সবই নীতি বদলে উপসর্গটি মুছে ফেলত। যাকে কোড দিতে হয়, গোপন তথ্য অপ্রাপ্য হলে তাকেও প্রত্যাখ্যান করতে হবে।

সম্পর্কিত নিবন্ধ