Postfixを運用していると、送信できなかったメールがキューに溜まることがあります。
例えば、
mailq
を実行すると、大量のメールが表示され、
status=deferred
となっているケースです。
このような場合、いきなりメールキューを削除するのではなく、
なぜメールが配送できずキューに残っているのか
を確認することが重要です。
メールキューは障害そのものではなく、配送できなかった結果だからです。
この記事では、Postfixでメールキューが溜まった場合に、キューの確認、原因調査、再送、削除を行う方法を紹介します。
Postfixのメールキューとは?
Postfixがメールを受け付けても、すぐに配送できない場合があります。
例えば、
Postfix
↓
メール送信
↓
相手メールサーバーへ接続
↓
一時的に配送できない
↓
メールキューへ保存
↓
後で再送
という動作をします。
そのため、メールがキューに入っていること自体は必ずしも異常ではありません。
一時的なネットワーク障害や相手メールサーバーの停止などでもキューに入ります。
問題なのは、
数通
↓
数十通
↓
数百通
↓
さらに増え続ける
という状態です。
この場合は配送障害が継続している可能性があるため、原因を調査します。
1. mailqでメールキューを確認する
まず、
mailq
を実行します。
Postfixでは、
postqueue -p
でもキューを確認できます。
例えば、次のような結果が表示されます。
A1B2C3D4E5 1234 Tue Sep 16 10:15:20
sender@example.jp
user@gmail.com
(connect to gmail-smtp-in.l.google.com[xxx.xxx.xxx.xxx]:25:
Connection timed out)
重要なのは、
A1B2C3D4E5
のような文字列です。
これは**Queue ID(キューID)**です。
特定のメールを詳しく調べたり削除したりするときに使用します。
2. キューの件数を確認する
キューが少ない場合はmailqをそのまま確認できますが、大量に溜まっている場合は件数を把握したくなります。
環境によっては、
mailq | tail
で最後の集計表示を確認できます。
例えば、
-- 250 Kbytes in 35 Requests.
なら、
35通
がキューに存在しています。
重要なのは単純な件数だけではありません。
例えば、
昨日 5通
今日 50通
1時間後 100通
のように増え続けているかも確認します。
3. Deferredになっている理由を見る
キューが溜まっていたら、次に配送できない理由を確認します。
Postfixでは配送が一時的に失敗すると、
status=deferred
となることがあります。
例えばログに、
status=deferred
(connect to mx.example.jp[192.0.2.10]:25:
Connection timed out)
とあれば、
相手メールサーバーへ
TCP/25で接続
↓
タイムアウト
↓
配送できない
↓
Deferred
と考えられます。
つまり、
Deferredそのものが原因ではありません。
その直前や括弧内に表示されている理由を確認します。
4. Postfixのログを確認する
メールキューだけでは原因が分からない場合、Postfixのログを確認します。
ログの場所はLinuxディストリビューションや設定によって異なりますが、例えば、
/var/log/maillog
や、
/var/log/mail.log
などです。
Queue IDが、
A1B2C3D4E5
なら、
grep A1B2C3D4E5 /var/log/maillog
のように検索します。
例えば、
postfix/smtp[12345]:
A1B2C3D4E5:
to=<user@example.jp>,
relay=none,
delay=120,
status=deferred
(connect to mx.example.jp[192.0.2.10]:25:
Connection timed out)
というログがあれば、
Queue ID
↓
宛先
↓
配送先
↓
配送結果
↓
失敗理由
を追うことができます。
5. postcatでキューのメールを確認する
特定のキューメールについて詳しく確認したい場合は、
postcat -q QUEUE_ID
を使用できます。
例えば、
postcat -q A1B2C3D4E5
です。
これにより、キューに保存されているメールの情報を確認できます。
調査では、
送信元
宛先
ヘッダー
配送情報
などが手掛かりになります。
ただし、メール本文には個人情報や機密情報が含まれる可能性があります。
業務環境では権限や組織の運用ルールを確認したうえで使用します。
6. 相手先が偏っていないか確認する
メールキューが大量にある場合、1通ずつ調べる前に共通点を探します。
例えば、
Gmail宛 100通
Yahoo宛 0通
社内宛 0通
その他 0通
なら、
Gmail宛だけ配送できていない
可能性があります。
反対に、
Gmail NG
Yahoo NG
Microsoft NG
その他 NG
なら、送信元メールサーバー側やネットワーク側を疑いやすくなります。
つまり、
キューが大量
↓
全部同じ障害?
↓
宛先ドメインを見る
↓
共通点を探す
という調査が有効です。
7. DNSを確認する
Postfixが外部メールサーバーへ直接配送している場合、DNSも重要です。
例えばexample.jp宛メールなら、
dig example.jp MX
を確認します。
nslookupなら、
nslookup -type=MX example.jp
でも確認できます。
MXレコードが、
10 mx.example.jp.
なら、続いて、
dig mx.example.jp A
などで配送先メールサーバーのIPアドレスを確認します。
DNSでMXを正常に解決できなければ、Postfixが配送先を特定できません。
8. TCP/25で接続できるか確認する
外部へ直接SMTP配送している環境では、相手メールサーバーのTCP/25へ接続できるか確認することもあります。
例えば、
nc -vz mx.example.jp 25
などです。
接続できない場合は、
Firewall
ルーター
ISP
上位ネットワーク
相手メールサーバー
などを調査します。
特定の宛先だけ接続できないのか、
Gmail NG
Yahoo OK
Microsoft OK
なのか、
すべて、
Gmail NG
Yahoo NG
Microsoft NG
なのかでも原因の範囲が変わります。
9. メールサーバー自身のDNSも確認する
Postfixが使用しているDNSサーバーに問題がある場合もあります。
例えば、
cat /etc/resolv.conf
でDNS設定を確認します。
さらに、
dig gmail.com MX
など、実際に外部ドメインを引けるか確認します。
ここで、
一部ドメインだけ引けない
というケースにも注意します。
単純に、
google.comが引ける
↓
DNSは全部正常
とは限りません。
問題になっている配送先そのものを確認した方が確実です。
10. postqueue -fで再送する
原因を修正したあと、キューに残っているメールの配送を再試行できます。
postqueue -f
を実行します。
これはキューにあるメールについて配送を再試行させる操作です。
実行後、
mailq
を再度確認します。
例えば、
修正前
35通
postqueue -f
修正後
0通
となれば、配送できた可能性があります。
ただし、mailqが空になったことだけでなく、メールログで、
status=sent
になったことも確認すると確実です。
11. 原因を直す前に再送しても意味がない
例えば、
DNS障害
↓
配送先MXを解決できない
↓
メールキューに溜まる
という状態で、
postqueue -f
を実行しても、
再送
↓
DNS障害
↓
また失敗
↓
Deferred
となります。
そのため、
キュー発見
↓
すぐ再送
ではなく、
キュー発見
↓
失敗理由確認
↓
原因修正
↓
再送
という順番が重要です。
12. 特定のメールだけ削除する
不要なメールであることを確認したうえで、特定のQueue IDだけ削除したい場合は、
postsuper -d QUEUE_ID
を使用します。
例えば、
postsuper -d A1B2C3D4E5
です。
これなら対象のメールだけ削除できます。
削除後、
mailq
で確認します。
13. キューを全削除する方法
Postfixにはキューをまとめて削除する方法もあります。
例えば、
postsuper -d ALL
です。
ただし、これは非常に注意が必要です。
キューの中に、
正常な業務メール
重要な通知
ユーザーが再送を待っているメール
が含まれていても削除される可能性があります。
そのため、
「キューが大量に溜まっているから全部消す」
という使い方はおすすめしません。
まず配送できない原因を確認します。
14. Deferredメールだけを削除する場合
Postfixではdeferredキューを対象に削除する方法もあります。
postsuper -d ALL deferred
です。
これも大量のメールを削除する可能性があります。
したがって、
何通ある?
誰から?
誰宛?
なぜDeferred?
再送する必要はない?
を確認してから実行します。
15. キューが溜まる主な原因
メールキューが溜まる原因は一つではありません。
例えば、
| 症状・ログ | 確認するところ |
|---|---|
Connection timed out | NW・Firewall・TCP/25・相手サーバー |
Connection refused | 相手SMTP・接続先・ポート |
Host or domain name not found | DNS・MX |
Relay access denied | Postfixリレー設定 |
SASL authentication failed | SMTP認証 |
Network is unreachable | ルーティング・IPv4/IPv6 |
status=deferred | 直前の具体的な理由を確認 |
特に、
status=deferred
だけを検索するのではなく、その後ろにある、
(reason...)
を読むことが重要です。
16. IPv6が原因になるケースにも注意
環境によっては、配送先のIPv6アドレスへ接続しようとして失敗するケースもあります。
例えばログに、
Network is unreachable
と表示され、その宛先がIPv6アドレスだった場合です。
この場合、
Postfix
↓
AAAAレコード取得
↓
IPv6へ接続
↓
サーバーにIPv6経路がない
↓
失敗
という可能性があります。
ただし、
IPv6で失敗したから、すぐIPv6を無効化する
のではなく、Postfixがその後IPv4で配送できているかなども含めて確認します。
17. キューが突然増えた場合は不正送信も確認する
これは重要です。
普段、
0~数通
しかないメールキューが突然、
数百通
数千通
になった場合は、単なる配送障害だけとは限りません。
例えば、
メールアカウントの不正利用
SMTP認証情報の漏えい
Webアプリからの不正送信
設定ミスによる大量送信
なども確認します。
この場合は、
送信元
宛先
時間帯
認証ユーザー
送信元IP
Queue ID
などをログから調査します。
大量キューを見つけたときは、「なぜ送れない?」だけでなく「なぜこんなに送信されている?」という視点も必要です。
私ならこの順番で調べる
Postfixでメールキューが溜まっていたら、次のように確認します。
メールが届かない
↓
mailq
↓
キューがある?
┌──┴──┐
NO YES
↓
件数確認
↓
Queue ID確認
↓
Deferred理由確認
↓
ログ確認
↓
宛先に共通点?
↓
┌───────┼────────┐
DNS NW 相手SMTP
│ │ │
└───────┴──────────┘
↓
原因修正
↓
postqueue -f
↓
mailq再確認
↓
status=sent確認
削除は、この流れとは別に考えます。
メールが不要と確認
↓
postsuper -d
です。
キューを消すことが「復旧」ではない
Postfixのメールキューが大量に溜まると、
postsuper -d ALL
で消したくなるかもしれません。
しかし、
キュー全削除
↓
mailq
↓
Mail queue is empty
となっても、配送障害の原因が残っていれば、
新しいメール
↓
配送失敗
↓
またキューに溜まる
だけです。
つまり、
メールキューを空にすることと、メール障害を直すことは別
です。
ここを切り分けて考えることが重要です。
まとめ
Postfixでメールキューが溜まった場合、まず、
mailq
または、
postqueue -p
で状態を確認します。
次に、
Queue ID
送信元
宛先
Deferredの理由
を確認し、必要ならメールログをQueue IDで検索します。
基本的な流れは、
mailq
↓
キュー確認
↓
失敗理由確認
↓
ログ確認
↓
DNS / NW / SMTP等を調査
↓
原因修正
↓
postqueue -f
↓
配送結果確認
です。
特定の不要なメールを削除する場合は、
postsuper -d QUEUE_ID
を使用できます。
しかし、
postsuper -d ALL
による全削除は、正常な業務メールまで削除する可能性があるため注意が必要です。
Postfixのメールキュートラブルでは、
「どうやってキューを消すか」より「なぜキューに入ったのか」を先に調べる
ことが、根本的な解決につながります。
Postfix関連記事
Postfixのメール配送トラブルについて、以下の記事でも解説しています。


コメント