ProtectHome مقابل بذرة TOTP: لماذا يفشل تسجيل الدخول إلى VPN
لا يفيد رمز صحيح وحدة PAM لا تستطيع فتح البذرة. اختر بين ملف drop-in ومسار حالة قابل للكتابة، ثم افحص الوحدة.
يعرض تطبيق المصادقة رمزًا جديدًا من ستة أرقام، فترفضه 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الخيار أ: نقل السر خارج الدليل المنزلي
عندما تخفي الخدمة /home وتفضّل الاحتفاظ بتلك الحماية، خزّن السر في مكان تستطيع رؤيته. تقبل الوحدة مسار secret= وحساب user= ينفذ عمليات الملفات، ما يسمح لمخزن مركزي بخدمة هويات كثيرة.
هذا هو الخيار المرتب، وهو الذي يحتاج إلى أكبر قدر من العناية، لأن المخزن المشترك يجعل دليلًا واحدًا الحد الأمني لكل حساب.
auth required pam_google_authenticator.so secret=/var/lib/vpn-otp/${USER}/.google_authenticator user=vpn-otpتحقق من ثلاثة أمور قبل الوثوق به: أن الحساب موجود، وأن عامل الوحدة يستطيع التحول إليه، وأن الملفات مملوكة له بأوضاع تقييدية. لا تستخدم ~ أو مسارًا بمتغير الدليل المنزلي مع user=، ولا تعطّل فحوص الملكية في الوحدة لجعل مسار يعمل. أبقِ مرحلة كلمة المرور وبقية الحزمة سليمة.
الخيار ب: ترك الملف وفتح مسار
إذا كان على السر البقاء في دليل المستخدم المنزلي، فتحتاج الوحدة إلى عرض يتضمن ذلك الدليل وحده من دون كشف كل دليل منزلي على المضيف. يمكن لملف drop-in إضافة ربط محصور النطاق تحت دليل منزلي معزول.
يحافظ هذا على الملكية لكل مستخدم كنموذج، على حساب تغيير في الوحدة يجب مراجعته كلما تغيّر الصندوق الرملي.
هناك حدّان يسهل إغفالهما. المسار للقراءة فقط المضاف تحت دليل يخفيه الصندوق الرملي لا يكشفه، لأن الدليل الأب ببساطة غير موجود. ويجب أن يكون الربط قابلًا للكتابة إذا كان على الوحدة تحديث الحالة، وهذا ما يستدعي الخيار التالي. اكتب ملف drop-in كملف منفصل بدلًا من تحرير الوحدة المعبأة تحت /usr/lib، حتى لا تلغيه ترقية الحزمة بصمت.
الخيار ج: الاحتفاظ بالصندوق الرملي وإصلاح كتابات الحالة
قراءة السر نصف المصادقة فقط. قد تعيد الوحدة كتابة معلومات انحراف الوقت أو حماية إعادة التشغيل أو عدّاد، والملف الذي ينجح في فحص القراءة قد يفشل في الكتابة.
يبدو ذلك الفشل كرمز سيئ في المحاولة التالية لا في هذه المحاولة، ولهذا يُخطئ فهمه على أنه انحراف ساعة.
امنحه دليلًا قابلًا للكتابة خاصًا به ووجّه مسار السر إليه، بدلًا من جعل الدليل المنزلي كله قابلًا للكتابة. تحقق من مالك الدليل، ومن المساحة الحرة في نظام الملفات، ومن كون الوحدة تقيّد الكتابة في مكان آخر. ثم اختبر تسجيلَي دخول متتاليين، لأن الثاني يثبت مسار الكتابة والأول يثبت القراءة فقط.
تحقق كالخدمة، لا كأنك نفسك
كل فحص مهم يجب أن يجري داخل صندوق الوحدة الرملي بهوية الوحدة.
أمر ينجح بصلاحية الجذر يخبرك بأن الملف موجود ولا شيء غير ذلك. أما تسجيل الدخول عبر الخدمة الفعلية فيخبرك هل تستطيع الوحدة قراءة السر واستخدامه وإعادة كتابة ما تحتاجه.
أخيرًا، أبقِ الشرط سليمًا. إضافة خيار كلمة مرور فارغة، أو قبول إخفاقات القراءة فقط، أو إزالة الصندوق الرملي، كلها ستُخفي العَرَض بتغيير السياسة. المستخدم المطالب بتقديم رمز يجب أن يُرفض أيضًا عندما يكون السر غير قابل للوصول.