فشل تجديد شهادات Let's Encrypt (فجأة)

منذ فترة – ليس من الواضح كم من الوقت ولكن على الأقل عدة أشهر – بدأت تجديدات Let’s Encrypt تفشل في منتدى Discourse الخاص بي، بعد أن كانت تعمل بشكل جيد لسنوات. عندما لاحظت هذا لأول مرة قبل أيام قليلة، انتهت صلاحية الشهادة في أغسطس 2021. بعد تجربة بعض التجديدات اليدوية وإعادة تشغيل nginx، وجدت أن الشهادة تم دفعها لتنتهي صلاحيتها قبل أيام قليلة. لا تزال ليست شهادة حالية، بالطبع. تشغيل acme.sh يدويًا لفرض تجديد (داخل حاوية discourse) ينتج عنه هذا الخطأ (حيث [site] هو عنوان موقعي، بالطبع):

[site]:Verify error:Fetching http://[site]/.well-known/acme-challenge/[long alpha challenge string]: Error getting validation data

يجب أن أشير إلى أن الموقع يتطلب تسجيل الدخول لجميع وصول المستخدمين، ولكن هذا لم يكن مشكلة في تجديدات شهادات SSL خلال سنوات التشغيل السابقة.

أي أفكار؟ شكراً جزيلاً!

تحديث: اختبار التحقق باستخدام wget يعيد 404. ومع ذلك، لا أعرف أين يتم تكوين هذه البيانات في nginx لـ Discourse في حاوية وكيف ترتبط بـ nginx ذي الصلة الذي يقوم بالوكالة خارج الحاوية.

إعجابَين (2)

إذا كان الأمر يعود لبضعة أشهر، فهل له علاقة بهذا:

إعجابَين (2)

مرحباً. لا ينبغي أن يكون لذلك علاقة، لأن هذه المشكلة ستتسبب في رفض المتصفح للشهادات بأخطاء مختلفة، وليس أخطاء انتهاء صلاحية كما في حالتي. يبدو أن Let’s Encrypt لم يعد بإمكانه المصادقة مع Discourse لتسليم شهادات جديدة. شكراً.

إعجابَين (2)

ليس إذا كان الانتهاء الأول في أغسطس. كان يجب أن يتجدد بعد ذلك.

4 إعجابات

قد تكون هناك هذه المشكلة لتطبيق لم يتم تحديثه بعد يونيو: Letsencrypt certificate failure to renew - #11 by pfaffman

لست متأكدًا مما إذا كان هذا ما تبحث عنه ولكن: discourse_docker/templates/web.letsencrypt.ssl.template.yml at main · discourse/discourse_docker · GitHub

إعجابَين (2)

مرحباً. لا يبدو أن هذه تنطبق. أنا أرى خطأ 404 وليس تلك الأخطاء الأخرى، وقد تم تحديث البنيات طوال الوقت، وهذا القالب من جيت هاب هو بالفعل الإصدار المثبت بالفعل في تثبيتي. شكراً!

3 إعجابات

هل تستخدم Cloudflare مع السحابة البرتقالية أو أي وكيل عكسي آخر؟

إعجابَين (2)

سلبي. مستضاف محليًا على Ubuntu 18.04 باستخدام تثبيت Docker الافتراضي.

3 إعجابات

تشغيل مهمة cron (داخل الحاوية) يدويًا لتجديد الشهادة، ويفشل دائمًا بنفس الطريقة. محاولة الحصول على:

http://[site]/.well-known/acme-challenge/[challenge-string]

تفشل مع “خطأ في الحصول على بيانات التحقق.”

إعجابَين (2)

نظرًا لعدم الإلمام بالعملية، هل يمكن أن يكون الأمر يتوقع أن يكون الحاوية في حالة ليست كذلك عند تشغيل هذا البرنامج النصي بمفرده؟ على سبيل المثال، ربما يتوقع وظيفة cron أخرى لتحدث أولاً تقوم بإعداد nginx للسماح بالوصول إلى عنوان URL كهذا.

هل حاولت إجراء إعادة بناء؟ (والتي ستحاول الحصول على شهادة جديدة في هذه العملية.)

تذكر أنه مستضاف محليًا. هل يمكنك الوصول إلى المثيل من خارج شبكتك باستخدام اسم المجال؟

إعجابَين (2)

أهلاً، نعم إعادة بناء متعددة. لم يتغير شيء. أستخدم Let’s Encrypt على عدد من المواقع غير التابعة لـ Discourse وجميعها تتجدد بشكل جيد. نعم، يمكنني الوصول إليها من موقع خارجي وقد اختبرت باستخدام wget، وكانت النتيجة 404. سؤال: أين بالضبط يعيش شجر HTML الخاص بـ nginx في هذه الحالة، الجزء الذي سيحتوي (أو يجب أن يحتوي) على الدليل .well-known؟ لم أتمكن من العثور عليه. شكراً.

إعجابَين (2)

لم أتمكن من العثور على مهمة cron، بل مجرد نص برمجي لمستوى التشغيل في /etc/runit/1.d/letsencrypt. يبدو أن هذا النص البرمجي يبدأ نسخة جديدة من nginx بتكوين يتضمن هذا:

location ~ /.well-known {
  root /var/www/discourse/public;
  allow all;
}

أعتقد أن هذا يعني أن المسار سينتهي بـ /var/www/discourse/public/acme-challenge، على الرغم من أنه قد يتم إنشاؤه قبل التحدي، ثم إزالته بعد ذلك.

إذا كان هذا هو النص البرمجي الذي حاولت تشغيله يدويًا، فهل أوقفت nginx أولاً؟ النسخة التي يحاول النص البرمجي تشغيلها ستحاول الاستماع على المنفذ 80، لذا أشك في أن ذلك سيفشل إذا كان nginx يعمل بالفعل لـ Discourse.

إعجابَين (2)

أعتقد أنني قد أرى المشكلة. لكنني لا أعرف كيفية إصلاحها. يبدو أن جميع محاولات الوصول إلى المنتدى على منفذ https 80 يتم (كما هو متوقع) إعادة توجيهها إلى https 443. صحيح. لكن هذا يعني أنه عندما تحاول Let’s Encrypt التحقق من التجديد، فإنها تفشل، لأن الشهادة الحالية قد انتهت صلاحيتها. يمكنني رؤية إعادة التوجيه باستخدام wget. لذا فإن السؤال هو، كيف يمكنني تعطيل إعادة التوجيه مؤقتًا حتى تتمكن Let’s Encrypt من التحقق والحصول على شهادة جديدة غير منتهية الصلاحية؟ هناك تعقيد إضافي محتمل وهو أن إعادة التوجيه هي 301 دائمة. شكراً.

إعجابَين (2)

هذا إعادة التوجيه موجود في /etc/nginx/conf.d/discourse.conf ولن يتم استخدامه عند إيقاف nginx، ثم تشغيله بالإعداد المذكور في مشاركتي السابقة.

أخشى أنني لست على دراية بكيفية عمل الترقية التلقائية، لذلك لست متأكدًا من الطريقة المناسبة للتجديد أثناء تشغيل الحاوية. من الناحية النظرية، يجب أن يؤدي إيقاف الحاوية وتشغيلها إلى تجديدها، ولكن بما أنك قلت إن إعادة البناء لم تفعل ذلك، فمن المحتمل أن هذا أيضًا لن يفعل ذلك.

يحتوي acme.sh على خيارات مثل --renew-all ولكني لست متأكدًا من الخيارات الأخرى المطلوبة لكي يقوم بالشيء الصحيح هنا. قد يكون ما يلي كل ما تحتاجه، ولكني لا أستطيع التأكيد بشكل قاطع.

LE_WORKING_DIR="/shared/letsencrypt" /root/acme.sh/acme.sh --renew-all
إعجابَين (2)

وبالفعل يسمح هذا لـ Let’s Encrypt بالدخول دون إعادة التوجيه، ولكن يبدو أن الملف الذي يبحث عنه غير موجود، لذا فشل التحقق بنفس النتيجة في النهاية.

إعجابَين (2)

لدي نفس المشكلة. هل توصل أي شخص إلى إجراء واضح لتصحيح المشكلة؟

إعجابَين (2)

أنا الآن أستخدم هذا لمحاولة الحصول على الشهادة بنجاح. يبدو أن رمز التحقق يتم استرداده بواسطة curl، لكن acme.sh لا يزال يعلن عن فشل التحقق في كل مرة! لذلك لا يزال معطلاً.

“/shared/letsencrypt”/acme.sh --renew-all --force --insecure --home “/shared/letsencrypt” --debug

إعجابَين (2)

مرحباً @L30110 :slightly_smiling_face:

أنا أحد المنتظمين في مجتمع Let’s Encrypt. أرسلني @JimPas لإلقاء نظرة على هذا الموضوع، وهو ما سأفعله فور عودتي من الغداء.

3 إعجابات

مع العديد من عملاء ACME (مثل acme.sh) عندما يتم تحديد nginx كطريقة مصادقة، يتم إنشاء ملف تحدي http-01 في دليل محدد بناءً على استثناء/إعادة توجيه في تكوين خادم nginx بدلاً من وضعه مباشرة في بنية الدليل .well-known/acme-challenge في دليل الويب. غالبًا ما يكون هذا التوجيه موجودًا مؤقتًا فقط طوال مدة التحقق من التحدي، وكذلك ملفات التحدي نفسها.

لذلك:


اعتبار حكيم. يجب أن يجعل البرنامج النصي للتجديد المكتوب بشكل صحيح إيقاف nginx غير ضروري. عادةً، يتم استخدام nginx لتقديم ملف (ملفات) التحدي ثم يتم استخدام شيء مشابه لـ nginx -s reload لإعادة تحميل خادم الويب/الوكيل بسلاسة بمجرد الحصول على الشهادة الجديدة.


لا. :غمزة:

وفقًا لـ Challenge Types - Let's Encrypt :

يتبع تطبيقنا لتحدي HTTP-01 عمليات إعادة التوجيه، حتى 10 عمليات إعادة توجيه عميقة. يقبل فقط عمليات إعادة التوجيه إلى “http:” أو “https:”، وفقط إلى المنافذ 80 أو 443. لا يقبل عمليات إعادة التوجيه إلى عناوين IP. عند إعادة التوجيه إلى عنوان URL HTTPS، فإنه لا يتحقق من صحة الشهادات (نظرًا لأن هذا التحدي مخصص لتهيئة شهادات صالحة، فقد يصادف شهادات موقعة ذاتيًا أو منتهية الصلاحية على طول الطريق).


عادةً عندما نرى مشاكل كهذه، يكون أحد هذه الأمور هو السبب عادةً:

  • جدار حماية لا يسمح بمرور حركة المرور إلى خادم الويب/الوكيل الذي يقدم ملف (ملفات) التحدي.
  • جهاز توجيه/وكيل تم تعيينه/تكوينه بشكل غير صحيح بحيث تحاول طلب التحقق من التحدي من Boulder (خادم CA الخاص بـ Let’s Encrypt) استرداد الملف (الملفات) من خادم ويب أو دليل غير صحيح.
  • نوع من إعادة الكتابة/إعادة التوجيه (مثل ملفات .htaccess في Apache) يتداخل مع قدرة خادم الويب/الوكيل على تقديم ملفات التحدي من الموقع الصحيح.
  • استخدام منافذ غير قياسية، عادةً مع تعيين غير صحيح.
  • الحاوية التي تشغل عميل ACME تنشئ ملف (ملفات) التحدي في مكان لا يقدمها خادم الويب/الوكيل (مثل nginx). عندما يكون Docker متورطًا، فهذه هي المشكلة دائمًا تقريبًا.
إعجابَين (2)

مرحباً. إذن، من بين هذه العناصر المختلفة التي أدرجتها، من الواضح أن العديد منها لا ينطبق في حالتي. ليست مشكلة جدار حماية - يمكنني الوصول يدوياً إلى الرمز المميز باستخدام wget أو curl من كل من 1) داخل تطبيق Docker Discourse، و 2) من خارج حاوية Docker على النظام المضيف، و 3) نظام مرتبط.

في هذه الحالات اليدوية، أحصل على محتويات الرمز المميز من الموقع المتوقع، بافتراض أن --ignore أو -k محدد لتجاوز الشهادة منتهية الصلاحية عندما يقوم Discourse بإعادة التوجيه إلى https تلقائياً.

لم أقم بتغيير أي جانب من جوانب تكوين nginx الذي تم إنشاؤه بواسطة Discourse، سواء داخل أو خارج حاوية Docker الخاصة بـ Discourse. لا أقوم بتشغيل أي نسخ من nginx، ويعيش Apache على منافذ مختلفة تماماً للاستخدام المحلي فقط. مع ملاحظة أن كل هذا كان يعمل بشكل جيد لمدة تزيد عن عامين، مع تجديدات منتظمة للشهادات وعدم وجود تغييرات أخرى في التطبيق - إنه صندوق مستقر جداً.

لا توجد منافذ غير عادية.

بما أنني أستطيع الحصول على محتويات الرمز المميز يدوياً، فلا أرى كيف يمكن أن تكون المواقع الخاطئة متورطة. إلا …

لم أكن أتوقف يدوياً عن تشغيل nginx لاختباراتي. لقد فعلت ذلك الآن، ولم يكن هناك فرق كبير - نفس الأخطاء من acme.sh (حالياً الخطأ 56 مرة أخرى). عندما يتم إيقاف nginx من داخل الحاوية، أرى عملية runsv nginx على المضيف، ولكن ليس لديها عمليات عاملة أو ذاكرة تخزين مؤقت. عندما أعيد تشغيل nginx في الحاوية، تظهر عمليات العامل وذاكرة التخزين المؤقت على المضيف مع عملية runsv nginx التي بقيت. أوامر sv start/stop nginx داخل الحاوية تعطي التأكيدات المتوقعة لتلك الإجراءات.

ولكن هناك شيء آخر مذكور أعلاه قد يكون مصدر قلق. وأنا لا أفهم لماذا سيكون هذا مشكلة فجأة بالنظر إلى المدة التي كانت تعمل فيها الأمور حتى الآن.

عنوان IP الثابت للمنتدى الذي يتم استخدامه من خارج شبكاتي المحلية غير قابل للاستخدام من قبل هذا الجهاز للاتصال بخدمات هذا الجهاز نفسه، بسبب التعقيدات في الطريقة التي يتم بها توفير عناوين IP الثابتة من قبل مزود خدمة الإنترنت. لقد استخدمت بشكل روتيني إدخالات في /etc/hosts لتوفير عناوين IP للشبكة المحلية لتلك الأسماء. لذا، عندما أختبر باستخدام curl على نفس الجهاز (داخل أو خارج الحاوية، كلاهما لديه إضافة /etc/hosts للمنتدى)، يستخدم الاختبار عنوان IP مختلف (ومحلي) عن الذي سيستخدمه موقع خارجي يبحث عنه عبر DNS. هل هناك أي طريقة قد يكون هذا ذا صلة؟ شكراً.

إعجابَين (2)