HELO詐称の迷惑メールをPostfixで破棄

メール使ってる人の多くはおそらく毎日大量に迷惑メールを受けている筈。Gmailなら迷惑メールを除去していると思うのでそうでもないのかな?
うちのメールサーバはRspamdを使っているので殆どの迷惑メールは自動識別され隔離フォルダに入るようになっている。Gmailのように迷惑メールフィルタが優秀なら迷惑メールと判断したら自動削除というのもアリなのだろうけど、False Positive(誤検知)が怖い。迷惑メールが非迷惑メールと判断されるFalse Negativeは許せるけど、例えば重要なメールが迷惑メール扱いにされて消されるというのはあってはならない。だから妥協して迷惑メールと判断したら削除ではなく隔離ね。

ところで、下のような題名の日本人向け迷惑メールがある。(最近の)

  • ★☆★☆★ WOWWOW ★☆★☆★
  • [ 緊急速報 ]
  • 【発送】ご注文の商品について
  • 詐欺ばっかりの業者にうんざり

皆がこのようなメールを受信しているとは限らないけど、見たことあるって人は多い筈。
他の特徴としては差出人のメールアドレスが下の様なの。

[8文字前後のランダム英字] @ [16〜24文字程度のランダム英字] .jp 

本文の文字コードがメールヘッダの文字コード指定と違っているのでメーラーによっては本文が読めないなんてのも。

そして、最大の特徴はメールヘッダにある。

Received: from customer.worldstream.nl (unknown [xxx.xxx.xxx.xxx])

Received fromにcustomer.worldstream.nlって書かれてるのね。
以前から迷惑メール送信に使われるホスト名なので見たことある人も多い筈。
Received fromに書かれているIPアドレスが customer.worldstream.nl ではないので念の為。というか、騙ってるだけ。 worldstream.nl は実在するドメインだが、 customer.worldstream.nl はIPアドレスを引けないホストなので存在しないと考えて構わない。つまり customer.worldstream.nl を騙るホストがメール送ってきたら、それはおそらくボットとかそんなの。
これは100%迷惑メールと判断して良い。100%迷惑メールであるならばRspamdなどの迷惑メールフィルタに渡して判断させるまでもなくPostfixで受けた瞬間に削除する方が良いかな。
これらのIPアドレスを個別にBANするのは無駄。

Postfixの設定

/usr/local/etc/postrix/main.cf (FreeBSDのports/pkgのDir構成)
header_checks = regexp:/usr/local/etc/postfix/header_checks

おそらく真面目に設定したPostfixならheader_checks行は既に存在する筈。既存の設定がregexp指定になってない場合は下のファイルは正規表現を使わないものに読み替えて。

/usr/local/etc/postfix/header_checks (追記1行)
/^Received: from customer\.worldstream\.nl/ DISCARD

REJECT(拒否)ではなくDISCARD(破棄)すること。
正規表現を使っている場合はpostmapでDBファイルを作成しない。
正規表現を使うことにした場合にすでにDBファイルが存在するならheader_checks.dbを削除。
そうでなければDBファイルを作成。

# postmap header_checks

設定が終わったらPostfixに設定再読込をさせる。

# service postfix reload

または、

そもそもheloでcustomer.worldstream.nlを詐称してくるのでそれを利用して拒否・破棄する。

/usr/local/etc/postfix/main.cf (変更・1行挿入)
1
2
3
4
5
6
7
8
smtpd_delay_reject = yes   #この行を忘れずに
smtpd_helo_required = yes
smtpd_helo_restrictions =
    permit_mynetworks,
    reject_invalid_hostname,
    reject_non_fqdn_hostname,
    check_helo_access hash:/usr/local/etc/postfix/helo_access,   #←これ
    permit

/usr/local/etc/postfix/helo_access (追記1行)
customer.worldstream.nl   DISCARD

REJECTではなくDISCARDを指定する。理由は後述の「確認してみる」のところに。

helo_accessファイルを編集したらDBファイルを作成・更新する。

# postmap helo_access

設定が終わったらPostfixに設定再読込をさせる。

# service postfix reload

確認してみる

helo_accessにHELOをREJECTで指定した場合
% telnet mx.example.com 25  メールサーバに接続
Trying 2001:xxxx:xxxx:xxxx::1000...
Connected to mx.example.com.
Escape character is '^]'.
220 mx.example.com ESMTP Postfix
HELO customer.worldstream.nl Reject登録済ホストを詐称
250 mx.example.com
MAIL FROM: hage@example.com 差出人を指定
250 2.1.0 Ok
RCPT TO: hoge@example.com 宛先を指定
554 5.7.1 : Helo command rejected: Access denied
QUIT   接続終了
Connection closed by foreign host.

メールを送信しようとしたら理由とともに拒否される。正当な送信者に対して拒否理由を知らせるのは良いことだが、スパマー(ボット)に拒否理由や回避方法のヒントを知らせる必要はない。

helo_accessにHELOをDISCARDで指定した場合
% telnet mx.example.com 25  メールサーバに接続
Trying 2001:xxxx:xxxx:xxxx::1000...
Connected to mx.example.com.
Escape character is '^]'.
220 mx.example.com ESMTP Postfix
HELO customer.worldstream.nl Discard登録済ホストを詐称
250 mx.example.com
MAIL FROM: hage@example.com 差出人を指定
250 2.1.0 Ok
RCPT TO: hoge@example.com 宛先を指定
250 2.1.5 Ok
DATA データ(メール本文)入力を宣言
354 End data with <cr><lf>.<cr><lf>
test メール本文
. メール本文終了
250 2.0.0 Ok: queued as 58BC818E0137
QUIT 接続終了
221 2.0.0 Bye
Connection closed by foreign host.

送信者には正常に送信できたように見える。

このときのPostfixのログ
Jul 23 21:47:51 hoge postfix/smtpd[76966]: NOQUEUE: discard: RCPT from spammer.example.com[2004:yyyy:yyyy:yyyy::yyyy]: <customer.worldstream.nl>: Helo command triggers DISCARD action; from=<hage@example.com> to=<hoge@example.com> proto=SMTP helo=<customer.worldstream.nl>

希望がかなってしっかり破棄できている。

なんでこんな初歩的なことを書くかって?、Rspamdとか使い始めると依存しすぎて意外と忘れがちかなと。