Exim4 で外部から postmaster@localhost に届いてしまう の変更点

更新


#author("2026-05-22T02:43:31+00:00","default:administrator","administrator")
#author("2026-05-22T03:11:23+00:00","default:administrator","administrator")
[[公開メモ]]

* 概要 [#t4ba6c92]

postmaster@localhost という宛先におかしな手段でメールが届いたので調査&対応した。

#contents

* 観測された現象 [#s81ae1f7]

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 が受け取って配送している。

** ヘッダーから読み取れる経路 [#ob00777b]

- 接続元 107.172.77.101 は ColoCrossing(米国の VPS 業者)の IP
- HELO は inside という嘘 FQDN
- MAIL FROM:<sender@example.com>、RCPT TO:<postmaster@localhost> で通過
- 認証なし(esmtps であって esmtpsa ではない)

配送経路を追うと:

 LANG:console
 $ 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 まで届いていた。

** 原因 [#b41e3391]

ふたつの設定が組み合わさることで起きていた。

*** localhost が local_domains に入っている [#f3d127c0]

local_domains を確認:

 LANG:console
 $ exim4 -bP config | grep local_domains
 domainlist local_domains = @:localhost:my-server.com

これは Debian Exim4 のデフォルトで、cron や mdadm からの root@localhost 宛通知がローカル配送されるために必要な設定。外すわけにはいかない。

*** Exim のデフォルト ACL に「postmaster は無条件で受け入れる」ルールがある [#nbf185cc]

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 だけが副産物として届いた格好。

* 対応 [#c944a323]

/etc/aliases のエイリアスチェーンを外すと cron 通知が届かなくなるので不可。local_domains から localhost を外すのも同じ理由で不可。

正しい対処は 「外部 IP から @localhost 宛の RCPT が来たら拒否する」を ACL で追加すること。「postmaster 無条件受け入れ」ルールよりも前に評価される位置に置く必要がある。

** 設定ファイルの特定 [#ga132c15]

 LANG:console
 $ sudo update-exim4.conf -v 2>&1 | head
 using non-split configuration scheme from /etc/exim4/exim4.conf.template

split しない設定ファイルが使われていた。

** ACL の追加 [#r5e1aaa1]

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
 
   # ... 既存の続き

** 更新&確認 [#ka2d8563]

 LANG:console
 $ 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 と書くと動かない [#l0f2c9e7]

コロン : は区切り文字として使われるので、::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

* 結局これ、何のために送られたメールだったか? [#m9ba617e]

結局これって送り付けた側は何がしたかったんですかね?

IP アドレス総当たりで smtp が動いているかどうかを見て、ドメイン名を指定せずにメールの転送状況を確認したかった?

でもログを調べてみると外部アドレスへのリレー試行などはされてない。

"HELO inside" でググっても何も出てこないのでかなり新しい、あるいはマイナーな攻撃(?)っぽいのだけれど、これ自体はうざいけど無害なので、ここからどこにつなげようとしていたか、興味&心配ある。

* コメント・質問 [#xa59bf63]

#article_kcaptcha



Counter: 64 (from 2010/06/03), today: 28, yesterday: 36