يبدو أن بعض التغييرات قد حدثت في خدمة 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 وضرورة جمع وحفظ عنوان بريد إلكتروني.
أفترض أن ما قمت به سيتم تجاوزها في المرة القادمة التي أقوم فيها بترقية الإصدارات، وسأضطر إلى تكرار ذلك إذا لم يتم حل هذه المشكلة.
إذا فاتني شيء هنا أو تم معالجة هذا الأمر بطريقة أخرى لا تتطلب تغيير السكربتات، فيرجى إعلامي.