Discourse + Let's Encryptを複数のホスト名で利用

Discourse をバックアップ経由で別のホスト名から別のホスト名へ移行する際、管理者は古いホスト名を維持しつつ、Web サーバーがリクエストを新しい正規名に書き換えるように設定したい場合があります。例えば:

https://old.example.org/t/my-great-topic/12345 :arrow_heading_down:
https://new.example.org/t/my-great-topic/12345

残念ながら、これは DNS の CNAME または A レコードを変更するだけでは簡単にはいきません。ブラウザクライアントは、Discourse インストールにより Let’s Encrypt 経由で生成された証明書とホスト名が一致しないため、エラーや警告を生成してしまいます。

手動で Web サーバーをインストールする場合、certbotユーティリティを使用して、複数の名前が割り当てられた証明書を生成 します。しかし、Discourse の設定では、Let’s Encrypt に Discourse ホスト名(のみ)が渡され、設定内にエイリアスの概念は見当たりません。

このような構成を設定した方や、最適な実現方法について見当がつく方はいますか? SSL および Let’s Encrypt のテンプレートを何らかの形で改変する必要があると予想されます。

「いいね!」 2

Discourse固有の話ではありませんが、HTTPS経由でリダイレクトが必要な場合は、すべてをリダイレクトしています。つまり、古いアドレスから新しいアドレスへのリダイレクトを行うサーバーを設けるということです。一部のホスティングオプションでは、これが裏側で処理され、「ドメインリダイレクト」や「フォワーディング」サービスと呼ばれることもあります。

他の方法を試した際に毎回非常に手間がかかるため、今ではこれについて考えることすらありません。:thinking:

「いいね!」 2

Discourse は 1 つのホスト名にのみ応答します。複数のホスト名を使用したい場合(あなたのユースケースである、以前のホスト名のサポートが最も一般的なケースの場合)、一方をもう一方にリダイレクトする必要があります。

その設定は Discourse 外で行うことをお勧めします。独自の証明書を持ち、旧ホスト名を server_name として設定し、すべてのリクエストを新ホスト名にリダイレクトする nginx 設定を作成してください。

「いいね!」 3

実際、サーバーあたり単一インスタンスの Docker ベースのインストールを使用している場合、nginx はすべてのホスト名のポート 80 および 443 でリッスンしており、任意の数の DNS エントリにも問題なく応答します。さらに、URL を正規の「新しい」ホスト名に正しく書き換えることも問題なく動作します。この部分はスムーズに機能しています。(これを試してみたい方は、お使いの機械の localhost ファイルに架空のドメイン名を追加し、お好みの Discourse サイトの IP アドレスを指すように設定してみてください。)

私が直面している唯一の問題は SSL の警告です。nginx からの書き換え応答が https://old.example.org/foo であり、新しい URL への HTTP 302 リダイレクトを送信するためです。

可能であれば、書き換えルールを実行するために別の Web サーバーを維持したくありません。:slight_smile:

「いいね!」 1

必要ありません。設定に追加の server セクションを追加するだけです。

「いいね!」 2

Set up Let’s Encrypt with multiple domains / redirects をご覧ください。

「いいね!」 2

更新: スタンドアロンインストールでセカンダリドメイン名を正常に設定し、旧名と新名の両方を処理する Let’s Encrypt 証明書を発行しました。

前提条件: DNS を新しいサイトへ切り替える前に、まず確実に動作することを確認したいため、まだ DNS の変更は行いませんでした。そのため、テストマシンでは localhost エントリを使用していました。これにより通常の Let’s Encrypt 検証が不可能となり、代わりに自動更新が一般的に推奨されない acme.sh の「DNS」メソッドを使用する必要がありました。これは私にとって問題ありません。なぜなら、「初期」(新しく発行された 2 ドメイン用) 証明書の 30 日間有効期限内に切り替える予定だからです。

  1. web_only.yml ファイル (app.yml を使用している場合もあります) の hooks: セクションで、プラグインの前に以下の記述を追加します:
  after_ssl:
    - replace:
        filename: "/etc/runit/1.d/letsencrypt"
        from: /--keylength/
        to: "-d second-domain.com --keylength"
  1. DNS で _acme-challenge.old.example.org に対して、5 分間の TTL を持つ架空の/一時的な TXT レコードを設定します (より短く設定することも可能かもしれません)。これを伝播させ、acme.sh (Let’s Encrypt) 検証キーで変更を素早く反映できるようにします。

  2. サイトを停止し、デバッグ (テスト) 検証を実行して、システムが新しいエントリの短い TTL を認識するようにします:

./launcher enter app
sv stop nginx
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf
LE_WORKING_DIR=/shared/letsencrypt DEBUG=1 /shared/letsencrypt/acme.sh --issue -d new.example.org -d old.example.org -k 4096 -w /var/www/discourse/public --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --force
  1. 今度はデバッグ設定を外して実際にリクエストを実行します。これにより、ステップ 2 で作成したエントリに DNS で使用する値を示す警告が表示されます:
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --issue -d new.example.org -d old.example.org -k 4096 -w /var/www/discourse/public --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --force
  1. DNS を更新し、5 分間待ちます。はい、Let’s Encrypt の制限に直面しないよう、その間ずっと待つ必要があります。

  2. 先ほどのコマンドと似たバージョンを renew モードで実行します:

LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --issue -d new.example.org -d old.example.org -k 4096 -w /var/www/discourse/public --dns --yes-I-know-dns-manual-mode-enough-go-ahead-please --force --renew
  1. 確認メッセージが表示されるはずです。以下を実行して整理し、新しい証明書を適用します:
LE_WORKING_DIR=/shared/letsencrypt /shared/letsencrypt/acme.sh --installcert -d new.example.org -d old.example.org --fullchainpath /shared/ssl/new.example.org.cer --keypath /shared/ssl/new.example.org.key --reloadcmd "sv reload nginx"
/usr/sbin/nginx -c /etc/nginx/letsencrypt.conf -s stop
exit
  1. ランチャーから抜けた後の最終ステップ:
rm -rf /var/discourse/shared/standalone/ssl
rm -rf /var/discourse/shared/standalone/letsencrypt
./launcher rebuild app

サイトが再び起動したら、新しい証明書で動作しているはずです。ブラウザの証明書ストアをクリアする必要があるかもしれませんが、これは読者およびお好みの検索エンジンへの課題として残します。

正しい方向へ導いてくれた方々に感謝します!

「いいね!」 2

これは Cloudflare ルールの完璧な適用例です。サーバー設定は不要で、新しいドメインに同じ URL パラメータを渡すだけです。

古いドメイン名では、オレンジ色のクラウドを有効にする必要があります。

「いいね!」 2

はい、Cloudflare のようなリバースプロキシ状況(あるいは Discourse サイトの前に設置するご自身のリバースプロキシ)であれば、「上位レベル」で書き換えルールを実装することで回避可能です。今回の場合、セキュリティと倫理上の理由から Cloudflare は選択肢に含まれていませんでした。:slight_smile:

(スタンドアロンの解決策については上記をご覧ください。)

「いいね!」 2

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.