Kibana4 の検索クエリでの2桁の数字について


(Satoru Ishizaki) #1

こんにちは

OSSECのアラート出力をlogstash で受け、elasticsearch,kibana4 で
可視化しようと試みておりますが、kibana4 の検索クエリについて質問させてください。

OSSECの Alert_Level 5以下は表示しないクエリを書きたいのですが、
Alert_Level:>5 では 6~9の範囲しか検索されません。(15まであります。)

Alert_Level:10 と検索すると、 Alert_Level が 10の検索結果が表示されますが、
Alert_Level:[6 TO 10] と検索すると、No results found となってしまいます。
Alert_Level:[6 TO 9] では正しく検索されます。

-AlertLevel<5 や、 NOT(Alert_Level:<5) も6~9の範囲しか表示されず、
2桁の数字をうまく扱えません。
どうも、2桁の数字ではなく2文字の文字列として扱われているようです。
(https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax
では、 string fields も Range の対象と書かれているので大丈夫だと考えていますが)

logstashでは NONNEGINT を指定していますが、kibanaからは stringに見えます。
NONNEGINTをINTやNUMBERに変更しても結果は変わりませんでした。

Alert_Level を 6~15の範囲で検索するにはどのようなクエリを記載すればよろしいでしょうか?

よろしくお願い致します。


(Jun Ohtani) #2

内部的に、文字列として登録されており、範囲検索した場合は、
文字の範囲検索として動いています。
英語や国語の辞書の単語の並び順を想像してもらうと分かりやすいかもしれません。
なので、1で始まる単語、2で始まる単語。。。という並びになっているものを範囲検索している形です。

対処方法としては、いくつか方法があるかと。

案1:Logstashで型を指定(データ再投入)

NONNEGINTなどは、おそらくgrokフィルタでのSYNTAXの話かと。
これは、文字列をパースする時の正規表現での数値を判定するシンタックスの指定であり、
grokフィルタは基本的に文字列として、データを出力します。
grokフィルタで数値として出力したい場合は、次のような記法を使用します。

%{NUMBER:num:int}

このように、最後に変換する型を指定すると、内部でint型で扱ってくれるという書式があります。
intとfloatがサポートされています。
参考:https://www.elastic.co/guide/en/logstash/current/plugins-filters-grok.html#_grok_basics

案2:ElasticsearchのMappingで指定(データ再投入)

Mappingの指定で、numeric_detectionをtrueにすると、
数値として登録してくれる機能があります。
デフォルトはfalseになっています。
https://www.elastic.co/guide/en/elasticsearch/reference/current/dynamic-field-mapping.html#numeric-detection

案3:クエリで

一応、以下のクエリで対応できるかと。
かなり強引ですが。

Alert_Level:(>=6 <2 -1)

データを入れ替えた方が分かりやすいクエリが書けるかと思います。


(Satoru Ishizaki) #3

迅速なご回答、有難うございます。

案3での動作を確認致しました。
Alert_Level:(>=6 <2 -1)は、
Alert_Level:(>=6 OR <2 OR -1) という事で間違っていないでしょうか?
省略されているときはデフォルト値が適用されるという所までは読み取れたのですが、
デフォルト値が OR かどうか確認できませんでした。

また、案3でもご指摘いただいているように、そもそものデータの型をintにしたいと
考え、案1を試してみましたが、うまくいきません。

以下のように、 Alert Level: %{NUMBER:Alert_Level:int}; に変更し、
grok {
match => { "message" => [ "%{SYSLOGTIMESTAMP:syslog_timestamp} %{USERNAME:syslog_host}%{DATA:syslog_progra
m}: Alert Level: %{NUMBER:Alert_Level:int}; Rule: %{NONNEGINT:Rule} - %{DATA:Description}; Location: %{DATA:Locat
ion}; (srcip: %{IP:Src_IP};%{SPACE})?(dstip: %{IP:Dst_IP};%{SPACE})?(src_port: %{NONNEGINT:Src_Port};%{SPACE})?(d
st_port: %{NONNEGINT:Dst_Port};%{SPACE})?(user: %{USER:User};%{SPACE})?%{GREEDYDATA:Details}" ]
}

elasticsearch, kibana, logstash 全てのサービス再起動、
kibana GUIの settings -> Indices -> ☆logstash-* -> reflesh field list
を実行しても、Alert_level の type は string のまま変更なしでした。
念のため index pettern を削除し、再登録したのですが string のままでした。

たびたびで恐縮ですが、お時間ある時で結構ですので型の指定方法について
間違い等あればご指摘頂けると助かります。

なお、以下のように geoipも利用しておりますが、geoip.area_code等は number として
認識されています。
geoip {
database => [ "/usr/share/GeoIP/GeoLiteCity.dat" ]
source => [ "Src_IP" ]
target => [ "geoip" ]
}

よろしくお願い致します。


(Jun Ohtani) #4

Elasticsearchの対象となるIndexを削除してから、再度データ投入する必要があります。


(Satoru Ishizaki) #5

ご回答、有難うございます。

indexを削除後、 新規投入されたデータから number になり、
Alert_Level:>5 等での検索でも 10以上のAlertが検索結果として出力されました。

有難うございました。


(system) #6