لماذا يفشل رمز صالح لمرة واحدة عند تسجيل الدخول إلى VPN
الرمز المرفوض مشكلة في ترتيب المطالبة أو في التسجيل أو في التوقيت، وليس رمزاً خاطئاً. تحقّق من هذه الأمور بالترتيب قبل أن تعيد تسجيل أي شيء.
تفتح عميل VPN، وتكتب كلمة المرور، فتعود الأرقام الستة من تطبيق المصادقة غير صالحة — مرتين، ثم مرة ثالثة. لم يتغير شيء في الحساب منذ الأمس، لذا تكون الغريزة هي حذف الإدخال من تطبيق المصادقة ومسحه ضوئياً من جديد — وهو عادةً الإصلاح الخاطئ. الرمز لمرة واحدة ليس كلمة مرور ثانية: على البوابة أن تطلبه في خطوة محددة، من إدخال مسجَّل محدد، داخل نافذة محددة، ومعظم حالات الرفض تحدث قبل مقارنة الأرقام. حدِّد في أي خطوة أنت قبل أن تلمس التسجيل.
ترتيب المطالبات يخبرك بأي مسار أنت
ثلاث صور تغطي تقريباً كل عملية دخول إلى VPN تتضمن رمزاً. في الصورة ذات الخطوتين يرسل العميل كلمة المرور، ويصدر الخادم تحدياً، ثم يطلب العميل مرة أخرى. في الصورة المدمجة تريد البوابة كلمة المرور والرمز في إرسال واحد — أحياناً متصلين، وأحياناً بعد فاصل لا يوثّقه إلا المشغّل. في صورة المتصفح لا يملك العميل أي حقل إطلاقاً: يذهب الرمز إلى صفحة ويب، أو تحلّ موافقة منبثقة محلّه، فينتظر عميل سطح المكتب النتيجة.
الخطأ في الصورة يبدو كرمز سيئ. الصق رمزاً جديداً في حقل مخصص لكلمة المرور فقط، فيقرأه الخادم جزءاً من كلمة المرور. على جانب العميل، يجعل OpenVPN 2.4 وما بعده الفرق مرئياً: الخادم الذي يرد بـ AUTH_FAILED,CRV1: يتوقع استجابة تحدٍّ، لذا يحتاج الملف الشخصي إلى static-challenge أو ملف كلمات مرور بصيغة SCRV1:. أما الملف الشخصي الأقدم الذي يحمل auth-user-pass فقط، فإنه يتحقق من كلمة المرور ثم يتوقف، وهو ما يبدو في السجل كفشل OTP مع أنه لم يُرسل أي رمز.
يستحق WireGuard أن يُذكر كاستثناء: فهو يصادق على أزواج المفاتيح لا على الأشخاص، لذا لا يوجد حقل للرمز. وإن أعلن مزوّد عن رمز ما، فشيء خارج النفق هو الذي يقبله.
ما يفعله الخادم بالأرقام الستة
تتبع الرموز الزمنية RFC 6238، الذي يلفّ البناء الأقدم القائم على العدّاد من RFC 4226: HMAC فوق عامل متحرك، يُقتطع إلى ستة أرقام افتراضياً. في TOTP يكون العامل المتحرك هو وقت Unix الحالي مقسوماً على خطوة، 30 ثانية ما لم يغيّرها المشغّل. لا يقارن المتحقِّق أرقامك بقيمة مخزّنة أبداً؛ بل يعيد حساب الرمز المتوقع من البذرة المشتركة، ويقبل عادةً الخطوات المجاورة أيضاً، لذا لا تفشل عملية الدخول بسبب رحلة ذهاب وإياب بطيئة.
ثمة نتيجتان يُغفلان. المنطقة الزمنية للهاتف لا صلة لها، لأن البذرة لا ترى ساعة محلية أبداً — الفارق عن UTC الحقيقي وحده هو المهم، وجهاز يعمل بفارق دقيقتين للأمام يفشل في كل رمز بينما يعرض عداً تنازلياً سليماً. والرمز أحادي الاستخدام بالتصميم: يتذكر المتحقِّق آخر قيمة عدّاد قبلها لتلك البذرة، لذا تُرفض الأرقام نفسها إن أُرسلت مرة أخرى حتى داخل النافذة نفسها. والعميل الذي يعيد المحاولة بعد انتهاء المهلة يمكن أن يحرق الرمز الذي أرسله للتو.
تغيّر الرموز القائمة على العدّاد عدّادها مع كل ضغطة، لذا تخرج عن التزامن بعد أن تُولَّد رموز ولا تُرسل قط؛ والإصلاح المعتاد هو نافذة إعادة تزامن تقبل بضعة قيم إلى الأمام. وإن سجّل المشغّل HOTP بينما يعرض تطبيقك TOTP، فكل قيمة خاطئة بطريقة تبدو مشكلة ساعة. ويسمّي URI التزويد الكامن خلف رمز QR النوع والأرقام والمدة والتجزئة.
إخفاقات تبدو كرمز خاطئ
الإدخال المسجَّل هو السبب الأكثر شيوعاً. تسمّي تطبيقات المصادقة الإدخالات بالمُصدر والحساب، لذا يمكن لمن يحمل هويتين على VPN نفسه أن ينتهي بإدخالين يختلف اسماهما بحرف واحد. الرمز صالح للبذرة التي وّلّدته ولا شيء غيرها. قارن الاسم على الهاتف باسم المستخدم الذي يسجّله الخادم، لا بما تتذكّر أنك كتبته.
ثانياً مجموعة معاملات غير متطابقة. البذرة المسجَّلة بثمانية أرقام أو بمدة 60 ثانية أو بـ SHA-256 تنتج رموزاً يرفضها متحقِّق يتوقع ستة أرقام و30 ثانية و SHA-1، ولا يمكن تمييز ذلك عند العميل عن رمز خاطئ. يظهر هذا بعد عمليات الترحيل حيث أُعيدت إضافة الإدخال من صورة لرمز QR، أو حيث أُعيد بناء سجل الرمز بالقيم الافتراضية.
ثالثاً الأمر لا يتعلق بالرمز. تعيد البوابات عادةً فشل مصادقة عاماً واحداً لكلمة مرور خاطئة ورمز منتهٍ وحساب معطّل، عن قصد، كي لا يستطيع أحد سبر أي عامل فشل. اقرأ سجل البوابة أو RADIUS بدلاً من لافتة العميل: التحدي الذي لم يُصدر قط، والرفض الوصولي بلا سمة OTP، ورفض السياسة كلها تظهر بالشكل نفسه على الشاشة وتؤدي إلى خطوات تالية مختلفة.
تسلسل قصير يضيّق الاحتمالات
ابدأ بأرخص فحص وتوقّف عند أول خطوة لا تصح.
- انتظر رمزاً جديداً، أرسله مرة واحدة، ولاحظ هل يظهر التحدي قبل قبول كلمة المرور أم بعده.
- طابق الاسم في تطبيق المصادقة مع اسم المستخدم الذي يخزّنه الخادم.
- تأكد من أن الملف الشخصي قادر على الإجابة عن تحدٍّ أصلاً، كما في حالة
CRV1أعلاه. - قارن ساعة الجهاز بمصدر وقت موثوق؛ فارق يتجاوز بضع عشرات من الثواني يكسر TOTP بذاته.
- اسأل المشغّل هل الرمز TOTP أم HOTP، وأي أرقام ومدة وتجزئة سُجّلت.
قاعدتان تمنعان هذا من جعل الأمور أسوأ. لا تعاود المحاولة مرات كثيرة: كثرة من البوابات تحسب الإخفاقات لكل حساب فإما تقفله أو تبدأ في تأخير الردود، فيحوّل انفجار المحاولات خللاً صغيراً في الإعداد إلى تذكرة دعم. ولا تُعِد تسجيل الرمز كتشخيص، لأن ذلك يبطل البذرة القديمة؛ وإن كان العطل الحقيقي تحدياً لم يرسله العميل قط، فلديك الآن تغييران لتفسيرهما بدلاً من واحد.
أبعِد البذرة ورموز الاسترداد عن الحلقة
الأرقام الستة والسرّ الكامن خلفها ليسا متبادلين. رمز QR للتزويد أو بذرة Base32 تولّد كل رمز مستقبلي للحساب، لذا تنتمي إلى الفئة نفسها التي تنتمي إليها كلمة المرور: لا في لقطة شاشة، ولا في تعليق على تذكرة، ولا في محادثة مع شخص بادر بالتواصل معك. رموز الاسترداد آلية منفصلة — أحادية الاستخدام، وتتخطى غالباً مطالبة الرمز كلياً، وإنفاق واحد منها لاختبار الحساب يزيل بديلاً قد تحتاجه لاحقاً.
ولا يجعل الرمز صفحة دخول جديرة بالثقة: مطالبة OTP على نطاق شبيه تجمع رمزاً صالحاً وتعيد تشغيله داخل النافذة، والشهادة هي ما يخبرك أين تكتب.
إن انتهى التسلسل عند ملف شخصي لا يستطيع الإجابة عن تحدٍّ، فأصلح الملف وأعد الاختبار برمز جديد واحد. وإن انتهى عند معاملات تسجيل غير متطابقة، فاطلب من المشغّل قراءة سجل الرمز قبل أن يمسح أحد أي شيء. وإن انتهى عند قفل، فانتظر انتهاءه بدلاً من تبديل العملاء — حالة الحساب هي العائق، لا التطبيق.