ELK Stackでシステム監視 Rspamd 1.7系のElasticsearchモジュールを試す

メールサーバの迷惑メール除去ツールRspamd1.7系がリリースされたけど、1.7.0が出てすぐに1.7.1が出た。Fixが多いところを見ると1.7.0はヤバかった?
1.7.0への更新準備を進めていたが、結果的に1.7.0にすることなく1.7.1を入れることになった。
また、1.7系ではElasticsearch moduleが追加されたので試してみた。(Rspamdの統計情報をelasticsearchに送信する機能)

Rspamdを1.7.1に更新

FreeBSDのportsの場合
# portupgrade rspamd-1.6.6_1

これで1.6.6_1から1.7.1に更新できた。

1.7.0への更新準備中にportsを確認していてファイルが1つ足りないと思ったが、1.7.1のportsでは直されていた。

# cp -p /usr/ports/mail/rspamd/work/rspamd-1.7.0/lualib/lua_squeeze_rules.lua /usr/local/share/rspamd/lua/

Rspamdを1.7.1の設定

更新したらコンフィグウィザード コマンドを実行。これはrspamadm configwizardを使ったことがなければ新規でも更新でも。更新の場合はclassifier-bayes.confとredis.confの設定の書き方変更に対応してるっぽい。

# rspamadm configwizard
symbol BAYES_SPAM has registered in multiple groups: statistics and bayes
symbol R_DKIM_REJECT has registered in multiple groups: policies and dkim
symbol R_DKIM_ALLOW has registered in multiple groups: policies and dkim
symbol R_DKIM_TEMPFAIL has registered in multiple groups: policies and dkim
symbol R_SPF_FAIL has registered in multiple groups: policies and spf
symbol R_SPF_DNSFAIL has registered in multiple groups: policies and spf
symbol R_SPF_ALLOW has registered in multiple groups: policies and spf
symbol R_SPF_SOFTFAIL has registered in multiple groups: policies and spf
cannot register delayed condition for DMARC_POLICY_ALLOW
cannot register delayed condition for R_SPF_ALLOW
cannot register delayed condition for R_DKIM_ALLOW
cannot find dependency on symbol FREEMAIL_FROM
cannot find dependency on symbol FREEMAIL_REPLYTO
  ____                                     _
 |  _ \  ___  _ __    __ _  _ __ ___    __| |
 | |_) |/ __|| '_ \  / _` || '_ ` _ \  / _` |
 |  _ < \__ \| |_) || (_| || | | | | || (_| |
 |_| \_\|___/| .__/  \__,_||_| |_| |_| \__,_|
             |_|

Welcome to the configuration tool
We use /usr/local/etc/rspamd/rspamd.conf configuration file, writing results to /usr/local/etc/rspamd
Modules enabled:
Modules disabled (explicitly):
Modules disabled (unconfigured):
Modules disabled (no Redis):
Modules disabled (experimental):
Modules disabled (failed):
Do you wish to continue?[Y/n]: y
Redis servers are not set:
The following modules will be enabled if you add Redis servers:
Do you wish to set Redis servers?[Y/n]: y
Input read only servers separated by `,` [default: localhost]:localhost
Input write only servers separated by `,` [default: localhost]:localhost
Do you have any password set for your Redis?[y/N]: n
Do you have any specific database for your Redis?[y/N]: n
Do you want to setup dkim signing feature?[y/N]:n
You are using an old schema for BAYES_HAM/BAYES_SPAM
Do you wish to convert data to the new schema?[Y/n]:y
Expire time for new tokens  [default: 100d]:100d
converted 107385 elements from symbol BAYES_SPAM
converted 73304 elements from symbol BAYES_HAM
Conversion succeed
File: /usr/local/etc/rspamd/local.d/classifier-bayes.conf, changes list:
new_schema => true
expire => 8640000

File: /usr/local/etc/rspamd/local.d/redis.conf, changes list:
write_servers => localhost
read_servers => localhost

Apply changes?[Y/n]: y
2 changes applied, the wizard is finished now
*** Please reload the Rspamd configuration ***

質問の後に表示されている標準値でよければ値を入力せずに[Enter]でも可。

1.7.0以降は /usr/local/etc/rspamd/override.d/metrics.conf または /usr/local/etc/rspamd/local.d/metrics.conf に、group{ hoge } があると動かないようなので消す。 action { hoge } はmetrics.confではなくactions.confに action {hoge}の hogeだけを書く。

場合によってはどうにもRspamdが起動しないことがあるようだが、既存の /var/db/rspamd または /var/db/redis を退避して新しい/var/db/rspamd, /var/db/redisで試すとか・・・
redisのデータを退避する場合はredisも再起動。

RspamdのElasticsearch moduleの設定

Rspamdに追加になったElasticsearch moduleだが、Rspamd側は簡単っぽい。

/usr/local/etc/rspamd/local.d/elastic.conf (新規作成)
1
2
server = "192.168.2.24:9200";    #elasticsearchのホストとポートを指定
use_https = false;               #非HTTPSの場合(これは効くのか不明)
Rspamd用のテンプレートをelasticsearchに登録する。
% curl -H "Content-Type: application/json" -XPUT 'http://192.168.2.24:9200/_template/rspamd' -d@/usr/local/share/rspamd/elastic/rspamd_template.json
{"acknowledged":true} %
192.168.2.24:9200はelasticsearchが動いているホストとポートとする。返答がacknowledged:trueであれば成功。elasticsearch6系以降では Content-Type: application/json の指定が必須。5系なら不要。
または、上のようにやらずに /usr/local/share/rspamd/elastic/rspamd_template.json の中身をコピーしてKibanaのDev Toolsで1行目に PUT /_template/rspamd と記入して2行目以下にrspamd_template.jsonの中身をペーストして実行でも可。

Rspamd側は設定終わり。Rspamdを再起動しておく。次のingest-geoipプラグインを入れてelasticsearchを再立ち上げしてからの方が良いかも。

elasticsearch側の準備

elasticsearchにingest-geoipプラグインが必要らしい。

# cd /usr/local/lib/elasticsearch/bin
# ./elasticsearch-plugin install ingest-geoip
-> Downloading ingest-geoip from elastic
[=================================================] 100%
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.lang.RuntimePermission accessDeclaredMembers
* java.lang.reflect.ReflectPermission suppressAccessChecks
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
-> Installed ingest-geoip
# chown -R elasticsearch:elasticsearch /usr/local/lib/elasticsearch/plugins

インストールしただけではファイルのオーナーの関係でelasticsearchが動かなくなるようなので変更しておく。
elasticsearchを起動して暫く様子をみてエラーにならないこと。

Rspamdからelasticsearchに送られる情報

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
{
  "_index": "rspamd-2018.03.23",
  "_type": "logs",
  "_id": "cfU_UmIBGcJ9bE3-_I6C",
  "_version": 1,
  "_score": null,
  "_source": {
    "rspamd_meta": {
      "rcpt": [
        "foobar@example.com"
      ],
      "geoip": {
        "continent_name": "North America",
        "city_name": "Albuquerque",
        "country_iso_code": "US",
        "region_name": "New Mexico",
        "location": {
          "lon": -10*.**07,
          "lat": 3*.*091
        }
      },
      "header_to": [
        "<foobar@example.com>"
      ],
      "header_subject": [
        "Google earth flight simulator controls"
      ],
      "ip": "64.***.***.212",
      "message_id": "3xu57y1dn6v3wyax-hgtchh9afoztlxi4-f20e3e91@*****.us",
      "header_date": [
        "Fri, 23 Mar 2018 04:43:39 -0500"
      ],
      "qid": "DC810177F4DA",
      "symbols": [
        {
          "score": -0.01591,
          "options": [
            "country: US(-0.08)"
          ],
          "name": "IP_SCORE",
          "group": "reputation"
        },
        {
          "score": 2,
          "options": [
            "212.***.***.64.zen.spamhaus.org : 127.0.0.3"
          ],
          "name": "RBL_SPAMHAUS_CSS",
          "group": "rbl"
        },
        {
          "score": 0.917949,
          "options": [
            "95.9%"
          ],
          "name": "R_PARTS_DIFFER",
          "group": "body"
        },
Spam判定要因部分
大量すぎるので中略
      ],
      "score": 36.406363,
      "header_from": [
        "\"Google Flight Simulator\" <virtualpilot@*****.us>"
      ],
      "action": "add header",
      "from": "8678-1348-4061019793-2725-foobar=example.com@mail.*****.us",
      "webmail": false,
      "is_local": false,
      "asn": {
        "country": "US",
        "ipnet": "64.***.***.0/24",
        "asn": "63018"
      },
      "user": "unknown",
      "direction": "Inbound"
    },
    "@timestamp": "1521798350369.5"
  },
  "fields": {
    "@timestamp": [
      "2018-03-23T09:45:50.369Z"
    ]
  },
  "sort": [
    1521798350369
  ]
}

省略と伏せ字とメールアドレスを置換した部分以外はそのままのデータ。
迷惑メールの情報だけがelasticsearchに送られるのかと思ってたら全メールの情報みたい。メール1件あたりのデータが多いのでメールが大量に届いたときが怖い。これは今後Rspamdのelastic.confで送信する情報を絞れるようにして欲しいところ。

Rspamdの情報をKibanaで表示。

うちの環境ではRspamdからelasticsearchに最初のデータが流れ始めるまで何故かとても時間がかかる。サーバーにメールが届くの関係なく数十分〜数時間?一度流れ始めれば問題ないようだが。
データが流れ始めたらおそらくrspamd-yyyy.mm.dd(←今日の日付)というインデックスでデータが溜まり始めている筈。Kibanaではインデックスパターンを登録してやらないと使えないデータなので左列メニューの (Management)からIndex Patternsを選択し、 Index Patterns をクリック、 左上の方の Create Index Pattern をクリック。
インデックスパターンには rspamd-* を指定、右の[ Next step ]ボタンを押す。タイムスタンプとしては@timestampを選択して作成。
なお、rspamd-yyyy.mm.dd(←今日の日付)というインデックスが作成されてそこに1件以上のデータが存在しないとインデックスパターンは作成できないのでデータが流れていることを確認してからとなる。

Rspamd付属のKibanaダッシュボード

Rspamd1.7.1に付属のKibanaダッシュボード&VisualizeのJsonファイル (/usr/local/share/rspamd/elastic/kibana.json)はかなり酷い造り。
雑なことにかけては定評のある「がとらぼ」の中の人から見ても凄い雑。というか、作りかけなのかしら?
部品のIDは合ってないわ、足りないわで逆に苦労するので使わない方が良さげ。おそらく自分で作る方が早い。

Rspamd付属のダッシュボードテンプレートを表示
いちおう、Rspamd付属のJsonファイルから直せる範囲で修正してKibanaで表示してみた。1つ足りない部品(Visualize)はそもそも何用なのか不明。
地図2つが同じ内容(地点)を表示してる気が・・・
一番下は数字(メール受信数)の下に受信者のメールアドレスが表示されているのをボカしている。

他人が作ったこういうのは何のデータから何を意図して表示しているのかすぐに解らないので個人的には好きじゃない。出来上がりがショボくても構わないから試行錯誤しながら自分で作りたい。もしくは他の人のを見るなら参考としてのレシピ程度?

2018年3月24日追記:

1つだけ作ってみた。受信メールのスループット、要するに受信したときのアクション別グラフ。RspamdのWebUIだとRspamd throughputのようなもの。上の画像の円グラフを時系列のグラフにした感じ。

VisualizeのTimelionで作った僅か1行の簡単なもの。
.es(interval=1m, q='rspamd_meta.direction:Inbound', split='rspamd_meta.action:6',  metric='count').bars(stack=false,width=1).label('$1', '^.* > rspamd_meta.action:(.+) > .*')

splitでアクションを6つに分けたのはRspamdのアクション数が6つの認識だから。もし違ったら要変更。

Rspamdの受信メールスループットをTimelionで表示
add headerが迷惑メール。本来はreject(破棄)なのかもだが、うちのメールサーバではrejectは無しで一定の判断基準点を超えたメールにはヘッダに迷惑メールのフラグを付けてスパムフォルダに振り分けるだけにしているのでこんなの。
greylistは機能をオフにしたいんだけど無効にできないので何とかしたい。no actionは非迷惑メールが普通にメールボックスに配送されたもの。

関連記事: