Rspamdで迷惑メールを判定

Rspamd

この記事ではRmilterを使っているけどRspamd1.6以降Rmilterは使わない方向みたい。

2018年4月28日変更:
Rspamd1.6から1.7.3までの変更でだいぶ変わっていて備忘録として役に立たないので1.7.3で使える内容に一部更新・変更した。

うちのメールサーバ(INTAA.NET)の中でどうにかしたいと思っていたのが迷惑メール判定を行うSpamAssassin。Perlのお化けみたいなツールで処理速度が遅いし扱いづらい。ソフトウエアの更新という面でも。
で、以前から目を付けていたのがRspamdというスパム判定ツール。目をつけたといってもブラウザのブックマークに登録した程度のレベルだけど。
RspamdとSpamAssassinとDSPAMの比較ページを見るとSpamAssassinからの乗り換え対象としてはRspamdはなかなか良さげ。もっともRspamdのサイトのページなのでRspamdが悪くなる比較である筈はないかな。

今回はRspamdのバージョン1.6がリリースされた記念に入れてみることに。

インストール

導入対象サーバがFreeBSDなのでportsで入れる。
インストールするportsは以下。

  • mail/rspamd
  • mail/rmilter
  • databases/redis
  • mail/dcc-dccd (好みで)

アンチウイルス関係はこの記事では対象外とする。

print/transfigなど幾つかたちの悪いportsが絡むのでビルドエラーになったら一つ一つ内容を確認しながら潰していく必要があるかも。 おそらくこんなん欲しくないと思うような余計なのも入れられる筈。うちの環境ではTexLiveまで入れられた フザケンナ。

/etc/rc.conf (自動起動用 以下4行追加)
1
2
3
4
rmilter_enable="YES"
rspamd_enable="YES"
redis_enable="YES"
dccifd_enable="YES" #使うなら

Postfix設定

Postfixのmain.cfのmilterの項目にrmilterを追加する。

/usr/local/etc/postfix/main.cf (追加と変更)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# rspamd
milter_mail_macros =  i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_protocol = 6

smtpd_milters =
        inet:127.0.0.1:10025
        unix:/var/run/rmilter/rmilter.sock
        unix:/var/run/clamav/clmilter.sock   #ClamAVをRspamdとは全く別で使うなら   
                                             
#       unix:/var/run/spamass-milter.sock    #外す(SpamAssassin用)
                                           
                                             
non_smtpd_milters =                          
        inet:127.0.0.1:10025                 
        unix:/var/run/rmilter/rmilter.sock
        unix:/var/run/clamav/clmilter.sock   #ClamAVをRspamdとは全く別で使うなら
                                             
#       unix:/var/run/spamass-milter.sock    #外す(SpamAssassin用) 

SpamAssassinのspamass-milterを使っていたならその行はコメントにして外すか削除。

Rmilterの設定

/usr/local/etc/rmilter.conf (該当箇所変更)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
spamd {
    whitelist = 127.0.0.1/32, [::1]/128, 192.168.0.0/24, [2001:db8::]/32 ;
    extended_spam_headers = yes;
    spamd_never_reject = yes;
};

limits {
    enable = no;
};

greylisting {
    enable = no;
};

スパム判定しないアドレスを列挙する。192.168.0.0/24はMTAのあるIPv4のネットワーク、[2001:db8::]/32はMTAのあるIPv6のネットワーク。どちらも実際に使っているネットワークに合わせる。IPv6のアドレスは[]で括る。
導入後暫くはメールヘッダに判定要素を詳しく表示したいのでextended_spam_headersを有効に。ただし、スパム対策の手の内を明かすことになるので設定が十分に煮詰まったら無効にするのを忘れずに。
4行目のspamd_never_rejectは元のrmilter.confには入っていなかったが、この行を追加して値をyesにしておかないと迷惑メールの判定基準のスコアを超えたメールが自動削除になる。迷惑判定のFalse positiveの可能性を考えると勝手に削除になってしまうのは困るので追加した。後述のmaildropで迷惑メールをSpamフォルダに振り分ける。
limitsは使わない(ことにした)。
greylistingは遅延とか再送されないなどのトラブルの元なので採用しない(ことにした)。

Rspamd1.6以降はRmilterを使わない方向(現在は使っても可)になったようだが、Rmilterにしかspamd_never_rejectに相当するオプションが無い。だからRmilterを使わなければ迷惑メールと判断されても弾かずに受けるということが(素直には)できないみたい。Rejectのスコアを引き上げて使うというのは中途半端。Rspamd単独の方がスマートなんだけどなぁ。)
上手い方法があればRmilterを外したい。

2018年4月28日追記:
Rspamd 1.7.1以降でアクション設定が変わったのでRmilterを使用する必要はほぼ無くなったかと思われる。Rmilter無しの設定はRspamdの設定 (Rmilter無し)を参照下さい。

Redisの設定

/usr/local/etc/redis.conf
1
2
3
bind 127.0.0.1 ::1
maxmemory 500mb          #500MBまでの使用を許可
maxmemory-policy volatile-lru

DCCの設定

設定を触るとしたら設定ファイルは /usr/local/dcc/dcc_conf だろうけど、書かれている初期値を触る必要はあまりなさそうに見える。

etc/crontab (1行追加)
32 3 * * * root /usr/bin/find /usr/local/dcc/log/ -not -newermt '1 days ago' -delete

Rspamdの設定

Rspamdの設定ファイルは/usr/local/etc/rspamdにある。
Rspamdの流儀に従うなら元から存在する設定ファイルは編集せずにlocalファイルを作成するか別ファイルにオーバーライド(上書き)する設定だけを書くということになっている。
portsでインストールしたなら殆どの場合はports更新で既存の設定ファイルを上書きされることは無いかと思われるが絶対とは限らないので一応流儀に従っておいた方が後々困らないかと。

ローカル用とオーバーライド用のディレクトリを作成する。
# mkdir /usr/local/etc/rspamd/local.d
# mkdir /usr/local/etc/rspamd/override.d
/usr/local/etc/rspamd/override.d/metrics.conf (この設定は使わない)
1
2
3
4
5
6
7
8
actions {
    reject = 10;
}
group "spf" {
    symbol "R_SPF_DNSFAIL" {
        weight = 2.0;
    }
}

このファイルの設定はがらっと変わったので上の設定内容は使わずにRspamd 1.7系のアクション設定の変更を参照下さい。

rejectの値、標準値では迷惑メールのしきい値が15点となっている。これは迷惑メール判定要素の合計点が10点を超えると迷惑メールと判定する。これはちょっと高すぎるので10点に下げた。この記事のように迷惑メールを削除しないで迷惑メール用フォルダに振り分けるということを行わないならこの値を下げることはオススメしない。迷惑メールと誤判定されて削除されてしまったということが頻発しかねない。
ルール設定のmetrics.confでは標準のR_SPF_DNSFAILのウエイト(スコアじゃない)0を2に変更した。

/usr/local/etc/rspamd/local.d/greylist.conf (新規)
enabled = false;

greylistingを使用したくないので指定した。いんや俺っちは使いたいんよという場合は要らない。

/usr/local/etc/rspamd/override.d/redis.conf (新規)
1
2
3
## servers = "127.0.0.1";       #Rspamd 1.6系用
write_servers = "127.0.0.1";    #Rspamd 1.7系用
read_servers = "127.0.0.1";     #Rspamd 1.7系用

インメモリDBのRedisが存在するサーバを指定。この記事的にはRspamdと同じサーバ。

/usr/local/etc/rspamd/local.d/dcc.conf (新規)
1
2
host = "/usr/local/dcc/dccifd";    #FreeBSDのpkg/portsでの構成
timeout = 10;
/usr/local/etc/rspamd/override.d/phishing.conf (新規)
1
2
3
openphish_enabled = true;
phishtank_enabled = true;
phishtank_map = "https://example.com/phishtank/online-valid.json.zst";

2019年1月20日追記: Rspamd1.8.0で大きな変更が入っているので最新のドキュメントに従って設定のこと。

せっかくなのでフィッシング判定も有効にする。
3行目は重要。/usr/local/etc/rspamd/modules.d/phishing.confの標準値ではrspamd.comにあるonline-valid.json.zstを指定してあるが、このファイルは巨大でダウンロードに10分程度かかる(ことがある)のでcronなどで1,2時間毎に定期的にダウンロードして自前のウェブサーバに置くなどするのが良さげ。

追記:
phishtankを有効にするとメモリを激しく消費する。サーバーのメモリを全て食い潰してハングアップすることもあるので注意。

/usr/local/etc/rspamd/local.d/classifier-bayes.conf (新規)
1
2
backend = "redis";
autolearn = true;
/usr/local/etc/rspamd/local.d/url_reputation.conf (新規)
enabled = true;
/usr/local/etc/rspamd/local.d/url_tags.conf (新規)
enabled = true;

Web UIの設定

引き続きRspamdの設定だが、ウェブの設定だけ別建て。
管理者がウェブ管理画面にログインする為のパスワードを作成する。

$ /usr/local/bin/rspamadm pw
Enter passphrase: パスワード/パスフレーズを入力[Enter]
$2$???????????????????????????????????????????????????????????????????????

$2$で始まる文字列が表示されるのでそれをコピーして下の設定ファイルに書き込む。

/usr/local/etc/rspamd/local.d/worker-controller.inc (新規)
1
2
password = "$2$?????????(中略)????????????";
enable_password = "$2$?????????(中略)????????????";

enable_passwordはデータ変更を伴う操作用みたいなことが書いてある。

ウェブサーバに設定を追加。下はNginxの場合。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
server {

  #既存の設定hogehoge
  
  location /rspamd/ {
    proxy_pass       http://localhost:11334/;
    proxy_set_header Host      $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

location /rspamd/ を指定しているのでアクセス用のURLはhttp[s]://example.com/rspamd/になる。
シンプル過ぎるので解りにくいものに変更するのもあり。一応パスワードによる認証があるのでそこまで神経質になる必要はないかも。

Nginxをリロード。(設定を適用)
# service nginx reload

迷惑メールの振り分け

2018年4月28日追記:
maildropではなくDovecot-LMTPを使うならDovecotのインストール 配送をmaildropからDovecot-LMTPに変更を参照下さい。

迷惑メールと判定されたメールをreject(削除)させるなら不要だが、上のrmilter.confの設定でspamd_never_reject = yes;を指定したなら判定したメールのヘッダにフラグを付けただけの状態なのでそのままメールボックスに送ったら意味がない。フラグを元に振り分けてやる。
メールの振り分けにmaildropを使っているなら迷惑メールの隔離はこんな感じ。

/usr/local/etc/postfix/main.cf (Postfix)
1
2
3
maildrop_destination_concurrency_limit = 2
maildrop_destination_recipient_limit = 1
virtual_transport = maildrop
/usr/local/etc/maildroprc (FreeBSD portsでのファイル配置)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
VERBOSE 5
SHELL="/bin/sh"
logfile "/var/log/maildrop.log"
MAILFOLDER = "$HOME/$6/$2"
export $MAILFOLDER
SPAMFOLDER = "$MAILFOLDER/.Spam"
export $SPAMFOLDER

`test -d $MAILFOLDER`
if ($RETURNCODE != 0)
{
    `/usr/local/bin/maildirmake $MAILFOLDER`
    `/usr/sbin/chown -R vmail:vmail $MAILFOLDER`
}

`test -d $SPAMFOLDER`
if ($RETURNCODE == 0)
{
    if (/^(X-Spamd-Result: default: True|X-Spam: yes)/)
    {
        to "$SPAMFOLDER"
    }
}
to "$MAILFOLDER"

$homeはメール置き場のトップディレクトリ、$6はドメイン名、$2はユーザー名(メールアドレス)。
上は最小限のことしか書いてないのでその他必要なことを追加しないと使い物にならない。
まだ使い始めでよく理解していないが、X-Spamd-Result: default: FalseでX-Spam: yesという場合があるようなので両方書いている。

使用開始

# service redis start
# service dccifd start
# service rmilter start
# service rspamd start
# service postfix restart

RmilterとRspamdを起動してPostfixを再起動する。

# cat /var/log/rspamd/rspamd.log

起動したらすぐに100KBほどのログができるが一応異常がないか一通り見ておいたほうが無難。

# tail -F /var/log/maillog

同様にPostfixのログも確認しRspamdとの連携でエラーになっていないことを確認。

以上でかろうじて「動く」ところまではたどり着いたが、「ルールの素」しか登録されていないので学習の進んだSpamAssassinのように高い精度?で迷惑メールを弾くまでには至っていない。
SpamAssassinのようにルールファイルが溢れるように存在しないので地道に作るかSpamAssassinから移植する必要がある。ベイジアンフィルタに学習させることも必要。

Web UIを見てみる

Rspamd 1
ログイン後最初の画面(Status)。Glaylisting使ってるじゃんってグラフになっているけど、設定中のものなのでご容赦。

Rspamd 2
ルール系の画面(Symbols)。こちらは使い方をまだ理解していない。
判定ルールのスコアを変えることができるみたい。数値を変更するときは一気に大きく変えずに様子をみながら徐々に。これはSpamAssassinで学んだこと。

Rspamd 3
学習用画面(Learning)。
迷惑メールなのにそう判断しなかった、迷惑メールじゃないのに迷惑メールと判断した、という場合にそのメールのソースをこの画面で登録して学習させる。もちろん、Web UIじゃなくてコマンドでも可能だけどサーバにSSHでログインできない遠隔地から学習させられるのは良いよね。でも、自分のところでは学習用のメールフォルダに振り分けたら学習するようにしてるから要らない機能だけど。
この画像はブラウザの幅を800pxにして撮ったので縦並びになっているけど、この状態だとInsert raw SPAM sourceに迷惑メールのソースを入力した後に[Upload text]ボタンを押せない。ブラウザの幅を広げてやると押せるようになるみたい。

Rspamd 4
設定ファイルの画面(Configuration)。
ファイルリストに緑色の[Write]が付いている設定はこの設定画面から変更保存ができる。なかなか良いんじゃないかな。

次の記事でもう少しやりたい。

2017年6月24日追記:
RmilterとRspamdで重複する設定があって何でかな?と思っていたが、Rspamdのサイトの1.6の紹介ページにサラッとRmilterは廃止の方向でって書いてあってアングリ。
Rmilterを使わない設定を追記した。なお、Rmilterを使ったらダメなわけではなさそう。

2017年7月10日追記:
Rmilterを使わない設定をこの記事に入れていたが、なんか解りにくくなってるので別記事にした。
この記事に追加したRmilter無しの部分は削除。

関連記事: