CloudFlare 使用例
この手順は、Cloudflare プロキシを使用しているセルフホスト型 Discourse フォーラム向けです。
Cloudflare プロキシを使用すると、SMTP (ポート 25) トラフィックがサーバーに到達するのをすべて防ぎます。そのため、メールレシーバーを機能させるには、別のサブドメインを設定する必要があります。
たとえば、ドメインが forums.domain.tld の場合、mail.domain.tld のような新しいサブドメインを作成する必要があります。
Cloudflare を使用する場合、以下の追加手順が必要です。
- 新しいサブドメインの A レコードを作成します。これは、
forums.domain.tldと同じ IP アドレスを使用します。 - メインの手順で提供されているように、新しいサブドメインの MX レコードを作成します。
このわずかな変更を加えて、メインの手順に従ってください。TLS セキュリティをオフにしても、すべて正常に機能します。
TLS セキュリティを実行したい場合は、追加の作業が必要になります。
TLS セットアップの概要
これらの手順では、Certbot と CloudFlare Certbot プラグインをインストールします。コマンドは、DNS 証明書プロセスによるスタンドアロンで Let’s Encrypt 証明書を取得します。証明書が利用可能になったら、コンテナが使用できるようにメールレシーバーの共有領域にコピーされます。Discourse はすでにポート 80 を使用しているため、DNS モデルを使用する必要があります。
DNS チャレンジ
証明書の所有権を HTTP 経由で証明する代わりに、certbot はDNS に TXT レコードを作成することによって証明します。DNS が Cloudflare であるため、Cloudflare API トークンを使用して完全に自動化できます。ポート 80 は不要で、Web サーバーをシャットダウンする必要もありません。
仕組み
Certbot → Cloudflare に _acme-challenge.mail.lotuselan.net TXT レコードを作成
Let's Encrypt → その TXT レコードをルックアップ → 検証 → 証明書を発行
Certbot → TXT レコードを削除
これらはすべて、Discourse コンテナ内ではなく、ベースサーバー上で行われます。
セットアップ
1 — certbot と Cloudflare certbot プラグインをインストールします。
bash
apt install certbot python3-certbot-dns-cloudflare -y
2 — Cloudflare API トークンを作成します。
- Cloudflare → マイプロフィール → API トークン → トークンの作成に移動します
- **「ゾーン DNS の編集」**テンプレートを使用します
- 権限:
ゾーン → DNS → 編集 - ゾーンリソース:
含める → 特定のゾーン → lotuselan.net - IP 制限: サーバーの IP アドレスからのアクセスのみを許可するように設定します
- トークンをコピーします
3 — トークンを資格情報ファイルに保存します。
bash
mkdir -p /etc/letsencrypt/cloudflare
nano /etc/letsencrypt/cloudflare/credentials.ini
貼り付け:
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN
ファイルをロックダウンします:
bash
chmod 600 /etc/letsencrypt/cloudflare/credentials.ini
4 — 証明書をリクエストします:
以下のコマンドを管理者メールアドレスとドメイン名で更新します。
bash
certbot certonly \
--dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
--non-interactive \
--agree-tos \
--email youremailadress@domain.tld \
-d mail.domain.tld
結果に、次のステートメントが表示されるはずです。
Certbot has set up a scheduled task to automatically renew this certificate in the background.
Certbot は、証明書の有効期限を 1 日に 2 回チェックするための cron ジョブを設定します。有効期限が 30 日以内の場合、証明書を更新します。これは、次のように検証できます。
# systemd タイマーがアクティブかどうかを確認します (ほとんどの最新の Ubuntu システム)
systemctl status certbot.timer
# または、cron ジョブが追加されたかを確認します
cat /etc/cron.d/certbot
これで、新しいメールレシーバードメイン名の TLS 証明書がサーバーに配置されました。それらは使用できる場所にはありません。
5 — ファイルを移動するためのデプロイスクリプトを設定します
certbot は自動更新を行うため、Discourse 固有の部分のみを処理するスクリプトが必要になります。更新された証明書をコピーし、メールレシーバーを再構築します。certbot の組み込みのデプロイフックを使用すると、スクリプトを大幅に簡素化できます。これは、正常な更新の後に自動的に実行されます。
デプロイフックファイルを作成します:
bash
nano /etc/letsencrypt/renewal-hooks/deploy/mail-receiver-deploy.sh
chmod +x /etc/letsencrypt/renewal-hooks/deploy/mail-receiver-deploy.sh
これを貼り付けます:
bash
#!/bin/bash
DOMAIN="mail.domain.tld"
DISCOURSE_DIR="/var/discourse"
CERT_SRC="/etc/letsencrypt/live/${DOMAIN}"
CERT_DEST_1="${DISCOURSE_DIR}/shared/mail-receiver/letsencrypt/${DOMAIN}"
CERT_DEST_2="${DISCOURSE_DIR}/shared/mail-receiver/letsencrypt/${DOMAIN}_ecc"
ADMIN_EMAIL="admin email address"
LOG_FILE="/var/log/mail-cert-renewal.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}
log "=== Certbot deploy hook triggered for ${DOMAIN} ==="
# 証明書をコピーします (シンボリックリンクを解決するには -L を使用)
for DEST in "$CERT_DEST_1" "$CERT_DEST_2"; do
mkdir -p "$DEST"
cp -L "${CERT_SRC}/fullchain.pem" "${DEST}/fullchain.pem"
cp -L "${CERT_SRC}/privkey.pem" "${DEST}/privkey.pem"
cp -L "${CERT_SRC}/cert.pem" "${DEST}/cert.pem"
cp -L "${CERT_SRC}/chain.pem" "${DEST}/chain.pem"
chmod 644 "${DEST}/fullchain.pem" "${DEST}/cert.pem" "${DEST}/chain.pem"
chmod 600 "${DEST}/privkey.pem"
log "Certs copied to ${DEST}"
done
# mail-receiver を再構築します
cd "$DISCOURSE_DIR" || { echo "Cannot cd to ${DISCOURSE_DIR}" | mail -s "[FAILURE] Mail cert deploy hook failed" "$ADMIN_EMAIL"; exit 1; }
log "Rebuilding mail-receiver..."
if ./launcher rebuild mail-receiver >> "$LOG_FILE" 2>&1; then
log "mail-receiver rebuilt successfully"
else
log "ERROR: rebuild failed"
echo "mail-receiver rebuild failed after cert renewal. Check ${LOG_FILE}" | \
mail -s "[FAILURE] Mail cert deploy hook failed" "$ADMIN_EMAIL"
exit 1
fi
log "=== Deploy hook completed successfully ==="
手動での cron ジョブはまったく必要ありません。certbot がプロセス全体をオーケストレーションします。デプロイフックは更新が発生した場合にのみトリガーされるため、certbot がチェックしても更新が行われない日には、メールレシーバーが不要に再構築されることはありません。
更新フックをテストするには、以下を実行します。
bash
bash /etc/letsencrypt/renewal-hooks/deploy/mail-receiver-deploy.sh
すべてが正しく設定されていれば、これは
→ 証明書を Discourse ディレクトリにコピーします
→ mail-receiver を再構築します
→ すべてをログに記録します
6 — mail-receiver.yml で TLS を設定します