إعداد Let's Encrypt مع عدة نطاقات / تحويلات

NOTE: @pfaffman says: This page needs to be cleaned up. There is now a new ENV setting that will let you add more hostnames. In your app.yml under your DISCOURSE_HOSTNAME line (it can go many places but that one makes sense), add

 DISCOURSE_HOSTNAME_ALIASES: domain.com,other.domain.com

and early reports suggest that you’ll get valid certs for those domains and that accessing https://domain.com will properly redirect you to your DISCOURSE_HOSTNAME without a certificate error.

If you do that and it works for you, you might add another “me too!” post to the bottom. If you feel comfortable, you could also edit this first post with the instructions that you think would be most helpful.


This is to address the problem where you get certificate errors with any redirects or CNAME DNS entries which point to your actual installed Discourse (sub)domain.

If you do not have https configured already (you do if you have done a standard install recently) see Setting up Let’s Encrypt as your first step.

Legacy Method

The method below no longer reliably works as of August 2025

There are three patterns that need to be replaced. Enter your (sub)domain (and any additional subdomains preceded by -d ) and then add the following to your app.yml hooks section (towards the end of the file):

2025-04-23 @pfaffman changed the code because there’s a 3rd place it needs to be changed

  after_ssl:
    - replace:
        filename: /etc/runit/1.d/letsencrypt
        from: /-d =domain1= /
        to: "-d =domain1= -d =domain2= "
        global: true

This will allow you to have HTTPS configured for a second domain that will redirect to the correct one without certificate issues.

If you need to add multiple extra domains, you can enter something like this in the domain2 field: www.bananas.com -d forum.bananas.com

For example, if you want people who visit https://forum.example.com to be redirected to your forum at https://community.example.com without a certificate error, this is all you need.

47 إعجابًا

شكرًا، هل يعمل هذا على إعادة توجيه “www.example.com” إلى “comunnity.example.com”؟
أو كيف يمكنني القيام بذلك؟
لدي مشاكل مع نطاقي www.example.com، لقد قمت بتكوين نظام أسماء النطاقات (DNS) لإعادة التوجيه إلى comunnity.example.com ولكنه لا يعمل على فايرفوكس أو كروم.

إعجابَين (2)

هناك أداة فحص إعادة التوجيه للتحقق من عمليات إعادة التوجيه الخاصة بك.

5 إعجابات

أواجه صعوبة في هذا الأمر بعض الشيء. حسناً، كثيراً في الواقع.

قررت أن أجرب إضافة شبكة توصيل محتوى (CDN) إلى أحد مواقعي.

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

لذا فكرت: “مهلاً، سيكون هذا سهلاً، لقد فعلت ذلك من قبل…” هل حقاً؟ :sweat_smile:

الموقع المعني هو https://starzen.space.

لقد نقلته في نهاية هذا الأسبوع إلى https://www.starzen.space باستخدام الدليل هنا

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

وفقًا لفهمي، أحتاج أيضًا إلى الرابط الأصلي الصادر بشهادة، لذلك باتباع هذا الدليل (الذي كان أكثر تعقيدًا في السابق؟) أضفت هذا إلى app.yml:

hooks:
  after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /--keylength/
        to: "-d starzen.space --keylength"
    - replace:
        filename: "/etc/nginx/conf.d/discourse.conf"
        from: /return 301 https.+/
        to: |
          return 301 https://$host$request_uri;
  after_web_config:
    - replace:
        filename: /etc/nginx/nginx.conf
        from: /sendfile.+on;/
        to: |
          server_names_hash_bucket_size 64;
          sendfile on;
    - file:
        path: /etc/nginx/conf.d/discourse_redirect_1.conf
        contents: |
          server {
            listen 80;
            listen 443 ssl;
            server_name starzen.space;
            return 301 $scheme://www.starzen.space$request_uri;
          }

عند إعادة البناء، يبدو أن كل شيء يسير على ما يرام.

ومع ذلك، إذا حاولت الوصول إلى https://starzen.space عبر المتصفح، أحصل على:

وإذا استخدمت curl:

blah discourse % curl https://starzen.space
curl: (60) SSL: no alternative certificate subject name matches target host name 'starzen.space'
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

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

blah discourse % curl -k https://starzen.space

301 Moved Permanently
301 Moved Permanently
nginx/1.21.6

وهو ما أعتقد أنه ما أريده.

أعتقد أن ملف البرنامج النصي المعدل صحيح، هذا ما لدي:

root@starship-enterprise:/etc/runit/1.d# cat 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 www.starzen.space -d starzen.space --keylength $1 -w /var/www/discourse/public
}

cert_exists() {
  [[ "$(cd /shared/letsencrypt/www.starzen.space$1 && openssl verify -CAfile <(openssl x509 -in 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

<SNIP>

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

root@starship-enterprise:/etc/runit/1.d# ./letsencrypt 
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
[Sun 25 Sep 2022 05:50:04 PM UTC] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Sun 25 Sep 2022 05:50:04 PM UTC] Creating domain key
[Sun 25 Sep 2022 05:50:05 PM UTC] The domain key is here: /shared/letsencrypt/www.starzen.space/www.starzen.space.key
[Sun 25 Sep 2022 05:50:05 PM UTC] Multi domain='DNS:www.starzen.space,DNS:starzen.space'
[Sun 25 Sep 2022 05:50:05 PM UTC] Getting domain auth token for each domain
[Sun 25 Sep 2022 05:50:08 PM UTC] Getting webroot for domain='www.starzen.space'
[Sun 25 Sep 2022 05:50:08 PM UTC] Getting webroot for domain='starzen.space'
[Sun 25 Sep 2022 05:50:08 PM UTC] www.starzen.space is already verified, skip http-01.
[Sun 25 Sep 2022 05:50:08 PM UTC] Verifying: starzen.space
[Sun 25 Sep 2022 05:50:12 PM UTC] Pending
[Sun 25 Sep 2022 05:50:15 PM UTC] Success
[Sun 25 Sep 2022 05:50:15 PM UTC] Verify finished, start to sign.
[Sun 25 Sep 2022 05:50:15 PM UTC] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/590255196/128806215177'
[Sun 25 Sep 2022 05:50:16 PM UTC] Downloading cert.
[Sun 25 Sep 2022 05:50:16 PM UTC] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03ff6b1b76f8516165032c6c2e02205a529b'
[Sun 25 Sep 2022 05:50:17 PM UTC] Cert success.
-----BEGIN CERTIFICATE-----
Lotsofcrazytext
-----END CERTIFICATE-----
[Sun 25 Sep 2022 05:50:17 PM UTC] Your cert is in  /shared/letsencrypt/www.starzen.space/www.starzen.space.cer 
[Sun 25 Sep 2022 05:50:17 PM UTC] Your cert key is in  /shared/letsencrypt/www.starzen.space/www.starzen.space.key 
[Sun 25 Sep 2022 05:50:17 PM UTC] The intermediate CA cert is in  /shared/letsencrypt/www.starzen.space/ca.cer 
[Sun 25 Sep 2022 05:50:17 PM UTC] And the full chain certs is there:  /shared/letsencrypt/www.starzen.space/fullchain.cer 
[Sun 25 Sep 2022 05:50:17 PM UTC] Installing key to:/shared/ssl/www.starzen.space.key
[Sun 25 Sep 2022 05:50:17 PM UTC] Installing full chain to:/shared/ssl/www.starzen.space.cer
[Sun 25 Sep 2022 05:50:17 PM UTC] Run reload cmd: sv reload nginx
ok: run: nginx: (pid 579) 35281s
[Sun 25 Sep 2022 05:50:17 PM UTC] Reload success
[Sun 25 Sep 2022 05:50:18 PM UTC] Domains not changed.
[Sun 25 Sep 2022 05:50:18 PM UTC] Skip, Next renewal time is: Wed 23 Nov 2022 10:01:01 AM UTC
[Sun 25 Sep 2022 05:50:18 PM UTC] Add '--force' to force to renew.
[Sun 25 Sep 2022 05:50:18 PM UTC] Installing key to:/shared/ssl/www.starzen.space_ecc.key
[Sun 25 Sep 2022 05:50:18 PM UTC] Installing full chain to:/shared/ssl/www.starzen.space_ecc.cer
[Sun 25 Sep 2022 05:50:18 PM UTC] Run reload cmd: sv reload nginx
ok: run: nginx: (pid 579) 35282s
[Sun 25 Sep 2022 05:50:18 PM UTC] Reload success

نجاح كبير في الغالب!!!، curl أصبح أكثر لطفًا الآن ويعطيني إعادة التوجيه:

blah discourse % curl https://starzen.space

301 Moved Permanently
301 Moved Permanently
nginx/1.21.6

و https://starzen.space في Firefox و Chrome يعمل الآن، ويعيد التوجيه إلى النطاق الفرعي الصحيح، ولكن ما زلت أحصل على الرسم البياني المروع للموت في Safari، ما الذي يحدث؟ لقد أعدت تشغيله ومسحت ذاكرة التخزين المؤقت لهذا الموقع:

بالنظر إلى الشهادة من المتصفح، أرى:

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

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

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

3 إعجابات

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

يبدو أن هناك مجموعتين من الملفات التشفيرية؟:

root@starship-enterprise:/shared/letsencrypt# cd starzen.space
root@starship-enterprise:/shared/letsencrypt/starzen.space# ls
backup	ca.cer	fullchain.cer  starzen.space.cer  starzen.space.conf  starzen.space.csr  starzen.space.csr.conf  starzen.space.key
root@starship-enterprise:/shared/letsencrypt/starzen.space# cd ..
root@starship-enterprise:/shared/letsencrypt# cd www.starzen.space
root@starship-enterprise:/shared/letsencrypt/www.starzen.space# ls
backup	    ca.cer	   www.starzen.space.cer   www.starzen.space.csr       www.starzen.space.key
backup_two  fullchain.cer  www.starzen.space.conf  www.starzen.space.csr.conf
root@starship-enterprise:/shared/letsencrypt/www.starzen.space# 

آه، هل يمكن أن يكون هنا (وما يلي)

إنه يتضمن فقط معلومات لاسم المضيف، وليس القمة؟

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

لا، أعتقد أن هذا صحيح؟ يجب أن يكون هناك شهادة واحدة ويجب أن تعمل لكل من www. والنقطة الأصلية.

تقترح هذه الأداة أن هناك مجالًا واحدًا فقط على شهادتي العامة (والذي سيكون مصدر المشكلة؟):

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

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

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

إذا قمت بتشغيل certbot certificates، فسيتم عرض الشهادة (الشهادات) الخاصة بك والنطاقات التي تغطيها. إذا لم تكن تغطي كلاً من النطاق الأساسي (apex) والنطاق www، فيمكنك

  1. تشغيل certbot مرة أخرى وجعله ينشئ شهادة لكل من النطاق الأساسي (apex) والنطاق www؛

إذا اخترت هذا الخيار، فقم بتشغيل certbot certificates للحصول على اسم الشهادة التي تريد حذفها. قم بتشغيل certbot delete (اسم الشهادة التي تريد حذفها). يجب أن تتركك شهادتك الجديدة فقط (مع كل من النطاق الأساسي www).
أو (الأسهل)
2) تشغيل `certbot --expand -d existing.domain -d added.domain

سيؤدي هذا إلى تحديث شهادتك بشهادة جديدة تحتوي على النطاق الأصلي والنطاقات التي تضيفها باستخدام العلامة -d.

إعجابَين (2)

جيم، الأمر certbot غير موجود؟ هل هذا جزء من التثبيت القياسي وهناك مجرد مشكلة في المسار؟

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

بدون النظر فعليًا… أعتقد أن certbot هو ما تستخدمه عادةً، ولكن داخل الحاوية استخدم discourse acme.

وأيضًا بشكل متعلق، هل تحاول هذا داخل الحاوية أم خارجها؟

(أيضًا يومي يمتلئ وقد لا أتمكن من النظر في هذا بعناية كما كنت أعتقد، ولكنه كان على قائمتي)

3 إعجابات

أتفق … أعتقد أن إحدى الطرق للقيام بذلك هي هذه؟:

إذا استخدمت من أي سطر أوامر لينكس مناسب

true | openssl s_client -connect www.starzen.space:443 2>/dev/null \
| openssl x509 -noout -text \
| perl -l -0777 -ne '@names=/\\bDNS:([^\\s,]+)/g; print join("\n", sort @names);'

أحصل على نطاق واحد فقط وهو يفتقد إلى القمة (apex).

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

داخل الحاوية تجد الرمز الذي يطلب (ويجدد؟) الشهادة وتكتشف أنه يطلبها لكلا النطاقين.

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

نعم، كما هو موضح في:

LE_WORKING_DIR="${LETSENCRYPT_DIR}" /shared/letsencrypt/acme.sh --issue $2 -d www.starzen.space -d starzen.space --keylength

ويمكنك رؤية هذا في مخرجات السجل أعلاه.

ومع ذلك، هناك بعض خطوات تثبيت الشهادة الأخرى التي تتضمن فقط -d www.starzen.space، وقد يكون هذا مشكلة؟ على الرغم من أنه إذا تم إنشاء هذه الشهادة لكليهما، فربما ليست هذه هي المشكلة…

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

هذا ما كنت أحاول قوله. يبدو أنك بحاجة إلى تحديثها أيضًا. لست متأكدًا لماذا يوجد الآن العديد منها، ولكن يجب تحديث OP بالتعليمات البرمجية لتغيير كل هذه الخطوات. أو هكذا أعتقد.

4 إعجابات

نعم، سأجرب ذلك، يدويًا في البداية

إعجابَين (2)

حسنًا. هذا ما كنت سأفعله. ربما خدعتك لأفعل ذلك. :winking_face_with_tongue:

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

من المنطقي المحاولة، فقط قد أحتاج إلى إعادة بناء الحاوية لتثبيت nano … :sweat_smile:

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

لا!

 apt-get uodate;apt-get install nano

يمكنك تشغيل ذلك داخل الحاوية. أنا أفعل ذلك طوال الوقت (باستثناء أنني أستخدم vim)

3 إعجابات

للأسف لم ينجح ذلك:

root@starship-enterprise:/etc/runit/1.d# ./letsencrypt 
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] still could not bind()
[Mon 26 Sep 2022 12:35:54 PM UTC] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Mon 26 Sep 2022 12:35:54 PM UTC] Creating domain key
[Mon 26 Sep 2022 12:35:56 PM UTC] The domain key is here: /shared/letsencrypt/www.starzen.space/www.starzen.space.key
[Mon 26 Sep 2022 12:35:56 PM UTC] Multi domain='DNS:www.starzen.space,DNS:starzen.space'
[Mon 26 Sep 2022 12:35:56 PM UTC] Getting domain auth token for each domain
[Mon 26 Sep 2022 12:35:59 PM UTC] Getting webroot for domain='www.starzen.space'
[Mon 26 Sep 2022 12:35:59 PM UTC] Getting webroot for domain='starzen.space'
[Mon 26 Sep 2022 12:35:59 PM UTC] www.starzen.space is already verified, skip http-01.
[Mon 26 Sep 2022 12:35:59 PM UTC] starzen.space is already verified, skip http-01.
[Mon 26 Sep 2022 12:36:00 PM UTC] Verify finished, start to sign.
[Mon 26 Sep 2022 12:36:00 PM UTC] Lets finalize the order.
[Mon 26 Sep 2022 12:36:00 PM UTC] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/590255196/129044627717'
[Mon 26 Sep 2022 12:36:01 PM UTC] Downloading cert.
[Mon 26 Sep 2022 12:36:01 PM UTC] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03ffc90cecd2f11f2ba386da2d501127aee5'
[Mon 26 Sep 2022 12:36:02 PM UTC] Cert success.
-----BEGIN CERTIFICATE-----
phewbigcert
-----END CERTIFICATE-----
[Mon 26 Sep 2022 12:36:02 PM UTC] Your cert is in  /shared/letsencrypt/www.starzen.space/www.starzen.space.cer 
[Mon 26 Sep 2022 12:36:02 PM UTC] Your cert key is in  /shared/letsencrypt/www.starzen.space/www.starzen.space.key 
[Mon 26 Sep 2022 12:36:02 PM UTC] The intermediate CA cert is in  /shared/letsencrypt/www.starzen.space/ca.cer 
[Mon 26 Sep 2022 12:36:02 PM UTC] And the full chain certs is there:  /shared/letsencrypt/www.starzen.space/fullchain.cer 
[Mon 26 Sep 2022 12:36:02 PM UTC] Installing key to:/shared/ssl/www.starzen.space.key
[Mon 26 Sep 2022 12:36:02 PM UTC] Installing full chain to:/shared/ssl/www.starzen.space.cer
[Mon 26 Sep 2022 12:36:02 PM UTC] Run reload cmd: sv reload nginx
ok: run: nginx: (pid 2970) 329s
[Mon 26 Sep 2022 12:36:02 PM UTC] Reload success
[Mon 26 Sep 2022 12:36:03 PM UTC] Domains not changed.
[Mon 26 Sep 2022 12:36:03 PM UTC] Skip, Next renewal time is: Wed 23 Nov 2022 10:01:01 AM UTC
[Mon 26 Sep 2022 12:36:03 PM UTC] Add '--force' to force to renew.
[Mon 26 Sep 2022 12:36:04 PM UTC] Installing key to:/shared/ssl/www.starzen.space_ecc.key
[Mon 26 Sep 2022 12:36:04 PM UTC] Installing full chain to:/shared/ssl/www.starzen.space_ecc.cer
[Mon 26 Sep 2022 12:36:04 PM UTC] Run reload cmd: sv reload nginx
ok: run: nginx: (pid 2970) 331s
[Mon 26 Sep 2022 12:36:04 PM UTC] Reload success

مما لا يزال يبدو أنه كشف عن شهادة بنطاق واحد…

true | openssl s_client -connect www.starzen.space:443 2>/dev/null \
| openssl x509 -noout -text \
| perl -l -0777 -ne '@names=/\\bDNS:([^\\s,]+)/g; print join("\\n", sort @names);'
www.starzen.space
إعجاب واحد (1)