連載
» 2001年11月06日 00時00分 UPDATE

実用qmailサーバ運用・管理術(3):SPAMメール徹底対策 (3/3)

[鶴長鎮一,@IT]
前のページへ 1|2|3       

キューイングしてしまったSPAMメールの処理

 qmailをインストールすると、配送キューの簡単な統計情報を表示する/var/qmail/bin/qmail-qstatと、たまっているメッセージキューのヘッダ情報を部分的に表示する/var/qmail/bin/qmail-qreadもインストールされます。

# /var/qmail/bin/qmail-qstat
messages in queue: 11
messages in queue but not yet preprocessed: 0

# /var/qmail/bin/qmail-qread
28 Oct 2001 20:35:57 GMT #11224 2127 <>
        remote XXX@XXX.jp
28 Oct 2001 17:20:17 GMT #11225 2132 <>
        remote XXX@XXX.jp
28 Oct 2001 20:44:32 GMT #11226 2130 <>
        remote XXX@XXX.jp
28 Oct 2001 23:30:57 GMT #11228 2130 <>
        remote XXX@XXX.jp
28 Oct 2001 17:01:33 GMT #11231 1555 <>
        remote XXX@XXX.jp
実行例 XXXは伏せ字

 実際には、巨大なシステムでもない限りキューにメッセージがたまったままという状況は発生しません。しかし、SPAMの踏み台(中継ホスト)にされた場合、さらには他ネットワークから発せられたSPAMメールのReturn-Pathに自社のサーバが指定されてしまい、身に覚えのないエラーメール、それも数千という膨大な数のメッセージが届けられた場合は、すさまじい数字と一覧が表示されます。こうなった場合は、すぐに/var/qmail/control/badmailfromにエラーメールの送信元を指定し、これ以上エラーメールなどのメッセージが届かないようにします。

 では、すでにキューにたまってしまったメッセージはどうしたらよいでしょうか? qmailではユーザーのメッセージと同様、キューもファイルとして保存されています。このキューのファイルを削除します。

 まずキューの操作を行う前に、qmailの各プロセスを停止させておく必要があります。ここでは、第1回で紹介したqmailのrcスクリプトを使用します。次にqmail-qreadを使ってMessage-Idを調べます。

# /スクリプトの保存先/qmail stop
# /var/qmail/bin/qmail-qread
28 Oct 2001 20:35:57 GMT #Message-Id 2127 <>
remote XXX@XXX.jp

 キューに関連する3つのファイルを削除します。

/var/qmail/queue/info/NN/Message-Id
/var/qmail/queue/mess/NN/Message-Id
/var/qmail/queue/remote/NN/Message-Id
送信キュー(リモート)の場合

/var/qmail/queue/info/NN/Message-Id
/var/qmail/queue/mess/NN/Message-Id
/var/qmail/queue/local/NN/Message-Id
受信キュー(ローカル)の場合

 上記の「NN」は1〜20の数字(qmailが通常インストールされている場合)です。問題は、このNNに指定すべき数字をどうやって見つけるかです。/var/qmail/queue/のinfo、mess、remote、localを手当たり次第に見ていくとなると、削除するキューが数個ならまだしも、数が増えると手に負えません。

 そこで「qmHandle」を使用します。qmHandleはqmail-qstat、qmail-qreadの機能を兼ね備え、さらにキューの削除も行えます。まず、qmHandle-0.5.1.tar.gzhttp://www.io.com/~mick/soft/qmhandle.htmlからダウンロードします。qmHandleはPerlスクリプトなので、特にインストール作業は必要ありません。ただし、Perlが/usr/bin/以外にインストールされている場合はqmHandleスクリプトの1行目のPerlのパスを変更します。

 qmHandleは、指定するオプションによって下記のように動作します。

-l ローカル/リモートすべてのキューを表示
-L ローカルキューを表示
-R リモートキューを表示
-s 統計情報の表示
-vN Message-Id Nのメッセージを表示
-dN Message-Id Nのキューを削除
-D ローカル/リモートすべてのキューを削除
-c 出力結果をカラー表示
-N Message-Idを表示。ただし、-l、-L、-Rオプションと一緒に指定する必要がある

 例えば、ローカルとリモートすべてのキューのMessage-Idを調べるには次のようにします。

# ./qmHandle -l -N
11224 (0, R)
11226 (2, R)
11229 (5, R)
11230 (6, R)
11220 (19, R)
11223 (22, R)
Messages in local queue: 0
Messages in remote queue: 6

 出力されたメッセージを削除するには、-dオプションにMessage-Idを渡して実行します。

# ./qmHandle -dXXX -dXXX -dXXXXX

 先ほどの、キューにかかわるファイルを手動で削除する場合に比べ、格段に手間が省けました。しかし、Message-Idだけでは削除していいメッセージなのかどうか判別がつきません。そこで、From、To、Subject、Date、Sizeに一致条件を付けて、該当したキューだけを削除する方法を考えてみましょう。

 まず、下記のようにしてたまっている送信キューのヘッダ情報を拾い出します。

# ./qmHandle -R
11234 (10, R)
  From: MAILER-DAEMON@XXX.jp
  To: someone@XXX.com
  Subject: failure notice
  Date: 29 Oct 2001 16:41:18 +0900
  Size: 17328 bytes

11220 (19, R)
  From: MAILER-DAEMON@XXX.com
  To: anyone@XXX.com
  Subject: failure notice
  Date: 29 Oct 2001 10:12:03 +0900
  Size: 2817 bytes

11223 (22, R)
  From: MAILER-DAEMON@XXX.net
  To: XXX@XXX.ne.jp
  Subject: failure notice
  Date: 29 Oct 2001 04:25:38 +0900
  Size: 2764 bytes
注:XXXは伏せ字

 実際には、下記のようにファイルにリダイレクトして保存しておきます。

# ./qmHandle -R > que.txt

 送信キューだけを出力するようにしたのは、送信キューと受信キューでは出力フォーマットが異なるため、混在していると次に紹介するシェルスクリプトでMessage-Idを拾い上げることができないからです。

 次に、以下のようなシェルスクリプトを用意します。

#!/bin/sh

cat que.txt |
    grep -B1 "From: XXXX@XXX.jp" |
    grep '^[0-9][0-9]*' |
    sed -e 's/^\([0-9][0-9]*\) .*$/\.\/qmHandle -d\1/'
DeleteQue.sh

 4行目の、

grep -B1 "Return-path: XXXX@XXX.jp"

が重要な一致条件を表現しているのはお分かりいただけると思います。「From: XXXX@XXX.jp」に一致する行と、その上の行を表示するためgrepのオプションに「-B1」を指定しています。もし条件が「To: XXX@XXX.jp」なら「-B2」を指定し、「Subject: XXXXXX」なら「-B3」というように、Message-Idがgrepで引っ掛かるようにオプションを指定します。次の

grep '^[0-9][0-9]*'

で、行頭が数字で始まっているものだけに絞り込みます。そして、

sed -e 's/^\([0-9][0-9]*\) .*$/\.\/qmHandle -d\1/'

で出力フォーマットを./qmHandle -dXXXXXの形に整えます。

 ではスクリプトを実行しましょう。

# ./DeleteQue.sh > delete.sh

./qmHandle -dXXXXX
./qmHandle -dXXXXX
./qmHandle -dXXXXX
./qmHandle -dXXXXX
./qmHandle -dXXXXX
./qmHandle -dXXXXX
.......
delete.shの内容

 ./qmHandle -dXXXXX -dXXXXX -dXXXXX -dXXXXXの形になっていないのは、引数として渡せる文字の長さに限界があるため、確実に削除を行うように1つの削除キューに対してその都度qmHandleを実行するからです。Perlの立ち上がりで無駄なコストが発生しますが、キューの削除は緊急かつ安全な対応が望まれるため、確実な方法を取っています。後はこのファイルを実行するだけです。実行する前に、delete.shとqmHandleが同じディレクトリにあることを確認してください。

# sh ./delete.sh

 削除が完了したら、./qmHandle -Rで確認してみましょう。完全に削除されているはずです。ここでは送信キューを例にしましたが、上記の例のqmHandleに渡すオプションを「-L」に変更するだけで受信キューも同じように削除できます。

 すべての作業が完了したら、再びqmailを起動します。

# /スクリプトの保存先/qmail start

まとめと次回予告

 冒頭でもお話ししたように、SPAMとSPAM対策は常にいたちごっこです。私の経験を基に、有効と思う方法をご紹介しましたが、ここに挙げた以外にも多くの対策が存在します。ですが、何よりも多くの小規模サイトではSPAMの温床にされていることに気付くのが遅いようで、第三者から警告をもらって初めて気が付くことも珍しくないように見受けられます。SPAMに対抗するには、常日ごろからサーバの状態をこまめに監視することが何より大事だと思います。サーバの監視については、回を改めてお話ししたいと思います。

 さて、次回はメーリングリストの構築を見ていきましょう。


前のページへ 1|2|3       

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

Focus

- PR -

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。