Exim4 で外部から postmaster@localhost に届いてしまう の履歴(No.1)
更新- 履歴一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- 管理者/Exim4 で外部から postmaster@localhost に届いてしまう へ行く。
- 1
観測された現象†
IMAP の受信箱に妙なメールが届いた。
Return-path: <sender@example.com> Envelope-to: postmaster@localhost Received: from [107.172.77.101] (helo=inside) by my-server.com with esmtps (TLS1.3) ... (envelope-from <sender@example.com>) for postmaster@localhost; ABCD
本文は ABCD だけ。From: To: Subject: などのヘッダーもない。明らかに正規のメールではないが、SMTP セッションとしてはきちんと完了し、Exim4 が受け取って配送している。
ヘッダーから読み取れる経路†
- 接続元 107.172.77.101 は ColoCrossing(米国の VPS 業者)の IP
- HELO は inside という嘘 FQDN
- MAIL FROM:<sender@example.com>、RCPT TO:<postmaster@localhost> で通過
- 認証なし(esmtps であって esmtpsa ではない)
exim4 -bt postmaster@localhost で配送経路を追うと:
R: system_aliases for postmaster@localhost
R: system_aliases for root@my-server.com
R: userforward for osamu@my-server.comt
...
osamu@my-server.com
<-- root@my-server.com
<-- postmaster@localhost
/etc/aliases の postmaster: root → root: osamu のチェーンで、外部から投げられた postmaster@localhost 宛のメールが自分の Maildir まで届いていた。
原因†
ふたつの設定が組み合わさることで起きていた。
localhost が local_domains に入っている†
exim4 -bP config | grep local_domains で確認:
domainlist local_domains = @:localhost:my-server.com
これは Debian Exim4 のデフォルトで、cron や mdadm からの root@localhost 宛通知がローカル配送されるために必要な設定。外すわけにはいかない。
Exim のデフォルト ACL に「postmaster は無条件で受け入れる」ルールがある†
Debian の /etc/exim4/exim4.conf.template の acl_check_rcpt: セクションにこんなブロックがあった:
# Accept mail to postmaster in any local domain, regardless of the source, # and without verifying the sender. accept local_parts = postmaster domains = +local_domains : +relay_to_domains
これは Exim の慣行で、「設定をミスっても postmaster だけは絶対に届くようにする」という保険。それ自体は妥当な思想だが、(1) と組み合わさると postmaster@localhost だけ外部から誰でも投げ込める入り口になってしまう。
bot の本来の狙いはおそらく次の段階の RCPT で外部リレーを試すことだったと思われる(relay_from_hosts には入っていないので拒否される)。今回は探査の ABCD だけが副産物として届いた格好。
対処方針†
/etc/aliases のエイリアスチェーンを外すと cron 通知が届かなくなるので不可。local_domains から localhost を外すのも同じ理由で不可。
正しい対処は 「外部 IP から @localhost 宛の RCPT が来たら拒否する」を ACL で追加すること。「postmaster 無条件受け入れ」ルールよりも前に評価される位置に置く必要がある。
設定ファイルの特定†
$ sudo update-exim4.conf -v 2>&1 | head using non-split configuration scheme from /etc/exim4/exim4.conf.template
split しない設定ファイルが使われていた。
ACL の追加†
exim4.conf.template の acl_check_rcpt セクションに、accept hosts = :(非SMTP投入の素通し) の直後に次のように書いた:
acl_check_rcpt:
# Accept if the source is local SMTP (i.e. not over TCP/IP). We do this by
# testing for an empty sending host field.
accept
hosts = :
control = dkim_disable_verify
######### added from here on 2026-05-22
# Deny external attempts to deliver to @localhost.
# postmaster@localhost would otherwise be accepted by the unconditional
# "accept postmaster" rule further down, since localhost is in
# local_domains (required for cron/root mail to be delivered locally).
deny
message = relay not permitted: <$local_part@$domain> from remote host
hosts = ! 127.0.0.0/8 : ! ::::1 : ! 172.16.0.0/12
domains = localhost : localhost.localdomain
######### added until here on 2026-05-22
# ... 既存の続き
更新&確認†
$ sudo update-exim4.conf $ sudo systemctl reload exim4 $ sudo exim4 -bh 107.172.77.101 <<'EOF' EHLO inside MAIL FROM:<sender@example.com> RCPT TO:<postmaster@localhost> QUIT EOF >>> check hosts = ! 127.0.0.0/8 : ! ::::1 : ! 172.16.0.0/12 >>> host in "..."? yes (end of list) >>> check domains = localhost : localhost.localdomain >>> localhost in "..."? yes (matched "localhost") >>> deny: condition test succeeded >>> end of ACL "acl_check_rcpt": DENY 550 relay not permitted: <postmaster@localhost> from remote host
ちゃんと拒否されるようになった。
注意:設定ファイルで ::1 と書くと動かない†
コロン : は区切り文字として使われるので、::1 と書く代わりに ::::1 のように : を重ねて書かないとダメだった。はじめ、これで難儀した。
(NG) hosts = ! 127.0.0.0/8 : ! ::::1 : ! 172.16.0.0/12 (OK) hosts = ! 127.0.0.0/8 : ! ::1 : ! 172.16.0.0/12