自己ホスト型サイトのMail-Receiverでダイレクトデリバリー受信メールを設定する

CloudFlare 使用例

この手順は、Cloudflare プロキシを使用しているセルフホスト型 Discourse フォーラム向けです。

Cloudflare プロキシを使用すると、SMTP (ポート 25) トラフィックがサーバーに到達するのをすべて防ぎます。そのため、メールレシーバーを機能させるには、別のサブドメインを設定する必要があります。

たとえば、ドメインが forums.domain.tld の場合、mail.domain.tld のような新しいサブドメインを作成する必要があります。

Cloudflare を使用する場合、以下の追加手順が必要です。

  1. 新しいサブドメインの A レコードを作成します。これは、forums.domain.tld と同じ IP アドレスを使用します。
  2. メインの手順で提供されているように、新しいサブドメインの 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 トークンを作成します。

  1. Cloudflare → マイプロフィール → API トークン → トークンの作成に移動します
  2. **「ゾーン DNS の編集」**テンプレートを使用します
  3. 権限: ゾーン → DNS → 編集
  4. ゾーンリソース: 含める → 特定のゾーン → lotuselan.net
  5. IP 制限: サーバーの IP アドレスからのアクセスのみを許可するように設定します
  6. トークンをコピーします

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 を設定します