docker-mailserverでメールサーバー構築(24/6/12:rspamd追記)
独自ドメインにメールも統合しようと思ったのでdocker-mailserverを使用してVPSにメールサーバーを構築しました。
docker-mailserverを使うとPostfixとDovecotでサクッとメールサーバーが構築できます。
送信にはリレーサーバーを使用、また受信ガイドラインの厳しくなったGmailでも受信できるようにdocker-mailserver+CloudflareでDKIM,DMARC,SPFの設定を行います。
元々example.comドメインを使用している前提で[email protected]のメアドを作る感じで説明を入れていきます。
証明書の取得
IMAP,SMTPサーバーを作成するのでmail.example.com
の証明書をLet’s encryptで取得しておきます。
Nginxを使用している場合一度止めてスタンドアロンでサクッと取得
sudo systemctl stop nginx sudo certbot certonly --standalone -d mail.example.com sudo systemctl start nginx
またメールサーバーのAコードとMXレコードをDNS設定しておきます。
CloudflareのDNS設定でタイプ:MX、名前:example.com、コンテンツ:mail.example.comを登録します。
docker-mailserver導入
導入
早速サーバー(Ubuntu)上にgithubからcloneして導入します。導入時点の最新バージョンはv13.3.1でした。
git clone https://github.com/docker-mailserver/docker-mailserver.git cd docker-mailserver
公式ドキュメントを読みつつ設定していきます。
必要ファイルをダウンロードします。
DMS_GITHUB_URL="https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master" wget "${DMS_GITHUB_URL}/compose.yaml" wget "${DMS_GITHUB_URL}/mailserver.env"
compose.yamlを編集します。メールサーバーのホストを入力します。
またletsencryptのSSL認証を使用するので←の付いている部分を追加します。
services: mailserver: image: ghcr.io/docker-mailserver/docker-mailserver:latest container_name: mailserver # Provide the FQDN of your mail server here (Your DNS MX record should point to this value) hostname: mail.example.com ←ここを編集 environment: - SSL_TYPE=letsencrypt ←ここを追加 env_file: mailserver.env # More information about the mail-server ports: # https://docker-mailserver.github.io/docker-mailserver/latest/config/security/understanding-the-ports/ ports: - "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead) - "143:143" # IMAP4 (explicit TLS => STARTTLS) - "465:465" # ESMTP (implicit TLS) - "587:587" # ESMTP (explicit TLS => STARTTLS) - "993:993" # IMAP4 (implicit TLS) volumes: - ./docker-data/dms/mail-data/:/var/mail/ - ./docker-data/dms/mail-state/:/var/mail-state/ - ./docker-data/dms/mail-logs/:/var/log/mail/ - ./docker-data/dms/config/:/tmp/docker-mailserver/ - /etc/localtime:/etc/localtime:ro - /etc/letsencrypt:/etc/letsencrypt ←ここを追加 // 以下略
mailserver.envを必要に応じて編集します。
送信にはリレーサーバーを使用するので末尾を編集してその設定を入れます。自分の場合はプロバイダメールを使用しています。例:リレーサーバー(プロバイダメール)のSMTPサーバー:mail.provider.ne.jp
# ----------------------------------------------- # --- Default Relay Host Section ---------------- # ----------------------------------------------- # Setup relaying all mail through a default relay host # # Set a default host to relay all mail through (optionally include a port) # Example: [mail.example.com]:587 DEFAULT_RELAY_HOST=[mail.provider.ne.jp]:465 ←リレーサーバーのホストとポート番号 # ----------------------------------------------- # --- Multi-Domain Relay Section ---------------- # ----------------------------------------------- # Setup relaying for multiple domains based on the domain name of the sender # optionally uses usernames and passwords in postfix-sasl-password.cf and relay host mappings in postfix-relaymap.cf # # Set a default host to relay mail through # Example: mail.example.com RELAY_HOST=mail.provider.ne.jp ←リレーサーバーのホスト # empty => 25 # default port to relay mail RELAY_PORT=465 ←リレーサーバーのポート番号 # ----------------------------------------------- # --- Relay Host Credentials Section ------------ # ----------------------------------------------- # Configure a relay user and password to use with RELAY_HOST / DEFAULT_RELAY_HOST # empty => no default [email protected] ←リレーサーバーのユーザー名 # empty => no default RELAY_PASSWORD=リレーサーバーのメールパスワード
リレーサーバのポート番号が465の場合、./docker-data/dms/config/postfix-main.cf
を新規作成して下記でpostfixのmain.cfをオーバーライドしてあげます。
smtp_tls_wrappermode = yes smtp_tls_security_level = encrypt
またmailserver.envではメールの最大受信サイズなど細かい設定や、fail2banやSpamAssasinといったスパム対策ツールなどの有効化もできるので必要に応じて設定していきます。公式ドキュメントに詳細があります。
設定が完了したらdockerコンテナを立ち上げます。
sudo docker compose up -d
ポート開放
ファイヤーウォール(ufw)のポートを開放します。常に暗号化したい場合143,587ポートは開放しなくて大丈夫です。
sudo ufw allow 25/tcp sudo ufw allow 143/tcp sudo ufw allow 465/tcp sudo ufw allow 587/tcp sudo ufw allow 993/tcp
メールアドレスの追加
dockerコマンドで簡単に追加できます。コマンド入力後パスワードを聞かれるので設定したいパスワードを入力します。
sudo docker exec -ti mailserver setup email add [email protected]
メールソフトの設定
ThunderbirdやSparkのようなメールソフトでアカウントを設定します。
メールアドレス、パスワードは先ほど作成したもの
IMAP,SMTPサーバー共に「mail.example.com」
IMAPポート993、SMTPポート465
他の手持ちのメアドから作ったメールアドレスに送信テストをしてみて受信の確認をしましょう。
受信が出来なかった場合DNS設定やポート開放状態を見直します。
DKIM,DMARC,SPFの設定
なりすまし防止のための送信ドメイン認証を設定します。Gmailなどは受信条件が厳しくなったため、色々とクリアしていないと正常に受信できません。
設定の仕方が公式ドキュメントに詳しく載っています。
DKIMの設定
送信メールに署名を行います。
DKIMのセットアップ
docker-mailserverではOpenDKIMがデフォルトで有効になっています。
dockerコマンドで下記を実行すると鍵が生成されます。
sudo docker exec -it mailserver setup config dkim
その後sudo docker compose stop && sudo docker compose up -d
で再起動した後から送信メールにDKIMの認証が付いた状態でメールが送信されるようになります。
Cloudflareの設定
./docker-mailserver/docker-data/dms/config/opendkim/keys/example.com
にmail.txtが生成されるので開いて確認します。下記のようになっている筈です。
mail._domainkey IN TXT ( "v=DKIM1; k=rsa; " "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQMMqhb1S52Rg7VFS3EC6JQIMxNDdiBmOKZvY5fiVtD3Z+yd9ZV+V8e4IARVoMXWcJWSR6xkloitzfrRtJRwOYvmrcgugOalkmM0V4Gy/2aXeamuiBuUc4esDQEI3egmtAsHcVY1XCoYfs+9VqoHEq3vdr3UQ8zP/l+FP5UfcaJFCK/ZllqcO2P1GjIDVSHLdPpRHbMP/tU1a9mNZ" "5QMZBJ/JuJK/s+2bp8gpxKn8rh1akSQjlynlV9NI+7J3CC7CUf3bGvoXIrb37C/lpJehS39KNtcGdaRufKauSfqx/7SxA0zyZC+r13f7ASbMaQFzm+/RRusTqozY/p/MsWx8QIDAQAB" ) ;
()の中身を""を外して結合してあげます。BASE64部分はそのままくっつけます。
v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqQMMqhb1S52Rg7VFS3EC6JQIMxNDdiBmOKZvY5fiVtD3Z+yd9ZV+V8e4IARVoMXWcJWSR6xkloitzfrRtJRwOYvmrcgugOalkmM0V4Gy/2aXeamuiBuUc4esDQEI3egmtAsHcVY1XCoYfs+9VqoHEq3vdr3UQ8zP/l+FP5UfcaJFCK/ZllqcO2P1GjIDVSHLdPpRHbMP/tU1a9mNZ5QMZBJ/JuJK/s+2bp8gpxKn8rh1akSQjlynlV9NI+7J3CC7CUf3bGvoXIrb37C/lpJehS39KNtcGdaRufKauSfqx/7SxA0zyZC+r13f7ASbMaQFzm+/RRusTqozY/p/MsWx8QIDAQAB
CloudflareのDNS設定画面を開き、レコードを追加します。
タイプ:TXT
名前:mail._domainkey.example.com
コンテンツ:先ほど編集したキー
設定後DNSが伝播するまでは~48時間程度かかるようです。DKIMチェッカーサイトがあるので自分のドメインとセレクター:mailで確認してみましょう。
SPFの設定
CloudflareのDNS設定画面のレコード追加で下記を登録します。
タイプ:TXT
名前:example.com
コンテンツ:
v=spf1 mx ~all
通常はこれだけでも送信はできるのですが、Gmailでスパム扱いされないようにする為には足りず、リレーサーバーのSPF設定を取り込む必要がありました。SPFチェッカーでリレーサーバーにしている自分のプロバイダのSPF設定(例ではprovider.ne.jp)を確認してincludeしました。
v=spf1 include:spf.provider.ne.jp ~all
DMARCの設定
自分のドメインから送信されたメールがDKIM署名に合わない場合に受信側がメールをどうするか等の設定です。
CloudflareのDNS設定画面で同様に入力するのですが、色々面倒なので、コンテンツ部分を自分はこちらのサイトで作成しました。
なりすましメールの対処について自分はq=rejectにしています。
タイプ:TXT
名前:_dmarc.example.com
コンテンツ:サイトで作成したキー
送信テスト
手持ちのGmailアドレス宛にメール送信をしてみて受信できるか確認します。
自分の場合:
メールがそもそも送信に失敗→「./docker-mailserver/docker-data/dms/mail-logs/mail.log」を確認。リレーサーバーの設定誤りで引っかかりました。
送信は完了したものの、リレーサーバーからのエラーメールによってDKIM等の設定が足りずにgmailに受け取って貰えないという内容のエラー→DKIM設定など見直し(DNS伝播に時間がかかった)
その後Gmailで受信できていたもののスパムに振り分けられていました。Gmail側でメールのソースを表示するとSPFの設定が足りないと出たので、自分のSPFにリレーサーバーのSPFをincludeしてようやく正常受信までこぎ着けました。
rspamdの導入(24/6/12追加)
一通り出来たので今度はrspamdを導入します。
導入
rspamdのweb UIが11334ポートで使用できるのでcompose.yamlにポートを追記しておきます。
ports: - "25:25" # SMTP (explicit TLS => STARTTLS, Authentication is DISABLED => use port 465/587 instead) - "465:465" # ESMTP (implicit TLS) - "993:993" # IMAP4 (implicit TLS) - "11334:11334" # rspamd web UI ←追加
ufwのポート開放もしておきます。自分はアクセスポートは変えてnginxで11334ポートに飛ばしているのでアクセス用のポートだけ自分のIP限定で開放しました。
mailserver.envを編集してrspamdやウイルスチェックのClamAVをオンにし、DKIM署名もrspamdに担当して貰うためにOpenDKIMなどをオフにします。
ENABLE_RSPAMD=1 ENABLE_CLAMAV=1 ENABLE_OPENDKIM=0 ENABLE_OPENDMARC=0 ENABLE_POLICYD_SPF=0 ENABLE_AMAVIS=0 ENABLE_SPAMASSASSIN=0 ENABLE_POSTGREY=0
dockerコンテナを再起動して有効化します。
DKIM設定
DKIMはrspamd用の鍵を生成してあげます。
sudo docker exec -it mailserver setup config dkim domain example.com
するとTXTレコードに入力する為のデータが表示されるのでcloudflareのDNS設定にコピペしてあげます。先述のmail._domainkey.example.comのコンテンツ部分です。
webUIの確認
webUIのパスワードを設定します。下記コマンドを実行するとパスワードが聞かれるので設定したいパスワードを入力します。パスワードのハッシュが生成されます。
sudo docker exec -it mailserver rspamadm pw
docker-data/dms/config/rspamdにcustom-commands.confというファイルを作成するとrspamdの設定を上書きできます。
set-option-for-controller password "ここにパスワードハッシュ"
上記を追記することでwebUIにパスワードでログインできます。
rspamdの確認
サーティーワンの会員登録完了がスパムマークを付けられていたのでrspamdのwebUIで見てみました。
内訳が見れるので確認してみます。
VIOLATED_DIRECT_SPF (3.5): SPFで送信元IPアドレスが許可されていないことを示しています。このメールの送信元IPが送信ドメインの許可リストに含まれていないため、高いスパムスコアがつけられています。
R_SPF_SOFTFAIL (2.5) [~all]: SPFレコードに「~all」(SoftFail)オプションが設定されているため、送信元IPが許可されていない可能性があるが、強制的に拒否はしない設定です。このため、スパムの可能性があると判定されます。
DMARC_NA (1) [31club.jp]: DMARCレコードが存在しないため、メールの整合性が検証できません。このため、スパムスコアが増加しています。
PHP_SCRIPT_ROOT (1): メール本文にPHPスクリプトのパスが含まれている可能性があります。これは、スパムメールがPHPスクリプトを利用している可能性があることを示唆しています。
こんな感じでスコアがプラスマイナスされ、最終的に一定値以上のスコアになるとスパムとして認識されます。はぇ~。
この他にフィルタを自分で追加したりもできるのでスパムを受信し始めたら設定してみたいです。
Gmailのようなエイリアス追加
gmailだと「[email protected]」「[email protected]」は「[email protected]」で受信できます。これと同様のことが行えます。
docker-mailserverではデフォルトで+区切りのエイリアスが有効になっています。特に設定しなくても+区切りでエイリアスの利用が出来ます。
また、これは記号を変更することもできます。「-」や「.」等にすると一見エイリアスとわかりづらくなるかも。
docker-data/dms/config/postfix-main.cf
とdocker-data/dms/config/dovecot.cf
に下記のコードを追記します。
recipient_delimiter = -
記述できたらdockerコンテナを再起動します。
おわりに
さくらのレンタルサーバーが今月末で契約終了なのにメールを移行するのをすっかり忘れていたので、大慌てでメールサーバーを立ち上げました。間に合って良かったです。メールサーバーについても勉強になりました。なりすまし防止ってこんなことしてるのね…。
独自ドメインのメールが使えるのも割と嬉しいです。Google workspace契約の方とかも見ていますがやっぱりVPS代だけで終わるので有り難いです。やったね🎉