فشل Discourse في تجديد الشهادة

متابعة المحادثة من هنا:

هذه هي المرة الأولى التي أتلقى فيها تذكيرًا من Redsift بأن شهاداتي ستنتهي صلاحيتها في غضون أسبوع. عادةً ما يقوم Discourse بتجديد الشهادات قبل وقت طويل من انتهاء صلاحيتها. هذه المرة لم يحدث ذلك، قبل أن أبدأ في إعادة البناء (والتي من المفترض أن تحل المشكلة)، @Falco هل هناك أي شيء تريد مني التحقق منه ونشره هنا للمساعدة في الوصول إلى جذر سبب عدم تجديد الشهادات؟
الشهادة الجذرية هي ISRGX1 وهذه هي معلومات الشهادة منتهية الصلاحية:

الاسم الشائع (CN) E6
المنظمة (O) Let’s Encrypt
الوحدة التنظيمية (OU) <لم يكن جزءًا من الشهادة>
تم الإصدار في الأربعاء، 16 يوليو 2025، الساعة 7:36:45 مساءً
تنتهي الصلاحية في الثلاثاء، 14 أكتوبر 2025، الساعة 7:36:44 مساءً

الإصدار الحالي هو 3.6.0.beta1-dev (7ee52c8f85)

إعجاب واحد (1)

كانت هناك فترة زمنية تم فيها إعادة توجيه نقطة النهاية التي تحتاجها Let’s Encrypt. تم إصلاح ذلك إذا قمت بإعادة البناء.

5 إعجابات

ما هي المدة التقريبية التي يجب بعدها تجديد الشهادة بعد التحديث؟

إذا كانت الذاكرة لا تخونني، فإن الشهادات صالحة لمدة 3 أشهر، وسيتم الآن محاولة تجديدها تلقائيًا قبل ذلك.

إعجاب واحد (1)

نعم، أعرف كيف يفترض أن يعمل.

ولكن مرّ أكثر من يوم منذ أن قمت بتحديث برنامج المنتدى، ويبدو أن الشهادة لم يتم تحديثها بعد. أمامها 5 أيام قبل أن تنتهي صلاحيتها، لذا يجب تجديدها قريبًا.

أنا أستخدم فرع Discourse المستقر إذا كان ذلك يحدث فرقًا. هل من الممكن أن يكون إصلاح نقطة النهاية لم يتم نقله للخلف؟

بالنسبة لي، تم تحديث الشهادة على الفور بعد إعادة البناء

هل قمت بإعادة البناء عبر الويب أم عبر سطر الأوامر؟

إعجاب واحد (1)

نعم، كان الشرح هنا:

إعجاب واحد (1)

لقد قام المنتدى الخاص بي أخيرًا بتحديث شهادته بعد أن قمت بإعادة بناء سطر الأوامر.

3 إعجابات

لقد مررنا بنفس تجربة عدم تجديد SSL.

سيكون من الرائع لو قام شخص ما بالتحقق المزدوج من أن web.ssl.template يتصرف بشكل صحيح على discourse-docker، ويبدو لي أن المنفذ 80 لم يكن يخدم أي من عناوين /.well-known/ التي يستخدمها Let’s Encrypt، وتم توجيه جميع عناوين URL إلى SSL بما في ذلك الملفات التجريبية التي وضعتها يدويًا في /var/www/discourse/public/.well-known/ . اضطررت إلى تحرير /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf مباشرة داخل حاوية التطبيق.

ربما بدأ هذا بعد commit ae4887a من discourse-docker؟

إعجاب واحد (1)

حدث خطأ آخر في المسار المعروف مؤخرًا.

متى كانت آخر مرة قمت فيها بإعادة بناء؟

إعجاب واحد (1)

حدث معي نفس الشيء. لم أتلق تحذيرًا بشأن انتهاء صلاحية الشهادة. الدخول إلى الخادم وتشغيل إعادة البناء /var/discourse % ./launcher rebuild قام بالمهمة.

إعجابَين (2)

في اختباري على تثبيت nginx عادي (1.18.0 ولكن أعتقد أنه نفس الشيء لـ 1.26.3)، فإن سطر تكوين nginx return 301 https://thehostname$request_uri; خارج نطاق location يتجاوز تمامًا أي كتلة location سابقة قبله، بدلاً من أن يكون بمثابة “catch-all”. أعتقد أن /.well-known/ لا يتم تقديمه ببساطة على المنفذ 80 ما لم يكن إعادة التوجيه 301 مخصصًا لموقع آخر مثل / في نهاية كتلة الخادم. هل يمكن أن تكون نفس مشكلة منشور stackoverflow هذا؟

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

إذا كنت تعتقد أن هذا هو Discourse، فربما يجب عليك الرد على التزام github أو فتح تقرير كبير جديد.

إعجاب واحد (1)

يمكنني أن أؤكد أن تجديد letsencrypt يفشل. لقد كنت أدير تثبيت Discourse مستضاف ذاتيًا لسنوات، وبشكل غريب للغاية فشل التجديد بالنسبة لي مرتين متتاليتين خلال الشهرين الماضيين. كانت المرة الثانية هذا الصباح، لذلك بدأت في التحقيق.

لقد تتبعت الأمر إلى الالتزامين التاليين:

والسطر ذي الصلة المرتبط:

هناك مشكلتان، أعتقد.

أولاً، يتم تحويل return 301 https://${DISCOURSE_HOSTNAME}$request_uri; إلى return 301 https://<اسم الخادم الخاص بي> بدون $request_uri في النهاية. لقد تحققت من التثبيت المستضاف ذاتيًا، وكذلك من تثبيت صديق مستضاف ذاتيًا تم إعداده في الأسبوع الماضي. لا أفهم كيف يعمل قالب Discourse، لذلك لا أعرف سبب حذفه.

ثانياً، كما ذكر @lessLost، فإن إعادة التوجيه 301 خارج كتلة الموقع. أعتقد أن إعادة التوجيه على مستوى الخادم تتجاوز جميع كتل الموقع. يستخدم LetsEncrypt http للتجديدات. ومع ذلك، فإن أي محاولة لـ curl -I http://YOUR_DOMAIN/.well-known/acme-challenge/test ستعيد 301 إلى https، بدلاً من 404 (وهو السلوك المتوقع؛ نحن نريد 404 وليس 301).

لقد أصلحت هذا يدويًا في التثبيت المستضاف ذاتيًا، ولكني أتوقع أن أي تحديث سيتجاوز تغييراتي. لسوء الحظ، لا أفهم القوالب بما يكفي لتقديم طلب سحب @pfaffman — وإلا كنت سأفعل ذلك أيضًا.

تم التعديل للإضافة:

أعتقد أن هذا خطأ —

أنا متأكد تمامًا من أن LetsEncrypt يستخدم http افتراضيًا (لأسباب واضحة، إذا كانت الشهادة منتهية الصلاحية فلا يمكن تجديدها!) ولكن وضع إعادة التوجيه 301 على مستوى كتلة الخادم يجبر جميع الطلبات على إعادة التوجيه 301 إلى https، وهو ما يتعارض مع استراتيجية التجديد هذه.

إعجاب واحد (1)

متى كانت آخر عملية إعادة بناء لك؟

في هذا الصباح، بعد حوالي 10 دقائق من استيقاظي، زرت منتدى خاصتي وأدركت أن الشهادة قد انتهت صلاحيتها مرة أخرى. (إعادة البناء هي ما جددها في المرة الأخيرة التي انتهت فيها صلاحيتي - قبل حوالي 3 أشهر؟)

أعتقد أنهم أجروا تغييرات منذ ذلك الحين قامت بإصلاح هذه المشكلة، ولكن نظرًا لأن الأمر يستغرق 3 أشهر لمعرفة ذلك، فلا يزال الحكم معلقًا. قد تحدد تذكيرًا قبل أسبوعين من انتهاء صلاحية الشهادة الحالية.

إعجاب واحد (1)

هذا ليس صحيحًا.

  1. الروابط التي أرفقتها في التعليق أعلاه كانت من git blame. إليك أحدث إصدار للملف (السطر ذو الصلة مرتبط): discourse_docker/templates/web.ssl.template.yml at 247c71a1e45d32b0b814a8e9d5fdaa4faaf727b9 · discourse/discourse_docker · GitHub
  2. كان تثبيت موقع صديقي الجديد منذ أسبوع. يقرأ السطر 37 من القالب أعلاه: return 301 https://${DISCOURSE_HOSTNAME}$request_uri; ولكن في حاوية Discourse Docker، يقرأ كل من ملفه (وملفي) /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf ما يلي: return 301 https://<عنوان_موقع_المنتدى_الخاص_بك>؛ لاحظ كيف تم تجريد $request_uri. هناك شيء ما يتسبب في اختفائه! (لا أعرف ما هو).
  3. أجريت تجديدًا قسريًا محاكى هذا الصباح كجزء من تحقيقي. لقد فشل. ثم قمت بتغيير /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf. لقد نجح!

هذا جيد في الواقع؛ سأقوم فقط بتعديل 20-redirect-http-to-https.conf يدويًا في كل مرة أقوم فيها بتحديث Discourse. بالنسبة لأولئك الذين يصادفون هذا التعليق، فإن الأمر الذي يجب تشغيله هو:

cat > /etc/nginx/conf.d/outlets/before-server/20-redirect-http-to-https.conf << 'EOF'
server {
  listen 80;
  listen [::]:80;

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

  location / {
    return 301 https://<عنوان_منتدىك_هنا>$request_uri;
  }
}
EOF

لست متأكدًا تمامًا مما يسبب هذا الفشل، ولكني أعرف أن تعديل ملف التكوين أعلاه يصلحه. ولكني قمت أيضًا بتعديل الإشعارات حتى لا تفشل تجديدات letsencrypt بصمت بعد الآن - حتى أتمكن من الحصول على بعض التحذير المسبق. اعتقدت أنك قد ترغب في معرفة ذلك!

4 إعجابات

شكراً على التقرير، أعتقد أن هذا صحيح.

(للعلم @featheredtoast)

6 إعجابات