milter-regex + S25R 方式にて spam メールの受け付けを拒否

Postfix で メールサーバ構築のページにて導入しました S25R 方式ですが、milter-regex を 使用して MTA が sendmail のシステムでも同じように spam メールの拒否を行える ようにします。
なお、sendmail はソースからコンパイルとインストールを行っていることを前提と します。


[1] sendmail の Milter サポートの確認

Milter (sendmail のメールフィルタ API) は sendmail 8.13 以降では デフォルトでサポートされるようになっていますが、念のため確認を 行います。
sendmail をデバッグモードで起動し、Compiled with: の欄に MILTER の 表示があれば OK です。

$ /usr/sbin/sendmail -bt -d0.1 < /dev/null

Version 8.14.4
 Compiled with: DNSMAP LOG MATCHGECOS MILTER MIME7TO8 MIME8TO7
                NAMED_BIND NETINET NETUNIX NEWDB PIPELINING SCANF USERDB XDEBUG

============ SYSTEM IDENTITY (after readcf) ============
      (short domain name) $w = mailsvr
  (canonical domain name) $j = mailsvr.example.com
         (subdomain name) $m = example.com
              (node name) $k = mailsvr.example.com
========================================================

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>

[2] libmilter のコンパイルとインストール

Milter のライブラリである libmilter のコンパイルとインストールを 行います。
sendmail のソースを展開したディレクトリ 以下に libmilter ディレクトリが ありますので、その中で Build スクリプトを実行します。

$ cd sendmail-8.14.4/libmilter/
# sh Build install

[3] milter-regex のコンパイルとインストール

milter-regex 用のディレクトリを作成します。 所有者は smmsp ユーザとします。

# mkdir /var/milter-regex
# chown smmsp:root /var/milter-regex

次に benzedrine.cx - milter-regex からソースを入手し、コンパイルとインストールを行います。
(最新版は milter-regex-1.6 です)

$ tar -zxf milter-regex-1.6.tar.gz
$ cd milter-regex/
$ make -f Mailefile.linux
# cp milter-regex /usr/bin/

なお milter-regex はデフォルトでは facility:daemon にてログを出力します。 別の facility にてログを出力させたい場合は、milter-regex.c の 564 行目 の openlog 関数の facility 引き数を変更してからコンパイルを行います。
facility を daemon から local5 に修正する例は以下の通りとなります。

openlog("milter-regex", LOG_PID | LOG_NDELAY, LOG_DAEMON);
  ↓
openlog("milter-regex", LOG_PID | LOG_NDELAY, LOG_LOCAL5);

[4] 起動スクリプトの作成

起動スクリプトの作成を行います。
milter-regex.init の "user=" の値を mailregx から smmsp に 修正します。

# vi milter-regex.init

user="mailregx"
  ↓
user="smmsp"

milter-regex.init を /etc/init.d/ 以下にコピーし、chkconfig コマンドで 扱えるよう登録します。

# cp milter-regex.init /etc/init.d/milter-regex
# chmod 755 /etc/init.d/milter-regex
# chkconfig --add milter-regex
# chkconfig milter-regex on

[5] milter-regex.conf の作成

設定ファイル (/etc/mail/milter-regex.conf) の作成を行います。
内容例につきましては下記の通りとなります。

tmpfail "may not be mail exchanger"
connect /^[^\.]*[0-9][^0-9\.]+[0-9]/ //
connect /^[^\.]*[0-9]{5}/ //
connect /^([^\.]+\.)?[0-9][^\.]*\.[^\.]+\..+\.[a-z]/ //
connect /^[^\.]*[0-9]\.[^\.]*[0-9]-[0-9]/ //
connect /^[^\.]*[0-9]\.[^\.]*[0-9]\.[^\.]+\..+\./ //
connect /^(dhcp|dialup|ppp|adsl)[^\.]*[0-9]/ //

1 行目では、以降で指定するホストからの接続があった場合の 動作を指定します。
上記例では、tmpfail コマンドにて "may not be mail exchanger" のメッセージと共に一時的エラーを返す設定としています。
(参考までに、恒久的エラーを返す場合は tmpfail ではなく reject コマンドを 使用します)

2 行目以降で拒否対象とする接続元の条件 (正規表現) を記述します。
内容につきましては、 阻止率99%のスパム対策方式の研究報告にて記述されている S25R 方式の ルール (正規表現) をそのまま流用しています。

connect コマンドの文法は "connect <ホスト名> <IP アドレス>" と なっていまして、接続元のホスト名と IP アドレスの両方が正規表現にマッチした場合に 拒否される形となります。
今回の例のようにホスト名だけを条件とする場合は、IP アドレス部分の 正規表現を "//" として、無条件マッチとなるようにします。


[6] milter-regex の起動

milter-regex を起動します。

# /etc/init.d/milter-regex start

/var/log/messages に "milter-regex startup succeeded" の メッセージが出力されることを確認します。

milter-regex[11542]: started: $Id: milter-regex.c,v 1.49 2005/03/06 11:42:53 dhartmei Exp $
milter-regex: milter-regex startup succeeded

[7] sendmail.cf の再作成

milter-regex に対応した sendmail.cf の作成を行います。

# cd sendmail-8.14.4/cf/cf/
# vi sendmail.mc

下記の行を sendmail.mc に追記します。

# milter-regex
INPUT_MAIL_FILTER(`milter-regex',
    `S=unix:/var/milter-regex/milter-regex.sock', `T=S:30s,R:2m')

再作成した sendmail.cf のインストールを行い sendmail を再起動して 作業は終了となります。

# sh Build sendmail.cf
# sh Build install-cf
# /etc/init.d/sendmail restart

実際に接続を拒否した milter-regex のログ (/var/log/milter-regex) の 例は下記のような感じとなります。

milter-regex[22128]: 218.9.244.48: cb_connect('[218.9.244.48]', '218.9.244.48')
milter-regex[22128]: 218.9.244.48: REJECT: may not be mail exchanger, From: , To: , Subject:
milter-regex[22128]: 218.9.244.48: cb_close()

戻ります