L
次のページ
H
前のページ
U
上のページ

« 娘ちゃんと NOVA 問題を語らうの巻き | Main | 中止ボタンがしいたけに見えて困る »

2007年11月28日

CentOS 5.0 上の Postfix に amavisd-new + SpamAssassin + ClamAV

先日は CentOS 5.0 に ClamAV をインストールし、ClamdOmitScan を用いた定期スキャン用に設定するとともに clamav-update で自動アップグレードするようにした。

今回は CentOS 5.0 で Postfix を MTA として使用しているときに、amavisd-new を通して SpamAssassin と ClamAV によってスパム判定と感染メールのチェックをする設定について説明する。clamav-update プロジェクトのソフトウェアは clamdsh を使用する。


前提

このドキュメントは次のことを前提としている。

  • CnetOS 5.0 を使用している。
  • MTA として Postfix を使用し、既に稼働している。
  • ローカル配送されたメールは Maildir 形式で保存される。
  • メールの取得には imap が利用される。
  • Postfix を通して流通するメールメッセージのウィルススキャンに ClamAV を使用する。
  • Postfix を通して流通するメールメッセージの spam 判定に SpamAssassin を使用する。
  • ClamAV と SpamAssassin は amavisd-new を通して利用する。
  • ClamAV は「僕は見ていた : CnetOS 5.0 への ClamAV のインストール手順」に従って既に稼働している。
  • SpamAssassin は既に rpm でインストールしてある。

準備

CentOS 5.0 では amavisd-new が rpm で用意されていない。そこでまず最初に amavisd-new をダウンロードし、ダウンロードした中にあるドキュメントに記載されている関連するソフトウェアをインストールする。

  1. amavisd-new をダウンロードして解凍する。

    URL は http://www.ijs.si/software/amavisd/#download。解凍すると amavisd-new-バージョン というディレクトリができる。

    ここではそのディレクトリを /root/etc/amavisd-new/amavisd-new-2.5.2 として説明する。

  2. 必須な Perl モジュールをインストールする。

    /root/etc/amavisd-new/amavisd-new-2.5.2/INSTALL に記載してある必須の Perl モジュールを全てインストールする。依存するモジュールも同時にインストールするには cpan コマンドが便利。

  3. オプションの Perl モジュールをインストールする。

    INSTALL に記載してあるオプションの Perl モジュールをインストールする。Mail::ClamAV はインストールしなくてよい。clamd を利用する方がメモリ効率も処理効率も高いから。しかし、clamd の未知の脆弱性を突かれて DoS 攻撃されることを懸念するならば使用する選択肢もある。Mail::SpamAssasin は SpamAssassin パッケージに含まれている。

  4. 外部コマンドをできるだけインストールする。

    INSTALL に記載してある外部コマンドをなるべく多くインストールしておく。一覧は各コマンドの提供元の URL と一緒にリストされているところを見る。無いものは無いでもよい。pax など rpm で提供されているものくらいはインストールしておく。

amavisd のインストール

amavisd-new のデーモン amavisd は Perl スクリプトなのでビルドは必要なく、動作のための環境作りとファイルのコピーをする。この段階では amavisd 自体の動作環境の設定のみで、それを SpamAssassin や ClamAV と連動させるのは以降のステップである。

  1. UNIX グループ amavis を作成する。
    groupadd -r amavis
  2. UNIX アカウント amavis を作成する。
    useradd -r -d /var/amavis -g amavis -s /sbin/nologin amavis
  3. amavis のホームディレクトリを作成する。
    mkdir /var/amavis
    cd /var/amavis
    mkdir tmp var db home quarantine
    chown -R amavis:amavis .
    chmod -R 750 .
  4. amavisd をコピーする。
    cp /root/etc/amavisd-new/amavisd-new-2.5.2/amavisd /usr/local/sbin/
    chown root /usr/local/sbin/amavisd
    chmod 755 /usr/local/sbin/amavisd
  5. 設定ファイルをコピーする。
    cp /root/etc/amavisd-new/amavisd-new-2.5.2/amavisd.conf /usr/local/etc/
    chown root:amavis /usr/local/etc/amavisd.conf
    chmod 640 /usr/local/etc/amavisd.conf
  6. 設定ファイルを編集する。

    /usr/local/etc/amavisd.conf を次の要領で編集する。

    • デーモンの実効ユーザ
      変更前
      $daemon_user = 'vscan';
      変更後
      $daemon_user = 'amavis';
    • デーモンの実効グループ
      変更前
      $daemon_group = 'vscan';
      変更後
      $daemon_group = 'amavis';
    • ドメイン名

      amavisd は必要に応じてメールを送信するのだが、そのときの送信元のメールアドレスのドメイン名などに使用される。

      変更前
      $mydomain = 'example.com';
      変更後(例)
      $mydomain = 'mydomain.co.jp';
    • ホームディレクトリ
      変更前
      # $MYHOME = '/var/amavis';
      変更後
      $MYHOME = '/var/amavis';
    • 隔離ディレクトリ
      変更前
      $QUARANTINEDIR = '/var/virusmails';
      変更後
      $QUARANTINEDIR = '/var/amavis/quarantine';
    • データベースディレクトリ
      変更前
      # $db_home = "$MYHOME/db";
      変更後
      $db_home = "$MYHOME/db";
    • LAN のネットワーク

      必要に応じて LAN (というよりも信頼するネットワーク)を設定する。デフォルトではループバックアドレスといわゆる IPv4 のプライベートネットワークが全て、IPv6 のリンクローカルユニキャストアドレスなどが設定されている。実際に設置されるマシンがこれら全てのネットワークに所属するわけではないのでこれを限定しておく。

      ここで指定したネットワークからリモートで amavisd に接続できるようになる(と思う)。

      変更前
      @mynetworks = qw( 127.0.0.0/8 [::1] [FE80::]/10 [FEC0::]/10 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 );
      変更後(例)
      @mynetworks = qw( 127.0.0.0/8 192.168.42.0/24 );
    • メールサーバのホスト名

      メールのヘッダなどに amavisd が自分のホスト名を書き込むときに使用される値がある。デフォルトでは uname コマンドで表示されるホスト名になっているのだが、そのホスト名が例えば LAN 上のもので WAN 向けとは異なる場合などに設定する。

      変更前
      # $myhostname = 'host.example.com'; # must be a fully-qualified domain name!
      変更後(例)
      $myhostname = 'mail.mydomain.co.jp'; # must be a fully-qualified domain name!

編集が終わったら間違いがないかどうかをチェックするために amavisd をデバッグモードで起動する。

/usr/local/sbin/amavisd -c /usr/local/etc/amavisd.conf debug

amavisd が終了することなく稼働しつづけ、全ての amavisd プロセスのインスタンスのオーナが amavis であれば成功である。amavisd は ctrl-c をタイプして終了させる。

ここで amavisd の起動スクリプトを用意しておいたので、これを /etc/rc.d/init.d に置いて実行パーミッションを付けておく。そして次のようにして有効化しておく。

chkconfig --add amavisd

ClamAV の準備

ClamAV を導入したときは定期スキャン用に clamd を設定した。この clamd は利用しない。なぜなら外部から来るメールのスキャンに利用するので、もし clamd の未知の脆弱性が利用されて clamd をクラッシュさせられてしまうと定期スキャンにも影響してしまうからだ。さらに、定期スキャン用の clamd は root 権限で動作している。root 権限で行う必要の無いことはできるだけ root 権限で行わない方が良い。もし clamd に任意のコードを実行させる脆弱性があったら root 権限で任意のコードが実行されてしまうからだ。メールはユーザが承認する前にシステムに入ってくるデータなので特に注意が要る。

そこでここで使用する clamd は次のように設定する。

設定ファイル
/usr/local/etc/clamd-amavis.conf
ログ
syslog をファシリティ LOG_MAIL で使用する。
pid ファイル
/var/amavis/var/clamd.pid
作業ディレクトリ
/var/amavis/tmp
UNIX ドメインソケット
/var/amavis/var/clamd.socket
ストリームデータ最大長
CPU スピードと搭載メモリに応じて決定する。ここではデフォルトのままとする。
ウィルスデータベースチェック間隔
設定しない。freshclam から能動的に通知ようにする。既に freshclam の NotifyClamd は定期スキャン用の clamd 用に使用してしまっているので別な手段を用いる。
実効ユーザ
amavis

これら以外はポリシーにしたがって各自で決定すること。

  1. amavisd 用 clamd 設定ファイルを作成する。

    定期スキャン用の clamd.conf をベースとしてコピーする。

    cp /usr/local/etc/clamd.conf /usr/local/etc/clamd-amavis.conf
  2. /usr/local/etc/clamd-amavis.conf を編集する。

    amavisd 用 clamd 設定ファイル /usr/local/etc/clamd-amavis.conf を次の要領で編集する。

    • ログファシリティを指定する。
      変更前
      #LogFacility LOG_MAIL
      変更後
      LogFacility LOG_MAIL
    • pid ファイルを変更する。
      変更前
      PidFile /var/run/clamd.pid
      変更後
      PidFile /var/amavis/var/clamd.pid
    • 作業ディレクトリを変更する。
    • 変更前
      TemporaryDirectory /var/clamav/tmp
      変更後
      TemporaryDirectory /var/amavis/tmp
    • ソケットファイルを変更する。
      変更前
      LocalSocket /var/clamav/clamd.socket
      変更後
      LocalSocket /var/amavis/var/clamd.socket
    • ウィルスデータベースチェック間隔を無効にする。
      変更前
      #SelfCheck 600
      変更後
      SelfCheck 0
    • 実効ユーザを指定する。
      変更前
      #User clamav
      変更後
      User amavis

    設定ファイルが正しく作成できたことを確認するために clamd を実際に起動し動作をチェックする。以下はその様子。

    # /usr/local/sbin/clamd -c /usr/local/etc/clamd-amavis.conf
    # sleep 3
    # ps u `cat /var/amavis/var/clamd.pid`
    USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    amavis    4797 28.4 12.5  34620 31968 ?        Ss   18:05   0:07 /usr/local/sbin
    # /usr/local/bin/clamdsh.pl --clamdConf=/usr/local/etc/clamd-amavis.conf
    /var/amavis/var/clamd.socket# PING
    PONG
    /var/amavis/var/clamd.socket# SHUTDOWN
    /var/amavis/var/clamd.socket# exit

    clamdsh で SHUTDOWN コマンドを clamd に送っているので、起動した clamd は停止している。

  3. freshclam から amavisd 用 clamd に更新通知するようにする。

    freshclam の設定ファイル /usr/local/etc/freshclam.conf を次の要領で編集する。

    変更前
    #OnUpdateExecute command
    変更後
    OnUpdateExecute echo RELOAD | /usr/local/bin/clamdsh.pl --clamdConf=/usr/local/etc/clamd-amavis.conf
  4. amavisd 用 clamd 起動スクリプトの準備。

    amavisd 用 clamd の起動スクリプトを作成しておいた。これを /etc/rc.d/init.d/ にコピーして、実行パーミッションを付ける。そして次のようにして有効にする。

    chkconfig --add clamd-amavis
  5. amavisd 用 clamd を起動する。
    /etc/rc.d/init.d/clamd-amavis start
  6. freshclam を再起動する。
    /etc/rc.d/init.d/freshclam restart

clamd を amavisd から使う設定

準備した clamd を amavisd が利用するように amavisd の設定ファイル /usr/local/etc/amavisd.conf を編集する。

/usr/local/etc/amavisd.conf の 350 行目付近に“@av_scanners = (”と書いてある行がある。ここからその丸括弧(開き)に対応する丸括弧(閉じ)までが amavisd が利用するウィルススキャナーの定義になっている。この @av_scanners には他にもたくさんのウィルススキャナーの設定がコメントになって載っているが、後半にはコメントになっていないものある。それらを“# ”を付けてコメントにしておく。正規表現 /^ / にマッチする行を“#”に置き換える操作を @av_scanners の内部に施すと便利。

そしてこの中で次のようにコメントになっている clamd の定義を探す。

# ### http://www.clamav.net/
# ['ClamAV-clamd',
#   \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamav/clamd"],
#   qr/\bOK$/, qr/\bFOUND$/,
#   qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
# # NOTE: run clamd under the same user as amavisd, or run it under its own
# #   uid such as clamav, add user clamav to the amavis group, and then add
# #   AllowSupplementaryGroups to clamd.conf;
# # NOTE: match socket name (LocalSocket) in clamav.conf to the socket name in
# #   this entry; when running chrooted one may prefer socket "$MYHOME/clamd".

ここを次のように書き換える。

  ### http://www.clamav.net/
  ['ClamAV-clamd',
    \&ask_daemon, ["SCAN {}\n", "/var/amavis/var/clamd.socket"],
    qr/\bOK$/, qr/\bFOUND$/,
    qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],
  # NOTE: run clamd under the same user as amavisd, or run it under its own
  #   uid such as clamav, add user clamav to the amavis group, and then add
  #   AllowSupplementaryGroups to clamd.conf;
  # NOTE: match socket name (LocalSocket) in clamav.conf to the socket name in
  #   this entry; when running chrooted one may prefer socket "$MYHOME/clamd".

オリジナルでは clamd の CONTSCAN コマンドを使用しているが、ここでは SCAN コマンドを使用することにする。CONTSCAN は全てのウィルスを見つけようとするが、SCAN コマンドは一つ見つけたらそれでスキャンを終了する。このため感染しているかどうかだけを判定するには SCAN コマンドの方が速いからである。ここでは感染メールあるいはフィッシングメールはドロップする(ユーザに届かせない)方針なので、全てのウィルスを発見する必要は無い。

ここで定義したウィルススキャナー(amavisd 用の clamd)が何らかの理由で使えないときに備えて @av_scanners_backup という設定がある。@av_scanners で列挙したウィルススキャナーが全て使えないときにここに列挙されたものが使用される。これも同じように一旦全てをコメントにした上で ClamAV の設定を有効にする。他のウィルススキャナーが使えるのであればそれも有効にしておく。ClamAV の設定は一旦全てをコメントにした後なら次のようになっている。

# ### http://www.clamav.net/   - backs up clamd or Mail::ClamAV
# ['ClamAV-clamscan', 'clamscan',
#   "--stdout --no-summary -r --tempdir=$TEMPBASE {}",
#   [0], qr/:.*\sFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],

ここのコメントを外して次のようにしておく。

  ### http://www.clamav.net/   - backs up clamd or Mail::ClamAV
  ['ClamAV-clamscan', 'clamscan',
    "--stdout --no-summary -r --tempdir=$TEMPBASE {}",
    [0], qr/:.*\sFOUND$/, qr/^.*?: (?!Infected Archive)(.*) FOUND$/ ],

編集が終わったら間違いがないかどうかをチェックするために amavisd をデバッグモードで起動する。

/usr/local/sbin/amavisd -c /usr/local/etc/amavisd.conf debug

特にエラーがレポートされないことを確認する。amavisd は ctrl-c をタイプして終了させる。

SpamAssassin の準備

SpamAssasin のスパム判定のルールはシステムワイドのもの(/etc/mail/spamassassin/local.cf)とユーザ定義のもの(~/.spamassassin/user_prefs)があるが、ユーザへの負担を少なくするためにシステムワイドのルールをできるだけ強化しておく。このルールはかなり色々な記述ができる。ということはスパムを効率よく判定させるためにはかなりの構築が必要になる。幸いにも TLECよくできたファイルを配布している。これをベースにする。なお、デフォルトではユーザ定義のルールは無効になっている。

このファイルは作者がよく保守をして精度を上げている。その苦労を活かすためにも積極的に更新したい。そこで更新があったら自動でダウンロードし、必要と思われる変更を施す make ファイルを Makefile という名前で次の内容で作成する。作成する場所は /etc/mail/spamassassin である。

SRC_URL = http://tlec.linux.or.jp/docs/user_prefs

local.cf: TLEC.cf
	[ -f '$@' ] && mv '$@' '$@.prev'
	/bin/sed -e 's/^ok_languages/#ok_languages/' TLEC.cf > '$@'
	echo 'report_safe 0' >> '$@'
	/etc/rc.d/init.d/spamassassin restart

TLEC.cf::
	@if [ -f '$@' ]; then \
		echo curl --silent -z '$@' -o '$@' '$(SRC_URL)'; \
		curl --silent -z '$@' -o '$@' '$(SRC_URL)'; \
	else \
		echo curl --silent -z '$@' -o '$@' '$(SRC_URL)'; \
		curl --silent -z '$@' -o '$@' '$(SRC_URL)'; \
	fi

インデントは TAB で行われていることに注意。ここで clamav-update を利用する手もあるのだが、それだとどんなに節約してもバージョン判定のために毎回 HTTP ヘッダだけは取得することになる。この make ファイルのように新しいものがあるときにだけダウンロードした方がネットワークとサーバに負荷をかけないで済む。

TLEC オリジナルでは日本語と英語のメッセージはスパムとしないとしているが、ここではこれらもスパム判定をするようにした。また、スパムと判定されたメッセージはデフォルトではスパム通知のメッセージの添付ファイルになって届けられるが、メッセージヘッダに“X-Spam-*”フィールドを追加するだけにして、それをどうするかはユーザのメーラーの設定に任せたい。そこで添付ファイルとして届けられるのではなくフィールドを追加するだけに変更するようにした。スパムと断定されたものは“X-Spam-Flag: Yes”が付くようになる。

この TLEK のファイルでは、信用するネットワークを設定する trusted_networks と自分が利用している MTA を private_pref というファイルで記述するようになっている。そしてこのファイルを /etc/mail/spamassassin に次の内容で作成する。

trusted_networks 127.0.0.1 設定中のメールサーバが所属する LAN のネットワークアドレス
replace_tag MYMTA (設定中のメールサーバ名にマッチする正規表現)

例えば次のようにする。

trusted_networks 127.0.0.1 192.168.48.0/24
replace_tag MYMTA ((mail|www)\.mydomain\.co\.jp)

そして上で作成した Makefile によって更新のチェックと更新が定期的に行われるようにする。sa-update というファイルを /etc/cron.weekly に次の内容で作成して実行パーミッションを付けておく。

#!/bin/sh

cd /etc/mail/spamassassin
make > /dev/null

spamassasin を rpm でインストールすると /etc/cron.d/sa-update という local.cf をアップデートするためのファイルが入っている。これはデフォルトではコメントだけなので、特に変更していなければ放置で構わない。

以上で spamassasin の設定が終わったのでこれの起動スクリプトを有効化し、起動する。

chkconfig spamassassin on
/etc/rc.d/init.d/spamassassin start

amavisd のポリシー設定

ここではスパムメールや感染メールと判定されたメールの取り扱いについて /usr/local/etc/amavisd.conf を設定する。主に検討するべき箇所を列挙する。

スパム判定結果の閾値

次のような箇所である。

$sa_tag_level_deflt  = 2.0;  # add spam info headers if at, or above that level
$sa_tag2_level_deflt = 6.2;  # add 'spam detected' headers at that level
$sa_kill_level_deflt = 6.9;  # triggers spam evasive actions (e.g. blocks mail)
$sa_dsn_cutoff_level = 10;   # spam level beyond which a DSN is not sent
# $sa_quarantine_cutoff_level = 25; # spam level beyond which quarantine is off

各項目の意味は次のとおり。

$sa_tag_level_deflt

この値以上のスパムらしさを持つメッセージのヘッダにスパム判定の情報を付与する。ユーザがメーラのルールによって迷惑メールかもしれないと注意を始めるのがこのレベルである。逆に言うとこの値未満のものは普通のメールとしてユーザは安心して参照する。

$sa_tag2_level_deflt

この値以上のスパムらしさを持つメッセージのヘッダにスパムと断定したときのマークを付ける。ここでは後にこの値以上のメッセージを迷惑メールフォルダに直接配送するように設定する。ユーザが迷惑メールだと思って見もしないかもしれないのがこのレベルである。

$sa_kill_level_deflt

この値以上のスパムらしさを持つメッセージにスパムと断定されたときのアクションを実行する。例えばそのメールをブロックしたりする。

$sa_dsn_cutoff_level

この値以上のスパムらしさを持つメッセージは配送されない。したがってもし隔離するように設定したならば届いているはずの非迷惑メールが届かなかったらユーザからの問い合わせによって隔離ディレクトリから探し出すことになる。

$sa_quarantine_cutoff_level

この値以上のスパムらしさを持つメッセージは隔離すらされない。メッセージが全く残らないのでこれは設定しない方がよいと思う。

筆者の自宅では一年以上 SpamAssassin を運用している。スコア 2.0 未満でスパムらしさが付かなかったが迷惑メールだったものが約 2.1%、スコア 6.31 以上でスパムと断定されたが迷惑メールでなかったものが約 2.8% あった。迷惑メールでなかったもので最も高いスコアは 20.119 だった。つまりスコア 21 以下を $sa_dsn_cutoff_level$sa_quarantine_cutoff_level に指定すると配送されない非迷惑メールが出てくる。スコアの分布から見て筆者は $sa_tag2_level_deflt は 8 あたりが適切ではないかと考えている。

スパム判定をするメッセージの大きさ

スパム判定をするためにはメッセージの内容をスキャンすることになるのだが、メッセージが大き過ぎるとその処理コストを無視できなくなってくる。そこでスパム判定をするメッセージのボディの最大長が次のように設定されている。

$sa_mail_body_size_limit = 400*1024; # don't waste time on SA if mail is larger
スパムと断定されたメールの件名に付ける文字列

ユーザが使用しているメーラが必ずしも柔軟な振り分けルールを実装してる訳ではない。そういうときに便利なのがスパムと断定されたメールの件名に付ける文字列を指定する機能だ。件名に目印があればそういうメーラでもユーザが到着メールの一覧を目視して判断できる。これが次のように設定されている。

$sa_spam_subject_tag = '***SPAM*** ';

しかし誤判定されたメールにもこれが付いてしまうと、それの返信をするときにうっかりこの文字列を付けたままにして失礼なことにもなってしまうかもしれない。

各種迷惑メールの取り扱い

ここがポリシー上最も重要なところ。次のように設定されている。

# $final_virus_destiny      = D_DISCARD;
# $final_banned_destiny     = D_BOUNCE;
# $final_spam_destiny       = D_BOUNCE;
# $final_bad_header_destiny = D_PASS;

上の例では全てコメントになっていてデフォルト値が指定されている。それぞれの意味は次のとおり。

項目の意味
$final_virus_destiny

感染メールと判定されたメッセージの取り扱い。

$final_banned_destiny

禁止メールと判定されたメッセージの取り扱い。

$final_spam_destiny

スパムメールと判定されたメッセージの取り扱い。

ここが D_PASS 以外になっていると誤判定されたメールがユーザに届かないことになる。そうする場合はスパムと断定するための閾値をかなり高い値に設定しておくべきだろう。

$final_bad_header_destiny

非 ASCII 文字などが含まれているなど不正なヘッダを持つメッセージの取り扱い。

値の意味
D_BOUNCE

そのメッセージは配送しないが、送信者に通知する。

D_REJECT

D_BOUNCE と同様だが、感染メールが大量に来ているときなどは送信者に通知しないらしい。

D_DISCARD

そのメッセージは配送しないし、送信者に通知もしない。

D_PASS

そのメッセージは配送する。

禁止添付ファイルの指定

$banned_filename_re という指定で危険なタイプのファイルが添付されているメールなどが禁止されている。その設定の中で例えば Windows の実行ファイルが次のように設定されている。

  •   qr'^\.(exe-ms|dll)$',                   # banned file(1) types, rudimentary
  •   qr'.\.(pif|scr)$'i,                     # banned extensions - rudimentary
  •   qr'^application/x-msdownload$'i,        # block these MIME types
      qr'^application/x-msdos-program$'i,
      qr'^application/hta$'i,
  •   qr'\.[^./]*[A-Za-z][^./]*\.\s*(exe|vbs|pif|scr|bat|cmd|com|cpl|dll)[.\s]*$'i,
  •   qr'.\.(exe|vbs|pif|scr|cpl)$'i,             # banned extension - basic

以上で amavisd の設定が一通り終わったので amavisd を起動しておく。

/etc/rc.d/init.d/amavisd start

Postfix に amavisd を利用させる設定

一通り準備が整ったので MTA の Postfix に amavisd を使用させるための設定を行う。

まず amavisd を利用したサービスの定義を行うために /etc/postfix/master.cf に次の記述を追加する。

#
# Content Filter amavisd
# 
smtp-amavis unix -	-	n	-	2	smtp
  -o smtp_data_done_timeout=1200
  -o smtp_send_xforward_command=yes
  -o disable_dns_lookups=yes
127.0.0.1:10025 inet n	-	n	-	-	smtpd
  -o content_filter=
  -o local_recipient_maps=
  -o relay_recipient_maps=
  -o smtpd_restriction_classes=
  -o smtpd_client_restrictions=
  -o smtpd_helo_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks=127.0.0.0/8
  -o strict_rfc821_envelopes=yes
  -o smtpd_error_sleep_time=0
  -o smtpd_soft_error_limit=1001
  -o smtpd_hard_error_limit=1000

そして今定義したサービスをコンテントフィルターとして使うようために /etc/postfix/main.cf に次の記述を追加する。

content_filter=smtp-amavis:[127.0.0.1]:10024

これで Postfix で amavisd が使われるように設定されたので Postfix を再起動する。

/etc/rc.d/init.d/postfix restart

迷惑メールを迷惑メールフォルダへ

ここまでで Postfix を通して配送されるメールのスパム判定と感染チェックが行われるようになったのだが、スパムと断定されたメールを受信者に送る設定にしている場合、ローカルユーザにはせめて最初から迷惑メールフォルダに置かれるようにしてきたい。そうすることで、ユーザは迷惑メールに埋もれてメールを見落としてしまうことが減るからである。

まず既存のユーザの迷惑メールフォルダを作る。そのために次の内容でシェルスクリプトを作成して実行する。これはシステムユーザではなく一般ユーザの Maildir がもしなければそれを作成し、その中の迷惑メールフォルダがなければ作成する。そして今後の新しいユーザのためにも、ホームディレクトリのひな形に同じ措置をしておく。ちょっと長いので mkjunkdir として作成しておいた。

#!/bin/sh

for user in `awk -F: '500 <= $3 && $3 < 65534 { print $1; }' /etc/passwd`
do
	home=`awk -F: -v "user=$user" '$1 == user { print $6; }' /etc/passwd`
	if [ \! -d "$home/Maildir" ]; then
		mkdir -p "$home/Maildir/new"
		mkdir -p "$home/Maildir/cur"
		mkdir -p "$home/Maildir/tmp"
		chmod -R 700 "$home/Maildir"
		chown -R $user. "$home/Maildir"
	fi
	if [ \! -d "$home/Maildir/.Junk" ]; then
		echo $user
		mkdir -p "$home/Maildir/.Junk/new"
		mkdir -p "$home/Maildir/.Junk/cur"
		mkdir -p "$home/Maildir/.Junk/tmp"
		chmod -R 700 "$home/Maildir/.Junk"
		chown -R $user. "$home/Maildir/.Junk"
	fi
done

if [ \! -d /etc/skel/Maildir ]; then
	mkdir -p /etc/skel/Maildir/new
	mkdir -p /etc/skel/Maildir/cur
	mkdir -p /etc/skel/Maildir/tmp
	chmod -R 700 /etc/skel/Maildir
fi

if [ \! -d /etc/skel/Maildir/.Junk ]; then
	mkdir -p /etc/skel/Maildir/.Junk/new
	mkdir -p /etc/skel/Maildir/.Junk/cur
	mkdir -p /etc/skel/Maildir/.Junk/tmp
	chmod -R 700 /etc/skel/Maildir/.Junk
fi

次にスパムと断定されたメールが迷惑メールフォルダに直接配送されるようにする。そのために procmail の設定ファイル /etc/procmailrc を作成し(デフォルトでは存在しない)、次の内容を記述する。

SHELL=/bin/bash
PATH=/usr/bin:/bin
DROPPRIVS=yes
MAILDIR=$HOME/Maildir
DEFAULT=$MAILDIR/
JUNK=$MAILDIR/.Junk/
#LOGFILE=$HOME/procmail.log
#VERBOSE=ON

:0
*^X-Spam-Flag: YES
$JUNK
last generated
2009-12-06
page view