Tag: procmail



2013年 4月 28

SpamAssassin

SpamAssasinのみをインストールしたくなったのでメールサーバ再構築のついでに試してみる。メールサーバ構築のまとめ でPostfix+MySQL+postfixadminは構築済みとして想定しています。そちらではウィルスチェックも導入しているため今回はスパムチェックのみの導入。

また、学習機能があるようなので試してみる。スパム判定の精度が高まるみたい。

  • .Spam ディレクトリの作成
  • スパムメールの学習
  • 通常のメールの学習

コレに合わせて postfixadmin +procmailな環境でメールディレクトリの自動作成・削除 のメールディレクトリ作成スクリプトに .Spam を作るコマンドを追加。

SpamAssassinのインストール

yum install spamassassin

procmailの設定

  • バーチャルドメインでのメールアカウントを使用。
  • 保存ディレクトリは /mail/domain.tld/user@domain.tld とする。
  • $DOMAINと$USERは Postfixのmaster.cfで取得している。

/etc/procmailrc を新規作成する。SpamAssassinの起動条件は参考ブログより引用。

# vi /etc/procmailrc

SHELL=/bin/bash
PATH=/usr/bin:/bin
DEFAULT=/mail/$DOMAIN/$USER\@$DOMAIN/
LOCKFILE=/mail/procmail.lock
LOGFILE=/mail/procmail.log   # ログ出力先
#VERBOSE=ON   # 詳細ログ出力

# メールヘッダー中に「 X-Spam-*** 」の記述がなければ spamassassin を起動します
:0fw
*!^X-Spam.*
|spamassassin

# メールヘッダー中に「 X-Spam-Status: Yes 」の記述があれば、「 .Spam 」ディレクトリにメールを格納します
:0
* ^X-Spam-Status: Yes
$DEFAULT/.Spam/

ログの肥大化を防ぐため、ログローテーション設定ファイル新規作成する。

# vi /etc/logrotate.d/procmail

/mail/procmail.log {
    missingok
    nocreate
    notifempty
}

Postfixとprocmailを連携させる

main.cf の設定

# vi /etc/postfix/main.cf

....最終行付近
# virtual_transport = virtual  ←コメントアウト
virtual_transport = procmail  ←追記
procmail_destination_recipient_limit = 1 ←追記

master.cf の設定

# vi /etc/postfix/master.cf

最終行に追記
procmail unix - n n - - pipe
  flags=R user=vuser argv=/usr/bin/procmail -t -m USER=${user} DOMAIN=${nexthop} /etc/procmailrc

SpamAssassin起動

# service spamassassin start

SpamAssassin自動起動設定

# chkconfig spamassassin on

Postfixを再起動して設定を有効化

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

スパムメールの学習

スパムメールの判定制度を上げるために学習する事が出来る。また、迷惑メールではないメールの学習も可能。

スパムメールを学習するコマンド(全てのユーザのSpamフォルダを対象)
# /usr/bin/sa-learn --spam /mail/*/*/.Spam/cur
通常のメールを学習するコマンド(全てのユーザの受信フォルダを対象)
# /usr/bin/sa-learn --ham /mail/*/*/cur

参考ブログではcronに設定していたけど、Spamメールを確認してから手動でコマンドを実行するようにする。~/binにコマンドスクリプトを作成してsudoで実行できるようにしておく。

$ mkdir ~/bin
$ vi ~/bin/spam-learn 
#!/bin/sh

/usr/bin/sa-learn --spam /mail/*/*/.Spam/cur

# スパムメール保存ディレクトリの中身を強制的に消去してよいのなら以下の記述を追加
/bin/rm -f /mail/*/*/.Spam/cur/*
echo 'All Spam Mail Deleted.'

$ chmod 700 ~/bin/spam-learn
$ sudo chown root:root ~/bin/spam-learn

スパムメール学習コマンドを使う時

メーラーでSpamフォルダに迷惑メールしか無いと確認してから以下のコマンドで学習&スパムメール削除

$ sudo spam-learn

入れなおしたらかなりの確率でスパムメールを排除してくれる!

参考:


Filed under: postfix,メールサーバ

Trackback Uri






2011年 1月 6

  • 2013/02/23追記 dovecot2にアップグレードしたエントリーはこちら
  • 2013/02/22追記 TLS対応。エントリーはこちら
  • 2013/01/15追記 wpの設定を変えたこともあり見難いので随時記事を添削します。
  • 2013/01/13追記 PostfixのMySQL対応はyumで出来るようです。詳しくは該当箇所で
  • 2012/08/31追記 master.cf の設定に漏れがありました。詳しくは該当箇所で
  • 2012/09/05追記 main.cf の設定に追加しました。詳しくは該当箇所で

  • 設定項目などはほぼコピペ。自分用のメモ。
    記事中の各リンク先の通り設定したのではなかなか実現できないので多少アレンジしています。

    ローカルのUNIXユーザーはMairdir/方式でメールを使いたい。
    バーチャルドメイン複数の運用、かつ、Web GUIでメールアカウントを管理したい。
    スパムメールとウィルスもチェックしたい。

    このような要望のもと、メールサーバを立て直した際に以前書いた記事をまとめてみた。
    さすがに長文になったので続きを読むにした。

    • CentOS5.5 i386とする
    • MySQLは設定済み前提
    • ローカルのUNIXユーザはMaildir方式でメールを利用する。
      メールボックスは ~/home/username/Mairdir
    • 複数のドメインをバーチャルドメインで扱う。
      メールボックスは /mail/domain.tld/user@domain.tld
    • PostfixをMTAとしてバーチャルドメインでのメールアカウントはMySQLで管理する。
    • Clam AntiVirusでウィルスチェックを行う。
    • SpamAssassinでスパムチェックを行う。このため各メールボックスへの配送(transport)はprocmailで行う。

    スガラボット (守田 直哉)さんのコメントを参考にすると、メールボックスは /mail/domain.tld/user@domain.tld/Mairdir にしておいた方がdovecot2を使う時に良さそうです。

    .. continue reading ..


    Filed under: postfix,インストールメモ

    Trackback Uri






    2009年 10月 15

    メールサーバ構築のまとめ(複数のバーチャルドメイン+Postfix+MySQL+Dovecot+procmail+Clam AntiVirus+spamassassin+postfixadmin) も参考になるかも知れません

    構築環境

    • CentOS5.3
    • Postfix +MySQL
    • Dovecot
    • postfixadmin
    • procmail (spamassassin、Clam AntiVirus でスパムメールとウィルス対策)

    postfixadminを使ってバーチャルドメインでメールサーバを構築するまではうまくいったのだけど、procmailを使うと自動でメールボックスが作成されない。

    もともとメールアカウント削除してもメールボックスが自動で削除されないので付属のシェルスクリプト改で行ってみるテスト。

    postfixadminは /var/www/postfixadmin に設置してあるとし、

    メールは /mail 以下に保存される設定で。
    各ユーザーのメールボックスは /mail/hoge.com/user@hoge.com な感じ。

    メールディレクトリ作成・削除スクリプトは/usr/local/bin/postfixadmin へ保存する。

    メールボックス作成用スクリプト
    /usr/local/bin/postfixadmin/postfixadmin-mailbox-postcreation.sh

    メールボックス削除用スクリプト
    /usr/local/bin/postfixadmin/postfixadmin-mailbox-postdeletion.sh

    ドメイン削除用スクリプト?
    /usr/local/bin/postfixadmin/postfixadmin-domain-postdeletion.sh

    1)メールボックス作成・削除スクリプト準備

    保存用ディレクトリを作成し、postfixadmin/ADDITIONS 内にある、

    postfixadmin-domain-postdeletion.sh
    postfixadmin-mailbox-postcreation.sh
    postfixadmin-mailbox-postdeletion.sh

    を/usr/local/bin/postfixadmin 以下にコピーする。

    # mkdir /usr/local/bin/postfixadmin
    # cp /var/www/postfixadmin/ADDITIONS/postfixadmin-domain-postdeletion.sh /usr/local/bin/postfixadmin
    # cp /var/www/postfixadmin/ADDITIONS/postfixadmin-mailbox-postcreation.sh /usr/local/bin/postfixadmin
    # cp /var/www/postfixadmin/ADDITIONS/postfixadmin-mailbox-postdeletion.sh /usr/local/bin/postfixadmin

    2)削除メールボックスの保存先

    削除したメールボックスは/mail/.deleted-maildirs 以下に保存されるようにする。

    削除したメールボックスを保存するディレクトリ作成

    # mkdir /mail/.deleted-maildirs
    # chmod 0700 /mail/.deleted-maildirs
    # chown vuser:vuser /mail/.deleted-maildirs

    3)スクリプトの編集

    ユーザーメールボックス作成用スクリプトの編集
    # vi /usr/local/bin/postfixadmin/postfixadmin-mailbox-postcreation.sh
    
    #!/bin/sh
    
    # Example script for adding a Maildir to a Courier-IMAP virtual mail
    # hierarchy.
    
    # The script only looks at argument 3, assuming that it
    # indicates the relative name of a maildir, such as
    # "somedomain.com/peter/".
    
    # This script should be run as the user which owns the maildirs. If
    # the script is actually run by the apache user (e.g. through PHP),
    # then you could use "sudo" to grant apache the rights to run
    # this script as the relevant user.
    # Assume this script has been saved as
    # /usr/local/bin/postfixadmin-mailbox-postcreation.sh and has been
    # made executable. Now, an example /etc/sudoers line:
    # apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postcreation.sh
    # The line states that the apache user may run the script as the
    # user "courier" without providing a password.
    
    # Change this to where you keep your virtual mail users' maildirs.
    #basedir=/var/spool/maildirs ←コメントアウト
    basedir=/mail ←追記
    
    if [ ! -e "$basedir" ]; then
        echo "$0: basedir '$basedir' does not exist; bailing out."
        exit 1
    fi
    
    if [ `echo $3 | fgrep '..'` ]; then
        echo "$0: An argument contained a double-dot sequence; bailing out."
        exit 1
    fi
    
    maildir="${basedir}/$3"
    parent=`dirname "$maildir"`
    if [ ! -d "$parent" ]; then
        if [ -e "$parent" ]; then
            echo "$0: strange - directory '$parent' exists, but is not a directory; bailing out."
            exit 1
        else
            mkdir -p "${parent}"
            if [ $? -ne 0 ]; then
                echo "$0: mkdir -p '$parent' returned non-zero; bailing out."
                exit 1
            fi
        fi
    fi
    
    if [ -e "$maildir" ]; then
        echo "$0: Directory '$maildir' already exists! bailing out"
        exit 1
    fi
    
    #maildirmake "$maildir" ←コメントアウト
    #if [ ! -d "$maildir" ]; then
    #    echo "$0: maildirmake didn't produce a directory; bailing out."
    #    exit 1
    #fi
    
    # 以下を追記(maildirmakeの代わり) --->
    mkdir "$maildir"
    if [ ! -d "$maildir" ]; then
        echo "$0: mkdir didn't produce a directory; bailing out."
        exit 1
    fi
    
    mkdir "${maildir}cur"
    if [ ! -d "${maildir}cur" ]; then
        echo "$0: mkdir didn't produce a directory; bailing out."
        exit 1
    fi
    
    mkdir "${maildir}new"
    if [ ! -d "${maildir}new" ]; then
        echo "$0: mkdir didn't produce a directory; bailing out."
        exit 1
    fi
    
    mkdir "${maildir}tmp"
    if [ ! -d "${maildir}tmp" ]; then
        echo "$0: mkdir didn't produce a directory; bailing out."
        exit 1
    fi
    
    mkdir "${maildir}.Spam"
    if [ ! -d "${maildir}tmp" ]; then
        echo "$0: mkdir didn't produce a directory; bailing out."
        exit 1
    fi
    
    chown -R vuser:vuser "$maildir"
    chmod -R 700 "$maildir"
    #<---
    
    exit 0
    ユーザーメールボックス削除スクリプトの編集

    ユーザーメールボックスは、/mail/hoge.com/user@hoge.com の形式としています。

    # vi /usr/local/bin/postfixadmin/postfixadmin-mailbox-postdeletion.sh
    
    #!/bin/sh
    
    # Example script for removing a Maildir from a Courier-IMAP virtual mail
    # hierarchy.
    
    # The script looks at arguments 1 and 2, assuming that they
    # indicate username and domain, respectively.
    
    # The script will not actually delete the maildir. I moves it
    # to a special directory which may once in a while be cleaned up
    # by the system administrator.
    
    # This script should be run as the user which owns the maildirs. If
    # the script is actually run by the apache user (e.g. through PHP),
    # then you could use "sudo" to grant apache the rights to run
    # this script as the relevant user.
    # Assume this script has been saved as
    # /usr/local/bin/postfixadmin-mailbox-postdeletion.sh and has been
    # made executable. Now, an example /etc/sudoers line:
    # apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-mailbox-postdeletion.sh
    # The line states that the apache user may run the script as the
    # user "courier" without providing a password.
    
    # Change this to where you keep your virtual mail users' maildirs.
    #basedir=/var/spool/maildirs ←コメントアウト
    basedir=/mail ←追記
    
    # Change this to where you would like deleted maildirs to reside.
    #trashbase=/var/spool/deleted-maildirs ←コメントアウト
    trashbase=/mail/.deleted-maildirs ← 追記
    
    if [ ! -e "$trashbase" ]; then
        echo "trashbase '$trashbase' does not exist; bailing out."
        exit 1
    fi
    
    if [ `echo $1 | fgrep '..'` ]; then
        echo "First argument contained a double-dot sequence; bailing out."
        exit 1
    fi
    if [ `echo $2 | fgrep '..'` ]; then
        echo "First argument contained a double-dot sequence; bailing out."
        exit 1
    fi
    
    #subdir=`echo "$1" | sed 's/@.*//'` ←コメントアウト
    subdir=$1 ← 追記
    
    maildir="${basedir}/$2/${subdir}"
    trashdir="${trashbase}/$2/`date +%F_%T`_${subdir}"
    
    parent=`dirname "$trashdir"`
    if [ ! -d "$parent" ]; then
        if [ -e "$parent" ]; then
            echo "Strainge - directory '$parent' exists, but is not a directory."
            echo "Bailing out."
            exit 1
        else
            mkdir -p "$parent"
            if [ $? -ne 0 ]; then
                echo "mkdir -p '$parent' returned non-zero; bailing out."
                exit 1
            fi
        fi
    fi
    
    if [ ! -e "$maildir" ]; then
        echo "maildir '$maildir' does not exist; nothing to do."
        exit 1
    fi
    if [ -e "$trashdir" ]; then
        echo "trashdir '$trashdir' already exists; bailing out."
        exit 1
    fi
    
    mv $maildir $trashdir
    
    exit $?

    ドメイン削除用スクリプトの編集

    # vi /usr/local/bin/postfixadmin/postfixadmin-domain-postdeletion.sh
    
    #!/bin/sh
    
    # Example script for removing a Maildir domain top-level folder
    # from a Courier-IMAP virtual mail hierarchy.
    
    # The script only looks at argument 1, assuming that it
    # indicates the relative name of a domain, such as
    # "somedomain.com". If $basedir/somedomain.com exists, it will
    # be removed.
    
    # The script will not actually delete the directory. I moves it
    # to a special directory which may once in a while be cleaned up
    # by the system administrator.
    
    # This script should be run as the user which owns the maildirs. If
    # the script is actually run by the apache user (e.g. through PHP),
    # then you could use "sudo" to grant apache the rights to run
    # this script as the relevant user.
    # Assume this script has been saved as
    # /usr/local/bin/postfixadmin-domain-postdeletion.sh and has been
    # made executable. Now, an example /etc/sudoers line:
    # apache ALL=(courier) NOPASSWD: /usr/local/bin/postfixadmin-domain-postdeletion.sh
    # The line states that the apache user may run the script as the
    # user "courier" without providing a password.
    
    # Change this to where you keep your virtual mail users' maildirs.
    #basedir=/var/spool/maildirs ←コメントアウト
    basedir=/mail ←追記
    
    # Change this to where you would like deleted maildirs to reside.
    #trashbase=/var/spool/deleted-maildirs ←コメントアウト
    trashbase=/mail/.deleted-maildirs ←追記
    
    if [ `echo $1 | fgrep '..'` ]; then
        echo "First argument contained a double-dot sequence; bailing out."
        exit 1
    fi
    
    if [ ! -e "$trashbase" ]; then
        echo "trashbase '$trashbase' does not exist; bailing out."
        exit 1
    fi
    
    trashdir="${trashbase}/`date +%F_%T`_$1"
    domaindir="${basedir}/$1"
    
    if [ ! -e "$domaindir" ]; then
        echo "Directory '$domaindir' does not exits; nothing to do."
        exit 0;
    fi
    if [ ! -d "$domaindir" ]; then
        echo "'$domaindir' is not a directory; bailing out."
        exit 1
    fi
    if [ -e "$trashdir" ]; then
        echo "Directory '$trashdir' already exits; bailing out."
        exit 1;
    fi
    
    mv $domaindir $trashdir
    
    exit $?

    実行権を与える

    # chmod 0700 /usr/local/bin/postfixadmin/postfixadmin*

    4)postfixadminの設定ファイルを修正

    # vi /var/www/postfixadmin/config.inc.php
    
    // Optional:
    // Script to run after creation of mailboxes.
    // Note that this may fail if PHP is run in "safe mode", or if
    // operating system features (such as SELinux) or limitations
    // prevent the web-server from executing external scripts.
    // $CONF['mailbox_postcreation_script']='sudo -u courier /usr/local/bin/postfixadmin-mailbox-postcreation.sh';
    $CONF['mailbox_postcreation_script']='sudo /usr/local/bin/postfixadmin/postfixadmin-mailbox-postcreation.sh'; ←追記
    
    // Optional:
    // Script to run after deletion of mailboxes.
    // Note that this may fail if PHP is run in "safe mode", or if
    // operating system features (such as SELinux) or limitations
    // prevent the web-server from executing external scripts.
    // $CONF['mailbox_postdeletion_script']='sudo -u courier /usr/local/bin/postfixadmin-mailbox-postdeletion.sh';
    $CONF['mailbox_postdeletion_script']='sudo /usr/local/bin/postfixadmin/postfixadmin-mailbox-postdeletion.sh'; ←追記
    
    // Optional:
    // Script to run after deletion of domains.
    // Note that this may fail if PHP is run in "safe mode", or if
    // operating system features (such as SELinux) or limitations
    // prevent the web-server from executing external scripts.
    // $CONF['domain_postdeletion_script']='sudo -u courier /usr/local/bin/postfixadmin-domain-postdeletion.sh';
    $CONF['domain_postdeletion_script']='sudo /usr/local/bin/postfixadmin/postfixadmin-domain-postdeletion.sh';  ←追記
    

    5)sudo を使用するので/etc/sudoers を編集する。

    どうやら最近のマシンではエラーが出るらしいので併せて対処。
    エラーログは
    /etc/httpd/logs/error_log や /var/log/httpd/ssl_error_log 等のapacheのログ

    参考:sudoが「sudo: sorry, you must have a tty to run sudo」と文句を言うときは

    webサーバ(apache)のhttpd.conf設定は
    User apache
    Group apache
    としています。

    2012/2/18追記
    コメントをいただきました。
    本文では
    #Defaults requiretty とコメントアウトしていますが、

    Defaults requiretty ← この行は そのまま にします
    Defaults:apache !requiretty ← これを 追記 します

    のようにするとセキュリティ的にちょっと安心できそうです。

    # visudo
    
    #
    # Disable "ssh hostname sudo ", because it will show the password in clear.
    #         You have to run "ssh -t hostname sudo ".
    #
    #Defaults    requiretty ←コメントアウト
    
    Defaults    env_reset
    Defaults    env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
                            LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
                            LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
                            LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
                            LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
                            _XKB_CHARSET XAUTHORITY"
    
    ## Next comes the main part: which users can run what software on
    ## which machines (the sudoers file can be shared between multiple
    ## systems).
    ## Syntax:
    ##
    ##      user    MACHINE=COMMANDS
    ##
    ## The COMMANDS section may have other options added to it.
    ##
    ## Allow root to run any commands anywhere
    root    ALL=(ALL)       ALL
    
    # 以下を追記 -----
    apache ALL=(ALL) NOPASSWD: /usr/local/bin/postfixadmin/postfixadmin-mailbox-postcreation.sh
    apache ALL=(ALL) NOPASSWD: /usr/local/bin/postfixadmin/postfixadmin-mailbox-postdeletion.sh
    apache ALL=(ALL) NOPASSWD: /usr/local/bin/postfixadmin/postfixadmin-domain-postdeletion.sh
    -----

    テスト

    postfixadminでメールアカウントの作成・削除を行って、該当のメールボックスの状況を確認する。

    ドメイン追加・削除を行う場合は、ドメインの追加後メールユーザーを1つ以上追加する必要がある。(ドメイン追加のみだとディレクトリが作成されない為)

    気になる事

    visudo でコメントアウトした

    #Defaults requiretty ←コメントアウト

    が、セキュリティー面でどうなのか、と。

    2011-01-14追記

    apacheユーザーなど 非シェルログインユーザーがsudoを実行できるようにするのに必要らしい。
    phpからsudoする時なども同様のようだ。


    Filed under: CentOS5.x,postfix,postfixadmin,メールサーバ

    Trackback Uri