複数ドメイン / リダイレクトで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」にリダイレクトしましたが、FirefoxやChromeで機能しません。

「いいね!」 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

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

nginx/1.21.6

そして、Firefox と Chrome での https://starzen.space は、正しいサブドメインにリダイレクトされ、機能するようになりましたが、Safari ではまだ「死のグラフィック」が表示されます。どうしたのでしょう?再起動し、このサイトのキャッシュをクリアしました。

ブラウザから証明書を確認すると、次のようになっています。

「いいね!」 1

これを詳しく見てみたいと思っていました。Let’s Encrypt のテンプレートには、追加のドメインを入力する必要がある箇所が 2 つあると思います。Nginx の設定は、ホスト名以外はすべて 301 リダイレクトしているので、変更する必要はないと思います。

やるべきことは、Let’s Encrypt のテンプレートを見て、ホスト名がどこに入力されているかを確認し、追加のホスト名でも同様に入力されていることを確認することです。

「いいね!」 3

はい、ありがとうございます。完全性のためにそうしましたが、後で削除しても問題ないようです。

暗号化ファイルが2セットあるようですが?

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

いいえ、これで正しいと思います。証明書は1つで、www.とapexの両方で機能するはずです。

このツールは、パブリック証明書にドメインが1つしかないことを示唆しています(これが問題の原因でしょうか?):

「いいね!」 1

証明書を取得する Let’s Encrypt の部分を変更する必要があります。両方のドメインに対して単一の証明書を要求する必要があります。これらの手順は以前は機能していましたが、証明書の要求方法が変更されたと思います。正しい証明書を取得できれば、他のすべては問題なく機能します。

「いいね!」 1

certbot certificates を実行すると、証明書とその証明書がカバーするドメインが表示されます。もし、ルートドメインと www の両方をカバーしていない場合は、以下のいずれかの方法をとることができます。

  1. certbot を再度実行し、ルートドメインと www の両方の証明書を作成します。

このオプションを選択した場合、certbot certificates を実行して削除したい証明書の名前を取得します。次に certbot delete (削除したい証明書の証明書名) を実行します。これにより、新しい証明書(ルートドメインと www の両方を含む)だけが残るはずです。

または(最も簡単な方法)

  1. certbot --expand -d existing.domain -d added.domain を実行します。

これにより、元のドメインと -d フラグで追加したドメインを含む新しい証明書で、証明書が更新されます。

「いいね!」 2

Jim、certbot コマンドが見つかりませんか?これは標準インストールの一部で、パスの問題だけですか?

「いいね!」 1

実際には見ていませんが…通常はcertbotを使用すると思いますが、コンテナ内ではacmeを使用していると思います。

また、関連して、コンテナの内側で試していますか、それとも外側で試していますか?

(また、私の日は忙しくなってきており、以前考えていたほど注意深く見ることができないかもしれませんが、リストには載っています)

「いいね!」 3

同意します…それを行う1つの方法を以下に示します。

適切なLinuxコマンドラインから以下を実行した場合:

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

ドメインが1つしか取得されず、ルートドメインが欠落しています。

「いいね!」 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