Configura Let's Encrypt con più domini / reindirizzamenti

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 Mi Piace

Grazie, questo funziona per reindirizzare “www.example.com” a “comunnity.example.com”?
O come posso farlo?
Ho problemi con il mio dominio www.example.com, ho configurato il DNS per reindirizzare a comunnity.example.com ma non funziona su Firefox o Chrome.

2 Mi Piace

C’è uno strumento per il controllo dei reindirizzamenti per controllare i tuoi reindirizzamenti.

5 Mi Piace

Ho un po’ di difficoltà con questo. OK, parecchia.

Ho deciso di sperimentare aggiungendo una CDN a uno dei miei siti.

Dopo aver letto la documentazione, mi sono reso conto che era meglio per il mio sito spostarsi da un dominio apex al suo sottodominio attuale per soddisfare i criteri raccomandati da Fastly (e il consiglio generale di farlo).

Quindi ho pensato: “meh, sarà una passeggiata, l’ho già fatto prima…” oh davvero?! :sweat_smile:

Il sito in questione è https://starzen.space.

L’ho spostato questo fine settimana su https://www.starzen.space usando la guida qui

Tutto è andato bene, MA ovviamente devo ancora considerare la piccola quantità di utenti che ho finora raccolto su questo sito, quindi ho voluto aggiungere un reindirizzamento.

Per quanto ne so, devo anche fornire il link originale con un certificato, quindi seguendo questa guida (che una volta era molto più complessa?) ho aggiunto questo ad 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;
          }

Dopo una ricostruzione, tutto sembra andare bene.

Tuttavia, se provo ad accedere a https://starzen.space tramite browser, ottengo:

E se faccio 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.

Sono abbastanza sicuro che sia il certificato il colpevole, perché se eseguo la stessa cosa in modalità insicura ottengo:

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

301 Moved Permanently
301 Moved Permanently
nginx/1.21.6

che credo sia quello che voglio.

Penso che il file script modificato sia corretto, ecco cosa ho:

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>

Ho persino eseguito questo dalla riga di comando all’interno del container, prima di aver spostato TUTTI i file di certificato dalla directory di destinazione in una directory di backup in modo che venga eseguito il comando corretto per il doppio dominio:

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

Per lo più un grande successo!!!, curl è molto più gentile ora e mi dà il reindirizzamento:

blah discourse % curl https://starzen.space

301 Moved Permanently
301 Moved Permanently
nginx/1.21.6

E https://starzen.space in Firefox e Chrome ora funziona, reindirizzando al sottodominio corretto, ma sto ancora ottenendo il temuto grafico del terrore in Safari, cosa succede? Ho persino riavviato e svuotato la cache per questo sito:

Guardando il certificato dal browser, vedo:

1 Mi Piace

Ho intenzione di dare un’occhiata più da vicino a questo. Penso che ora ci siano due punti nel template di Let’s Encrypt in cui deve essere inserito il dominio aggiuntivo. Non penso che tu debba apportare modifiche alle cose di nginx perché sta già facendo il 301 a tutto ciò che non è il nome host.

Quello che devi fare è guardare il template di Let’s Encrypt e vedere dove sta inserendo il nome host e assicurarti che tu lo stia facendo anche con il nome host aggiuntivo.

3 Mi Piace

Sì, grazie, l’ho fatto per completezza e non sembra esserci ancora alcun danno, ma sono felice di ricostruirlo senza in una fase successiva.

Ci sono due set di file crittografici?:

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#

Ah, potrebbe essere qui (e sotto)

Include solo informazioni per il nome host, non per l’apex?

1 Mi Piace

No, penso che questo sia corretto? Dovrebbe esserci un certificato e dovrebbe funzionare sia per www. che per apex.

Questo strumento suggerisce che ci sia un solo dominio sul mio certificato pubblico (che sarebbe la fonte del problema?):

1 Mi Piace

Devi cambiare la parte di Let’s Encrypt che ottiene il certificato. Deve richiedere il singolo certificato per entrambi i domini. Queste istruzioni funzionavano, ma qualcosa è cambiato nel modo in cui viene richiesto il certificato, credo. Se ottiene il certificato giusto, allora tutto il resto funziona.

1 Mi Piace

Se esegui certbot certificates verranno visualizzati i tuoi certificati e i domini che coprono. Se non copre sia l’apice sia www, puoi

  1. eseguire nuovamente certbot e farlo creare un certificato sia per l’apice sia per www;

Se scegli questa opzione, esegui certbot certificates per ottenere il nome del certificato che desideri eliminare. Esegui certbot delete (nome del certificato che desideri eliminare). Dovresti rimanere solo con il tuo nuovo certificato (con sia l’apice sia www).

o (più facile)

  1. esegui `certbot --expand -d existing.domain -d added.domain

Questo aggiornerà il tuo certificato con un nuovo certificato contenente il dominio originale e quelli che aggiungi con il flag -d.

2 Mi Piace

Jim, comando certbot non trovato? fa parte dell’installazione standard e c’è solo un problema di percorso?

1 Mi Piace

Senza guardare davvero… penso che certbot sia quello che usi normalmente, ma all’interno del container discourse usava acme.

E anche in relazione, ci stai provando dall’interno o dall’esterno del container?

(Inoltre la mia giornata si sta riempiendo e potrei non essere in grado di esaminare questo attentamente come pensavo una volta, ma è stato nella mia lista)

3 Mi Piace

Concordo… un modo per farlo, credo, è questo?:

Se uso da qualsiasi riga di comando Linux adatta

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);'

ottengo solo un dominio e manca l’apice.

1 Mi Piace

All’interno del container trovi il codice che richiede (e rinnova?) il certificato e vedi che lo sta richiedendo per entrambi i domini.

1 Mi Piace

Sì, lo è, come da:\n\n\nLE_WORKING_DIR=\"${LETSENCRYPT_DIR}\" /shared/letsencrypt/acme.sh --issue $2 -d www.starzen.space -d starzen.space --keylength\n\n\nE puoi vederlo nell’output del log sopra.\n\nTuttavia, ci sono alcuni altri passaggi di installazione del certificato che includono solo -d www.starzen.space, il che potrebbe essere un problema? Anche se se questo certificato è creato per entrambi, forse non è questo il problema…

1 Mi Piace

È quello che ho cercato di dire. Sembra che tu debba aggiornare anche quelli. Non sono sicuro del perché ora ce ne siano più di uno, ma l’OP deve essere aggiornato con il codice per modificare tutti quei passaggi. O almeno così credo.

4 Mi Piace

Sì, ci proverò, all’inizio manualmente

2 Mi Piace

Bene. Era quello che stavo per fare. Forse ti ho ingannato per farlo. :winking_face_with_tongue:

1 Mi Piace

È sensato provarci, solo che potrei dover ricostruire il container per installare nano… :sweat_smile:

1 Mi Piace

No!

 apt-get uodate;apt-get install nano

Puoi semplicemente eseguirlo all’interno del container. Lo faccio sempre (tranne che uso vim)

3 Mi Piace

Purtroppo non ha funzionato:

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

Il che sembra ancora aver esposto un certificato con un singolo dominio…

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 Mi Piace