postfixまたはsendmailでのウィルスフィルタ
 

procmailでの受信時のウィルス除去の方法

最終更新日:2002年3月14日
初出:2001年12月24日

2001年末にかけてウィルスがたくさん届きました

 2001年のコンピュータ環境を振り返るとき、Windows系のウィルスによる被 害がMac、Linuxユーザにも拡大した悲惨な年であったということが歴史的に認 識されるでしょう。とある大企業のネットワーク全体が麻痺したとか、メール サーバが動作を停止したとか、各種マスコミがその読者の皆さんにウィルスを ばらまいたとか、そういう話が年末にかけて一般の新聞などにも紹介されまし た。

 このところ、弊社が代理店を行なっているLinux Journal誌でも12月号でそ の対策が紹介されていたり、商用のフィルタを使用できるAMaViSなどがネット ワーク上で紹介されていたりしますが、より簡便な方法もありますのでご紹介 します。


postfixにもsendmailにも対応できるprocmailでのフィルタ

 ここでご紹介するのはPostfixまたはSendmailにてサーバマシン内のメール 配信にprocmailというコマンドを使用している場合の方法です。もちろん、こ れでメールが消えてしまったとか無限ループが発生したなどの被害がありまし ても責任は取れませんので、良く注意してご利用ください。また、こちらでは SMTPサーバとしてPostfixまたはSendmailでテストし、qmailではテストしてい ません。qmailでもqmail-commandの指定や.forwardの設定によってprocmailを 使うことが出来るはずですから、qmailをご利用の方も試されると良いでしょ う。

procmailの設定:procmailrcの書き方

 Procmailは、PostfixやSendmailなどで、メールスプールに書き込むプログ ラムとして使用されています(Sendmailではバージョンによりますが少なくと も1995年に発表されたの8.7.x以降であればprocmailに対応しています)。 procmailは、一般的に$HOME(ユーザのホームディレクトリ)の.procmailrcか、 /etc/procmailrcによってその挙動を制御できます。何も指定していなければ、 /var/spool/mail/以下にユーザごとのメールの実体を保存します。

 /etc/procmailrcに設定ファイルを保存する方法は、システム全体のメール スプールの書き方を制御する場合には良いのですが、エラーで転送されるメー ルについてもルールが適用されたりして無限ループを発生させる場合があるな ど、危険過ぎます。システムワイドな設定を行ないたい場合も、ユーザのホー ムディレクトリからシンボリックリンクを張るのが一般的です。

 man procmailrcなどとしてみれば説明を読むことが出来ますが、procmailrc は以下のようなフォーマットになっています(procmailrcはレシピと呼ばれる ことがあります)。

:0 フラグ
* パターン
書き出し先
* (アスタリスク)で始まる行がパターンを示していて、これは複数行記述す ることが出来ます。複数行記入していれば、それらすべてにマッチするメール が書き出しされることになります。書き出し先はファイルまたは|(パイプ) 経由でのプログラムになります。

簡単な実例

 前置きが長くなったので、動作する例をお見せすると、以下のようになりま す。

:0H:
* ^From: .*<_
$HOME/procmail/junkmail
 これだけで、今流行しているBadtransというメールがユーザのホームディレ クトリのprocmail/junkmailというファイルに追加されていきます。条件にマッ チしないメールは、通常のスプールに書き込まれます。ファイルのバックアッ プを取りたくない場合は、書き込み先を/dev/nullにしておけばすべて捨てら れます。

 この例は単純過ぎるかも知れません。_(アンダースコア)で始まるメール アドレスが実際に使われている例がほとんどなかったのでこのような例をご紹 介しましたが、_(アンダースコア)で始まるメールアドレスが使われている 場合には、以下の記述を参考にしてより複雑なルールを記述する必要がありま す。

 procmail/ディレクトリはそのユーザの権限で書き込めるように作成してお かなければなりません。また、ディレクトリがユーザ権限で書き込み禁止の場 合は、junkmailファイル自体をユーザの権限で書き込めるようにして作成して おく必要もあります。

 ここで、:0H:のHとは、ヘッダに含まれる情報であることを示します。Bと書 くと、ボディ(本文)の中でパターンを探します。右側の:(コロン)はロッ クファイルを作成しつつ処理することを示しています。プログラムに渡すとき はロックは不要ですが、ファイルに書き込むときは必ず右側に:(コロン)を 付けましょう。

もう少し条件を追加した例

 次に、筆者が使用中のファイルを示します。

LOGFILE=$HOME/procmail/log

:0H:
* ^From: .*<_
$HOME/procmail/junkmail

:0H
* ^Content-Type: .*multipart
{
	:0B:
	* ^	 name=.*(\.scr|\.exe)
	$HOME/procmail/virusmail
}

:0H
* ^Content-Type: .*multipart
{
	:0B:
	* ^Content-Type: .* name=.*(\.scr|\.exe)
	$HOME/procmail/virusmail
}

 これで実行していることは、以下のようになります。

  • 処理内容はlogというファイルに記録する。
  • _(アンダースコア)で始まるメールアドレスを使っているメールは有無 を言わさずjunkmailというファイルに書き込む。
  • 添付書類付きのメールで、添付のファイル名が.scrまたは.exeを含む場合 はvirusmailに書き込む。このように、ヘッダとボディの両方の条件がマッチ した場合など、複雑な挙動を設定することが出来ます。
 これで、今のところ大部分のウィルスメールが届くのを防ぐことが出来てい ます。ただし、ファイル名はContent-Type:行の次に来ることがあり、ルール としては2つに分けています。

/etc/aliasesを使用する方法

 システム全体でprocmailのフィルタを利用する方法(/etc/procmailrc)、 ユーザごとに設定する方法(~/.procmailrc)の二つを紹介しましたが、さら に、aliasアドレスに対しての設定方法もあります。システム全体での使いに くさは上述しましたが、aliasアドレスの場合は、その転送先のアドレスが他 のシステムであったりして、フィルタの設定が難しい場合があります。

 このような場合は、/etc/aliasesファイルで、aliasesアドレスに対して procmailにパイプさせる設定を記入するほうが便利です。ただし、その場合は、 展開されるはずのアドレスをprocmailrc側に記入しないといけないので、書き 方には十分に注意が必要です。また、procmailプログラムが、特定のユーザの 権限ではなく、システム側の権限(nobodyやdaemonやmailというユーザの権限) で動作していますので、これらの権限でアクセスできるログファイルや書き出 しファイルを作成しておかなければなりません。

postfixで/etc/aliasesを使用する場合

 postfixは通常rootやpostfixというユーザ権限で動作していますが、起動す るプロセスの一部は、設定ファイル中のdefault_privsという項目で設定され たユーザの権限で動作します。ここではnobodyという権限が設定されているも のと仮定して話を進めます。

 まず、ログファイルと作業ファイルを作成しておきます。
$ su
Password:
# mkdir /var/spool/procmail
# touch /var/spool/procmail/errors
# touch /var/spool/procmail/virusmail
# touch /var/spool/procmail/rc.webmaster
# chmod 600 /var/spool/procmail/rc.webmaster
# chown -R nobody.nobody /var/spool/procmail

 また、/var/spool/procmail/rc.webmasterファイル(次に説明します)は、 ファイルモードも、他人に読み取りができないようにしなければなりません。

 続いて、procmailrcファイルを正しく記入しておきます。ここでは、 /var/spool/procmail/rc.webmasterというファイルとします。特に、個人の設 定ファイルで使っていたような$HOMEなどの変数は書き換えておかねばなりま せんので、注意しましょう。

HOME=/var/spool/procmail
LOGFILE=$HOME/log

:0H:
* ^From: .*<_
$HOME/virusmail

:0H:
* ^From: .*(spammer|Spammer|SPAMMER)@
$HOME/errors

:0H:
* ^From: .*(mailer-daemon|Mailer-Daemon|MAILER-DAEMON)@
$HOME/errors

:0H
* ^Content-Type: .*multipart
{
        :0B:
        * ^Content-Type: .* name=.*(\.scr|\.exe|\.xls\.pif|\.doc\.com|\.xls\.bat
)
        $HOME/virusmail
}

:0H
* ^From: *
! validuser another@address.co.jp
 この例では、以下のようなことを指定しています。
  • ログファイルは/var/spool/procmail/ディレクトリのlogとする。
  • <_というパターンを持つFrom行を持つメールは同ディレクトリのvirusmailへ保存
  • SPAMMERおよびMAILER-DAEMONからのメールは同ディレクトリのerrorsへ保存
  • MIME形式(マルチパート)のメールで、添付ファイルに.exeなどで終わるファイル名を含むものはvirusmailへ保存
  • その他のメールはシステム内のvaliduserというユーザ、およびanother@address.co.jpへ転送する
 この/var/spool/procmail/rc.webmasterファイルは、  最終的に、/etc/aliasesファイルに、このrcファイルを使用する設定を、以 下のように記述します。ここでは、webmasterというアドレスに対して設定し てみます。

webmaster: "| /usr/bin/procmail -m /var/spool/procmail/rc.webmaster"
(以前の表記では|(パイプ)がありませんでした。申し訳ございませんでした)
 procmailの-mオプションは、aliasアドレスのように、システムに登録され ているユーザ名ではないアドレスに対してprocmailを実行する場合に必要とな ります。/etc/aliasesファイルを更新したら、newaliasesコマンドを実行する ことを忘れないようにしましょう。

 以上の設定でpostfixの/etc/aliasesに記述されているアドレス宛のメール は、procmailに直接流し込むことが出来るようになります。くれぐれも、 procmailrcファイル末尾のフォワード先のアドレスの記述は忘れないようにし ましょう。これがないと、動作している権限を持つユーザ(ここではnobody) 宛のメールとして処理されてしまいます(/var/spool/mail/nobodyに保存され る)。

sendmailで/etc/aliasesを使用する場合

 現状のsendmailの場合ですと、ほとんどpostfixと同じですが、唯一、smrsh という仕組みを使うところが異なります。sendmailがaliasesファイル内でパ イプとして呼び出すプログラムは、smrshを使用して起動されます。

 smrshで使用されるプログラムは、/etc/smrsh/ディレクトリにコマンドがな ければいけませんが、このコマンドはシンボリックリンクでも構いません。従っ て、aliasesファイルにprocmailの設定を記入する前に、以下の操作を行なっ ておけば良いでしょう。

$ su
Password: 
# cd /etc/smrsh
# ln -s /usr/bin/procmail
 また、smrshは| (パイプ)で渡されるコマンドは全てパス名を省略して、 /etc/smrshにあるコマンドであると見なします。もし絶対パス名で /usr/bin/procmailを指定しても、/etc/smrsh/ディレクトリにprocmailが存在 してなければ、エラーになります。

 さらに、sendmailプログラムはmailというユーザ権限でプロセスを起動する 場合がありますので、その場合には作業ディレクトリ(上記例でいけば /var/spool/procmail/ディレクトリ)以下のオーナをあわせておきましょう。 具体的には、/etc/sendmail.cfのDefaultUserでユーザIDとグループIDが記録 されていますので、そのユーザIDを持つユーザにchownしておきましょう。

「!広告!」メールの排除方法

 2002年になって、法律上、ダイレクトメールには「!広告!」という表題を つけなければならないことになりました。罰則はないにも関わらず、比較的多 数のダイレクトメールがこれを遵守するようになっています。

 しかし、個人でもビジネスの世界でも、わざわざダイレクトメールを受け取 りたくないのが普通でしょう。このようなダイレクトメールも、procmailを使っ て排除できます。


:0H:
* ^Subject: \/.*
* ? echo "$MATCH" | /usr/bin/nkf -Zme | /bin/grep '!.*広告.*!'
$HOME/procmail/junkmail
linux-usersメーリングリスト等で紹介されていた方法を改良しました。

 ここでは、:0H:によって、ヘッダを見ることを強制しています。さらに、 「\/」によって、Subject行を二つにわけ、右側を$MATCHという変数に割り当 てています($MATCHはprocmailに用意されている変数です)。その後、その $MATCHという変数の中身を文字コード変換して、「!広告!」という文字列が あったらjunkmailファイルに追加しています。もちろん、書き込むファイルは /dev/nullでも構いません(/dev/nullに書き込めば全て捨てられます)。

 この方法によって、

  • MIMEエンコードによってSubject:行が2行に分割されていても、対応でき ます。
  • また、「!」記号が全角であっても半角であっても対応できます。
  • 「!」記号と「広告」という文字列の間に他の文字列が入っていても対応 できます。
というようなスマートな対応が可能となっています。

まとめ

 以上の方法は、完全なウィルスフィルタではありませんので、ユーザ側がウィ ルスチェッカーを使用したり、感染しやすいソフトを使用するのをやめるなど の対処を怠ることは許されません。しかし、感染の可能性を減らしたり、ディ スクが予想外に早くあふれるなどの被害に対しては(適切なパーティションに 書き出すなどして)有効に作用できるでしょう。

 procmailは、postfixではルールの 記述が単純にしか出来ないという機能を補間できます。また、システム全体で メールを捨てたりエラーを返してしまうよりは、必要なメールだった場合の再 送が少なくなるなどの利点があります。また、procmailならformailなど他の プログラムに制御を任せたり(自動返信する場合に必要です)、junkfilterな どパッケージになっている複雑なルールを適用するなど、奥の深い対応にも挑 戦できます。ただし、AMaViSなどを使う場合に比べれば、フィルタの更新が大 変かも知れませんし、送信する場合の対処が抜け落ちています。

 ご紹介したのはあくまで例であって、これよりも良い方法があるかも知れま せん。どうも使ったことがないから良くわからないという場合は、弊社Linuxセミナー(メールサーバの構築)でもご 紹介していきますので、トライしてみてください。

 また、最低限のフィルタを共通化して、どこかでダウンロードできるように しておくのも、システム管理者にとっては楽かも知れませんね。.procmailrc 自体はシンボリックリンクでも構いませんので、一つのシステム(メールサー バ)内であれば共通化しておいて、全てのユーザの受信フィルタとして活用す ることも可能です。

 ネットワーク管理者の皆さん、少しずつでもネットワークを快適に使ってい きましょう。


ご参考:
アミュレット Linuxセミナー
アミュレットのLinuxソリューション
Amulet Logo
当サイトは、AMULET開発部の情報サイトです。
Copyright (c) 2001,2002 AMULET Inc. All Rights Reserved.
 
AMULETのトップページへ