Skip to main content

メールサーバー構築 トラブルシューティング記録

Author
blackratel

メールサーバー構築(Postfix / Dovecot / Roundcube / SpamAssassin)で発生したトラブルと解決策


1. Roundcube: Internal Error(INBOX が存在しない)
#

症状
ログインは成功するが画面に “Internal Error” が表示される。ブラウザの開発者ツールで確認したレスポンス:

"exec": "this.display_message(\"サーバーエラー: STATUS: Internal error occurred.\", \"error\", 0);"

原因
IMAP の STATUS コマンドが失敗。メール未受信のため Maildir の INBOX ディレクトリが存在しなかった。エラーログには何も出力されないため原因特定にブラウザの開発者ツールが必要だった。

解決策
Dovecot に INBOX 自動作成設定を追加した。初回ログイン時に INBOX ディレクトリが自動生成される。

# dovecot 10-mail.conf
namespace inbox {
  inbox = yes
  mailbox INBOX {
    auto = subscribe
  }
}

2. Postfix: 外部送信タイムアウト(OCI Free Tier)
#

症状

postfix/smtp: connect to gmail-smtp-in.l.google.com[...]:25: Connection timed out

原因
OCI Free Tier はアウトバウンド port 25 をブロックしている。

解決策
受信専用サーバーに方針変更。


3. SpamAssassin: content_filter ループ
#

症状
メール受信時に同一メッセージのログが大量に出力され続ける。

原因
Postfix の content_filter は「受信メールを外部プログラムに渡してスキャンし、処理後に Postfix へ戻す」機構。SpamAssassin はスキャン後に spamc -e sendmail でメールを Postfix に再投入するが、この経路を担当する pickup デーモンにも content_filter 設定が引き継がれているため、再投入メールが再び SpamAssassin に送られ無限ループが発生した。

# 正常系
smtpd → SpamAssassin → spamc -e sendmail → pickup → 配送

# ループ発生時
smtpd → SpamAssassin → spamc -e sendmail → pickup
                            content_filter が再適用される
                                          SpamAssassin
                                         spamc -e sendmail → pickup → ...(無限ループ)

解決策
master.cfpickup サービスに -o content_filter= を追加し、再投入メールへのフィルタ適用を無効化した。

pickup     unix  n       -       y       60      1       pickup
  -o content_filter=
  -o receive_override_options=no_header_body_checks
オプション 意味
-o content_filter= pickup 経由のメールは content_filter を空(無効)にする
-o receive_override_options=no_header_body_checks ヘッダ・本文の再チェックも無効化し、二重処理を防ぐ

pickup はローカルからの再投入専用デーモンなので、ここで content_filter を切っても外部着信メールには影響しない。smtpd 側の設定はそのまま有効なため、外部メールは引き続き SpamAssassin でスキャンされる。


4. SpamAssassin: Spamhaus ZEN ブロック
#

SpamAssassin の概要
#

SpamAssassin はメールをスコアリング方式でスパム判定するフィルタ。様々なルールを適用してスコアを合算し、閾値(デフォルト 5.0)を超えるとスパム判定する。

受信メール
ルール群を適用してスコア計算
    ├─ ヘッダチェック(From/Subject の怪しいパターン等)   +1.5
    ├─ 本文チェック(スパムっぽい文言等)                  +2.0
    ├─ DNSBL チェック ← 今回の問題箇所                    +3.0
    └─ SPF/DKIM チェック                                   -0.1
合計スコア ≥ 5.0 → スパム / < 5.0 → 正常メール

DNSBL とは
#

DNSBL(DNS Block List)は「スパム送信元として知られている IP アドレスのブラックリスト」を DNS で照合できる仕組み。SpamAssassin は受信メールの送信元 IP を DNSBL サーバに問い合わせ、リストに載っていればスコアを加算する。

# 照合の仕組み(送信元 IP: 1.2.3.4 の場合)
DNS クエリ: 4.3.2.1.zen.spamhaus.org
    ├─ 応答あり → リストに載っている → スコア加算(スパム寄り)
    └─ NXDOMAIN → リストにない → スコア変動なし

Spamhaus ZEN とは
#

Spamhaus が提供する複数のブロックリストを統合した DNSBL。

リスト 対象
SBL 確認済みスパム送信者の IP
XBL マルウェア・ボットネットに乗っ取られた IP
PBL ISP が「メール送信に使うべきでない」と申告した IP(住宅向け回線等)

ZEN はこれら全てをまとめて一度に照合できるリスト。


症状

dns_block_rule RCVD_IN_ZEN_BLOCKED hit
(This means DNSBL blocked you due to too many queries)

原因
Spamhaus ZEN は本来「受信メールの送信元 IP」を照合するサービスだが、クエリ自体の送信元(=自サーバーの IP)もチェックしている。Spamhaus ZEN は無償利用に制限があり、OCI などクラウドプロバイダの IP からの DNS クエリをブロックする。受信メールの内容や送信元 IP とは無関係で、クエリを送る自サーバーの IP が原因。

通常の利用(ISP 等)
    自サーバー(IP: A) → DNS クエリ → Spamhaus ZEN
    「受信メールの送信元 IP: X がリストに載っているか?」

OCI 環境で起きたこと
    自サーバー(OCI IP) → DNS クエリ → Spamhaus ZEN
                          「クエリ元 OCI の IP 自体がブロック対象」
                                    dns_block_rule ヒット

解決策
local.cf に Spamhaus ZEN への DNS クエリを無効化する設定を追加した。

dns_query_restriction deny zen.spamhaus.org

これにより SpamAssassin が zen.spamhaus.org へのクエリを送らなくなる。Spamhaus ZEN によるスコアリングは無効になるが、ヘッダ・本文・SPF/DKIM 等の他ルールは引き続き機能する。根本対応としては Spamhaus の有償ライセンス取得やローカルミラーの構築があるが、個人運用の受信専用サーバーであれば無効化で十分。