Featured image of post docker-mailserver メールサーバの構築記録

docker-mailserver メールサーバの構築記録

本記事では docker-mailserver を使ってメールサーバを構築する方法を詳しく解説します。設定ファイル、Caddy によるTLS証明書の自動取得・管理、DNS、DKIM・SPFなど送信認証まで、完全な手順と注意点付きでご紹介します。

ある朝、目を覚ますと受信トレイに見慣れないメールが届いており、韓国から自分のメールアドレスでログインがあったと通知されていました。最初は誤検出かと思い気にしませんでしたが、その後も発信元IPが毎回異なるメールが継続的に届くようになり、さすがに問題が発生していると認識しました。対策を取らなければ、自分のメールアカウントが迷惑メール送信に悪用されかねません。そこで、すぐにドメインの MX、SPF、DMARCレコードを削除し、新しい解決策を探すことにしました。

もともとはパスワードを変更したかったのですが、大手中国プロバイダの管理画面ではパスワード変更の導線が非常に分かりづらく、結局見つけられませんでした。こんなことで手間取るくらいなら、いっそサービス自体を移行しようと思い、この構築記録を書くことにしました。

本記事では、防火壁ポートの解放から配信成功率の最適化まで、docker-mailserver を使ったメールサーバ構築の実体験をまとめています。これから構築される方の参考になれば幸いです。

docker-mailserver 構築前の準備

ファイアウォールの設定

まずはメールサーバに必要な主要ポート(25143465587993)をファイアウォールで開放します。OSやディストリビューションによって操作が異なりますが、例えば Ubuntu で UFW(Uncomplicated Firewall)を使う場合は以下の通りです。

1
2
3
4
5
ufw allow 25
ufw allow 143
ufw allow 465
ufw allow 587
ufw allow 993

なお、私の環境では UFW だけでなく、To Fix The Docker and UFW Security Flaw Without Disabling Iptables という設定を併用しています。Dockerコンテナのポートを外部公開する場合には追加の設定が必要です。

1
2
3
4
5
6
# メールサーバ用ポートの開放
ufw route allow proto tcp from any to any port 25
ufw route allow proto tcp from any to any port 143
ufw route allow proto tcp from any to any port 465
ufw route allow proto tcp from any to any port 587
ufw route allow proto tcp from any to any port 993

サーバの構築条件を確認する

多くの格安VPSなどでは、メールサーバ用途に適さない場合があります。世界中のメール大手プロバイダは、Spam 対策の一環として過去にスパム送信履歴のあるIPアドレスを大規模にブラックリスト化しています。もし自分のVPSに割り当てられたIPがすでにスパマーに利用されていたものだと、どれだけ設定してもリモートのメールサーバにメールが一切届きません。それに加え、VPS業者側でメール関連のポート自体を全て封鎖していることも珍しくありません。

以下のスクリプトで、自分のサーバがメールサーバ運用に適しているか、最低限の通信・受信条件を満たしているかを検査できます。

1
bash <(curl -sL IP.Check.Place)

メールサーバ構築不可例 メールサーバ構築可能例

上記チェックでサーバがメールサーバ用に適していない、またはポートが開放されていない場合は、潔くあきらめてよりクリーンで制限の少ないIPアドレスに乗り換えましょう。

構築手順

設定ファイルの取得

docker-mailserver で必須の設定ファイルは compose.yamlmailserver.env の2つです。以下で取得できます。

1
2
3
4
mkdir mailserver && cd mailserver
sudo apt install wget
wget -O compose.yaml "https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/compose.yaml"
wget -O mailserver.env "https://github.com/docker-mailserver/docker-mailserver/blob/master/mailserver.env"

必要に応じて各種設定を変更します。私のケースの例は以下です。

1
2
3
4
5
POSTMASTER_ADDRESS=webmaster@l3zc.com
TZ=Asia/Shanghai
SSL_TYPE=manual
SSL_CERT_PATH=/certs/cert.crt
SSL_KEY_PATH=/certs/cert.key

Caddy でTLS証明書の準備と自動管理1

すでに Caddy を導入済みのため、証明書の自動取得はCaddy側で完結させることにしました。公式ドキュメントに従い、Caddyfile にサブドメイン設定を追加すればCaddyが自動で証明書を更新・管理してくれます。

1
2
3
4
5
6
7
8
9
mail.example.com {
  tls internal {
    # これは内部用証明書を生成する設定です
    key_type rsa2048
  }

  # Optional, 証明書取得動作確認用レスポンス例
  respond "Hello DMS"
}

ただし、私の環境は少し特殊で、Caddy の自動取得機能ではなく Cloudflare Origin 証明書(15年有効なワイルドカード証明書)を使っています。この場合、Caddy は該当サブドメインに対して証明書ファイルがあれば新たに証明書を発行しません。そのため、Cloudflare Origin Certificate とCaddyによる証明書自動管理は基本的に併用できません。結局、dns.providers.cloudflare モジュールを追加し、Caddy でLet’s Encryptを使ったドメインごとの自動更新運用に切り替えました。手動管理が不要になるぶん心が軽くなります。

dns.providers.cloudflare 導入後のグローバル設定例:

1
2
3
{
        acme_dns cloudflare {API_KEY}
}

Caddy で取得・管理された証明書ディレクトリを docker-mailserver コンテナにボリュームマウントします。

1
2
volumes:
   - /home/user/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.tld/:/certs/

Caddy を root 権限で動かす場合、証明書の格納先は /root/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/yourdomain.tld/ となります。環境に合わせてパスを調整してください。

設定ファイルでも /certs/ ディレクトリ以下を参照するよう指定します。

1
2
SSL_CERT_PATH=/certs/cert.crt
SSL_KEY_PATH=/certs/cert.key

初回コンテナ起動

最初のコンテナ起動時、すぐ(120秒以内)に新しいPostmasterアカウントを作成する必要があります。

1
2
docker compose up -d
docker exec -it <CONTAINER NAME> setup email add <postmaster@yourdomain.tld>

配信成功率の最適化

DNSレコード設定

  • Aレコード1つ:名前は任意(以下では仮にmail)、サーバのグローバルIPを指定(Cloudflare利用時は「DNSのみ」運用推奨)
  • MXレコード1つ:Apex ドメイン(@)に対し、mail.yourdomain.tld を宛先に
  • TXTレコード(SPF):Apex ドメイン(@)用、こちらで生成可能(任意)
  • TXTレコード(DMARC):名前_dmarcこちらで生成可能(任意)
  • TXTレコード(DKIM):名前mail._domainkey、設定手順は後述(任意)

DKIM・SPF・DMARC の設定2

DKIM・SPF・DMARCとは何か、簡単に言えば以下の通りです:
DKIMはデジタル署名方式、SPFは「正規送信サーバ一覧」として働きます。DMARCはDKIM・SPFでの認証に失敗したメールを受信側がどう扱うかを定義する規格です。3

まずDKIMの鍵ペアをサーバで生成します。

1
docker exec -it <CONTAINER NAME> setup config dkim

生成された鍵のペアは、コンテナのボリューム ./docker-data/dms/config/opendkim/keys/ 以下に保存されます。

mail.txt が公開鍵情報 (DNS Zoneファイル形式) Cloudflareでのインポート画面

mail.txt をダウンロード(または内容を全てコピー&ローカル保存)し、Cloudflareのダッシュボード等にインポートすればDKIM設定は完了です。なお、反映にはコンテナの再起動が必要です。4

1
docker compose up -d --force-recreate

SPFについては、「送信許可リスト」なので、正規送信サーバが1台だけの場合、DNSには以下のように設定します。

1
"v=spf1 mx ~all"

DMARCは前述のテンプレートジェネレーター等を使って作成します。

ドメインレジストラやDNSプロバイダが独自のガイドやインポート機能を提供している場合(例: Cloudflare)、それを活用するとより簡単に設定できます。

メールクライアントの設定

あとはご利用のメールクライアントにて、IMAP/SMTPサーバ共に mail.yourdomain.ltd を指定し、「SSLあり」でIMAP:993、SMTP:465ポートを使ってログインすれば利用できます。

設定例

MailTester を活用する

これでdocker-mailserverによるメールサーバの一連の構築は完了です。運用前に MailTester で設定全体が正しいかをチェックできます。10/10 のスコアが出れば、配信到達率も非常に高くなります。ぜひご利用ください。

パーフェクトスコア例

スコアが10/10でなくても、減点理由ごとに順番に対処していけば段階的に改善できます。焦らず原因を一つ一つ解消しましょう。

TODO-List

  • WebUI 対応
本ウェブページの日本語版は、生成系大規模言語モデル(LLM)によって簡体字中国語版の内容を翻訳したものです。その内容は「乱筆」による確認、校正および承認を経ておりません。ご利用の際には、いかなる場合でも本日本語版を簡体字中国語版または英語版と同等と見なさないようご注意ください。
Hugo で構築されています。
テーマ StackJimmy によって設計されています。