مشاكل Letsencrypt

يبدو أن بعض التغييرات قد حدثت في خدمة letsencrypt اعتبارًا من 1 أغسطس. لم تنتهِ صلاحية شهادتي حتى اليوم، لذا تأثرت بالتغييرات فقط اليوم. تم تحديث السكربتات التي يستخدمها Discourse لإدارة خدمة letsencrypt لتستخدم افتراضيًا خدمة جديدة تسمى ZeroSSL بدلاً من letsencrypt. للأسف، يبدو أن ZeroSSL يتطلب التسجيل بعنوان بريد إلكتروني قبل أن تعمل، لذا عندما انتهت صلاحية شهادتي الحالية هذا الصباح، توقف الموقع عن العمل.

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

[Wed 01 Sep 2021 05:33:58 PM UTC] Reload error for :
[Wed 01 Sep 2021 05:34:03 PM UTC] Using CA: https://acme.zerossl.com/v2/DV90
[Wed 01 Sep 2021 05:34:04 PM UTC] No EAB credentials found for ZeroSSL, let's get one
[Wed 01 Sep 2021 05:34:04 PM UTC] acme.sh is using ZeroSSL as default CA now.
[Wed 01 Sep 2021 05:34:04 PM UTC] Please update your account with an email address first.
[Wed 01 Sep 2021 05:34:04 PM UTC] acme.sh --register-account -m my@example.com
[Wed 01 Sep 2021 05:34:04 PM UTC] See: https://github.com/acmesh-official/acme.sh/wiki/ZeroSSL.com-CA
[Wed 01 Sep 2021 05:34:04 PM UTC] Please check log file for more details: /shared/letsencrypt/acme.sh.log

حاولت تسجيل الحساب يدويًا من داخل الحاوية، ورغم أنها أظهرت أن التسجيل تم، إلا أنني عند إعادة تشغيل الحاوية حصلت على نفس الخطأ. لذا قمت بتتبع السكربتات، والسكربت المسؤول عن ذلك موجود داخل الحاوية في المسار /etc/runit/1.d/letsencrypt. إليك السكربت الأصلي:

#!/bin/bash
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf

issue_cert() {
  LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --issue $2 -d mudtoemanor.baronshire.org --keylength $1 -w /var/www/discourse/public
}

cert_exists() {
  [[ "$(cd /shared/letsencrypt/mudtoemanor.baronshire.org$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
}

########################################################
# RSA cert
########################################################
issue_cert "4096"

if ! cert_exists ""; then
  # Try to issue the cert again if something goes wrong
  issue_cert "4096" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
  --installcert \
  -d mudtoemanor.baronshire.org \
  --fullchainpath /shared/ssl/mudtoemanor.baronshire.org.cer \
  --keypath /shared/ssl/mudtoemanor.baronshire.org.key \
  --reloadcmd "sv reload nginx"

########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"

if ! cert_exists "_ecc"; then
  # Try to issue the cert again if something goes wrong
  issue_cert "ec-256" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
  --installcert --ecc \
  -d mudtoemanor.baronshire.org \
  --fullchainpath /shared/ssl/mudtoemanor.baronshire.org_ecc.cer \
  --keypath /shared/ssl/mudtoemanor.baronshire.org_ecc.key \
  --reloadcmd "sv reload nginx"

if cert_exists "" || cert_exists "_ecc"; then
  grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
fi

/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop

بما أن تسجيل البريد الإلكتروني لم ينجح، قررت إضافة خيار لجعل سكربت acme.sh يعود لاستخدام خدمة letsencrypt الأصلية بدلاً من ZeroSSL. وقد وُضعت تعليمات حول كيفية القيام بذلك في هذا الموقع: https://community.letsencrypt.org/t/the-acme-sh-will-change-default-ca-to-zerossl-on-august-1st-2021/144052

في البداية، حاولت إضافة هذا السطر كسطر ثالث في السكربت مباشرة بعد عبارة “/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf”:

/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt

أظهر السجل رسالة مفادها أن الافتراضي تم تغييره، ولكن مباشرة بعد ذلك حصلت على نفس الخطأ المتعلق بعدم وجود بريد إلكتروني مسجل لـ ZeroSSL. كان هناك تأخير قدره حوالي 6 ثوانٍ في السجل بين هذه الرسالة ورسائل الخطأ، مما يجعلني أعتقد أن سكربت acme.sh يجب أن يحافظ على معلومات الحالة عبر متغيرات البيئة، وأن التنفيذات اللاحقة للأمر كانت تعمل في سياق مختلف وبالتالي فقدت المتغير. لذا، ما انتهى بي الأمر بفعله هو تغيير جميع استدعاءات acme.sh في سكربت letsencrypt لإضافة الوسيطة “–server letsencrypt” إلى الأمر. عندما فعلت ذلك وأعدت تشغيل الحاوية، تم إنشاء شهادة جديدة بواسطة letsencrypt بدلاً من ZeroSSL، وعاد الموقع للعمل.

إليك النسخة المعدلة من سكربت letsencrypt التي استخدمتها:

#!/bin/bash
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
/shared/letsencrypt/acme.sh --set-default-ca --server letsencrypt

issue_cert() {
  LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --server letsencrypt --issue $2 -d mudtoemanor.baronshire.org --keylength $1 -w /var/www/discourse/public
}

cert_exists() {
  [[ "$(cd /shared/letsencrypt/mudtoemanor.baronshire.org$1 && openssl verify -CAfile ca.cer fullchain.cer | grep "OK")" ]]
}

########################################################
# RSA cert
########################################################
issue_cert "4096"

if ! cert_exists ""; then
  # Try to issue the cert again if something goes wrong
  issue_cert "4096" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
  --installcert \
  -d mudtoemanor.baronshire.org \
  --fullchainpath /shared/ssl/mudtoemanor.baronshire.org.cer \
  --keypath /shared/ssl/mudtoemanor.baronshire.org.key \
  --server letsencrypt \
  --reloadcmd "sv reload nginx"

########################################################
# ECDSA cert
########################################################
issue_cert "ec-256"

if ! cert_exists "_ecc"; then
  # Try to issue the cert again if something goes wrong
  issue_cert "ec-256" "--force"
fi

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh \
  --installcert --ecc \
  -d mudtoemanor.baronshire.org \
  --fullchainpath /shared/ssl/mudtoemanor.baronshire.org_ecc.cer \
  --keypath /shared/ssl/mudtoemanor.baronshire.org_ecc.key \
  --server letsencrypt \
  --reloadcmd "sv reload nginx"

if cert_exists "" || cert_exists "_ecc"; then
  grep -q 'force_https' "/var/www/discourse/config/discourse.conf" || echo "force_https = 'true'" >> "/var/www/discourse/config/discourse.conf"
fi

/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop

كما تركت الأمر الأصلي الذي أضفته لمحاولة تعيين الخدمة الافتراضية احتياطًا، لكنه قد لا يكون ضروريًا.

إذن، ما يجب أن يحدث هو تغيير هذا السكربت إما لتحديد خدمة letsencrypt المراد استخدامها صراحةً في جميع استدعاءات acme.sh، أو لمعرفة كيفية قيام acme.sh بحفظ معلومات الحالة بحيث يعمل استدعاء واحد للأمر الافتراضي، أو أخيرًا إضافة دعم لـ ZeroSSL وضرورة جمع وحفظ عنوان بريد إلكتروني.

أفترض أن ما قمت به سيتم تجاوزها في المرة القادمة التي أقوم فيها بترقية الإصدارات، وسأضطر إلى تكرار ذلك إذا لم يتم حل هذه المشكلة.

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

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

فقط أضف عنوان بريدك الإلكتروني في ملف الإعدادات.

/var/discourse/containers/app.yml

## إذا أضفت قالب Lets Encrypt، قم بإلغاء التعليق أدناه للحصول على شهادة SSL مجانية
 LETSENCRYPT_ACCOUNT_EMAIL: gavin@truecode.co.za

قم بتشغيل الأمر ./launcher rebuild app

بعدها ستكون جاهزًا للاستخدام.

لقد أصلحنا هذا قبل بضعة أسابيع، هل جربت إعادة البناء؟

3 إعجابات

لا، لم أجرب ذلك. أنا أعمل بالإصدار 2.8.0.beta4، ويظهر لي أن النظام محدث. هل يجب عليّ إجراء إعادة بناء بعد التحديثات، أم أن الملفات يتم تحميلها تلقائيًا بين التحديثات مما قد يتطلب إعادة بناء؟ لدي بالفعل عنوان بريد إلكتروني مُدرج في LETSENCRYPT_ACCOUNT_EMAIL.

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

في حين يمكنك تحديث التطبيق من واجهة الويب، إلا أننا بين الحين والآخر نضطر إلى إصدار تحديث للبيئة الأساسية التي يعمل عليها Discourse (صورة الحاوية). وتتطلب هذه التحديثات البيئية إعادة بناء.

ولإلغاء التغييرات المحلية الخاصة بك، قد تتمكن من حفظها مؤقتًا باستخدام الأمر التالي:

cd /var/discourse
git stash
./launcher rebuild app
إعجاب واحد (1)

هل هذه “التحديثات البيئية” هي تحديثات “docker-manager” التي أراها بعد النقر على رابط “إجراء الترقيات هنا” في صفحة إعدادات المسؤول؟ أعتقد أنني مرتبك قليلاً الآن بشأن أي التحديثات يجب أن أحصل عليها ومن أين ومتى أعرف أنه يجب علي إعادة البناء. على الرغم من أنني أرى ترقية في تلك الصفحة، إلا أن الصفحة السابقة لا تزال تقول إنني محدث.

لا، للحصول على تلك التحديثات يجب عليك الوصول إلى الخادم عبر سطر الأوامر وإصدار أمر إعادة البناء.

حسناً. لقد قمت بإعادة البناء، لكنني غير متأكد مما إذا كان سيُنجح خلال 90 يوماً، لأن الشهادة لم تنتهِ صلاحيتها بعد، وبالتالي لا تحاول الحصول على شهادة جديدة. لقد تفحصت سكريبت letsencrypt ووجدت أن تاريخ التعديل الجديد هو اليوم، لكن عند مقارنته بالإصدار القديم من السكريبت (النسخة الأصلية، قبل تعديلاتي)، اتضح أنهما متطابقان. حاولت تشغيل السكريبت يدوياً داخل الحاوية باستخدام خيار --force وفقاً لأحد تعليقات رسائل الإخراج، لكن ذلك لم ينجح. لذا، في هذه المرحلة، سأضطر إلى الاعتماد على الإيمان بأن الشهادة ستُجدد بشكل صحيح عند انتهاء صلاحيتها.