
ZeekログをフィルタリングしてElastic/OpenSearch+Humioに転送するPythonアプリケーションです。このアプリは、さらに処理するために純粋なJSONログをstdoutに出力することもできます!
このPythonアプリケーションは、ZeekのASCII TSVおよびJSON ログをElasticSearchのバルクロードJSON形式に変換します。

同じ接続ID(uid)またはファイルID(fuid)に対する複数のZeekログを確認したいですか? 次は、単一のuidに対するfiles.log、http.log、conn.logのヒットです:

Zeekの'addr'型に対してサブネット検索を実行できます:

このNTPおよびHTTPグラフのような時系列グラフを作成できます:

IPアドレスは、-gコマンドラインオプションを使用して地理位置情報を取得できます:

集計は簡単かつ迅速です:

このアプリケーションは、Zeekのログ形式が変更された場合にも「そのまま動作」します。このロジックは、 フィールド名と関連する型を読み取り、ElasticSearch内でマッピングを正しく設定します。
このアプリケーションは、gzip圧縮されたログまたは非圧縮ログを認識します。このアプリケーションは、
ElasticSearchがデフォルトポートでlocalhost上にセットアップされていることを前提としています。
ElasticSearchがない場合は、-s -bコマンドラインオプションを使用してJSONをstdoutに出力し、
jqアプリケーションで処理できます。
-kコマンドラインオプションを使用して、テキストフィールドにキーワードサブフィールドを追加できます。
これはKibanaでの集計に役立ちます。
Pythonがすでにシステムにある場合、requestsライブラリが インストールされていれば、Elasticsearch、Kibana、および zeek2es.py以外にマシンへコピーする追加のものはありません。
要件を満たしていると仮定すると、インストールは不要です。zeek2es.pyを
ホストにコピーしてPythonで実行するだけです。自動インデックス名生成(つまり、-iオプションを指定していない場合)で
Zeekログがインポートされると、インデックスは"zeek_zeeklogname_date"という名前になります。ここで、
zeeklognameはconnのようなログ名で、dateはYYYY-MM-DD形式です。この場合、Kibanaのインデックスパターンを
zeek*に一致するように設定してください。-iオプションでインデックスに名前を付けた場合は、その命名スキームに
一致するKibanaインデックスパターンを作成する必要があります。
zeek2esをアップグレードする場合は、zeek2esのアップグレードに関するセクションを参照してください。
インデックスには日付が付加されているため、次のコマンドで 2021年12月31日を削除できます:``` curl -X DELETE http://localhost:9200/zeek_*_2021-12-31
このコマンドですべてのconn.logエントリを削除できます:```
curl -X DELETE http://localhost:9200/zeek_conn_*
optional arguments:
-h, --help show this help message and exit
-i ESINDEX, --esindex ESINDEX
The Elasticsearch index/data stream name.
-u ESURL, --esurl ESURL
The Elasticsearch URL. Use ending slash. Use https for Elastic v8+. (default: http://localhost:9200)
--user USER The Elasticsearch user. (default: disabled)
--passwd PASSWD The Elasticsearch password. Note this will put your password in this shell history file. (default: disabled)
-l LINES, --lines LINES
Lines to buffer for RESTful operations. (default: 10,000)
-n NAME, --name NAME The name of the system to add to the index for uniqueness. (default: empty string)
-k KEYWORDS [KEYWORDS ...], --keywords KEYWORDS [KEYWORDS ...]
A list of text fields to add a keyword subfield. (default: service)
-a LAMBDAFILTER, --lambdafilter LAMBDAFILTER
A Python lambda function, when eval'd will filter your output JSON dict. (default: empty string)
-f FILTERFILE, --filterfile FILTERFILE
A Python function file, when eval'd will filter your output JSON dict. (default: empty string)
-y OUTPUTFIELDS [OUTPUTFIELDS ...], --outputfields OUTPUTFIELDS [OUTPUTFIELDS ...]
A list of fields to keep for the output. Must include ts. (default: empty string)
-d DATASTREAM, --datastream DATASTREAM
Instead of an index, use a data stream that will rollover at this many GB.
Recommended is 50 or less. (default: 0 - disabled)
--compress If a datastream is used, enable best compression.
-o fieldname filename, --logkey fieldname filename
A field to log to a file. Example: uid uid.txt.
Will append to the file! Delete file before running if appending is undesired.
This option can be called more than once. (default: empty - disabled)
-e fieldname filename, --filterkeys fieldname filename
A field to filter with keys from a file. Example: uid uid.txt. (default: empty string - disabled)
-g, --ingestion Use the ingestion pipeline to do things like geolocate IPs and split services. Takes longer, but worth it.
-p SPLITFIELDS [SPLITFIELDS ...], --splitfields SPLITFIELDS [SPLITFIELDS ...]
A list of additional fields to split with the ingestion pipeline, if enabled.
(default: empty string - disabled)
-j, --jsonlogs Assume input logs are JSON.
-r, --origtime Keep the numerical time format, not milliseconds as ES needs.
-t, --timestamp Keep the time in timestamp format.
-s, --stdout Print JSON to stdout instead of sending to Elasticsearch directly.
-b, --nobulk Remove the ES bulk JSON header. Requires --stdout.
--humio HUMIO HUMIO First argument is the Humio URL, the second argument is the ingest token.
-c, --cython Use Cython execution by loading the local zeek2es.so file through an import.
Run python setup.py build_ext --inplace first to make your zeek2es.so file!
-w, --hashdates Use hashes instead of dates for the index name.
-z, --supresswarnings
Supress any type of warning. Die stoically and silently.
To delete indices:
curl -X DELETE http://localhost:9200/zeek*?pretty
To delete data streams:
curl -X DELETE http://localhost:9200/_data_stream/zeek*?pretty
To delete index templates:
curl -X DELETE http://localhost:9200/_index_template/zeek*?pretty
To delete the lifecycle policy:
curl -X DELETE http://localhost:9200/_ilm/policy/zeek-lifecycle-policy?pretty
You will need to add -k -u elastic_user:password if you are using Elastic v8+.
## Requirements <a name="requirements" />
- Unixライクな環境(MacOSでも動作します!)
- Python
- [requests](https://docs.python-requests.org/en/latest/) Pythonライブラリがインストールされていること(例:`pip` を使用)。
## Notes <a name="notes" />
### Humio <a name="humio" />
データをHumioにインポートするには、`corelight-json` パーサーを使用するリポジトリを設定する必要があります。 インジェストトークンを
リポジトリから取得すると、次のようなコマンドでデータをインポートできます。```
python3 zeek2es.py -s -b --humio http://localhost:8080 b005bf74-1ed3-4871-904f-9460a4687202 http.log
URLは http://yourserver:8080 の形式にしてください。パスの残りは
zeek2es.py スクリプトが自動的に追加します。
大量のログにはインデックスの代わりにデータストリームを使用できます。-d コマンドラインオプションを使用します。 この
オプションは、zeek_ で始まるインデックステンプレートを作成します。 また、ライフサイクルポリシー
zeek-lifecycle-policy という名前のものを作成します。 すべてのデータストリーム、ライフサイクルポリシー、
およびインデックステンプレートを削除したい場合は、次のコマンドで実行できます:```
curl -X DELETE http://localhost:9200/_data_stream/zeek*?pretty
curl -X DELETE http://localhost:9200/_index_template/zeek*?pretty
curl -X DELETE http://localhost:9200/_ilm/policy/zeek-lifecycle-policy?pretty
### ヘルパースクリプト <a name="helperscripts" />
ログを `logs-zeek-conn` のようなデータストリームにするのに役立つスクリプトが2つあります。
最初のスクリプトは [process_logs_as_datastream.sh](https://github.com/corelight/zeek2es/blob/master/process_logs_as_datastream.sh) で、
ログとディレクトリのリストを指定すると、それらをデータストリームとしてインポートします。 2つ目のスクリプトは
[process_log.sh](https://github.com/corelight/zeek2es/blob/master/process_log.sh) で、ログを1つずつインポートするために使用できます。
このスクリプトは、ディレクトリ内に作成されたログを監視するために、
[fswatch](https://emcrisostomo.github.io/fswatch/) を使用することもできます。 どちらのスクリプトも、パラメータなしで実行するとコマンドラインの例が
表示されます。```
$ ./process_logs_as_datastream.sh
Usage: ./process_logs_as_datastream.sh NJOBS "ADDITIONAL_ARGS_TO_ZEEK2ES" "LIST_OF_LOGS_DELIMITED_BY_SPACES" DIR1 DIR2 ...
Example:
time ./process_logs_as_datastream.sh 16 "" "amqp bgp conn dce_rpc dhcp dns dpd files ftp http ipsec irc kerberos modbus modbus_register_change mount mqtt mysql nfs notice ntlm ntp ospf portmap radius reporter rdp rfb rip ripng sip smb_cmd smb_files smb_mapping smtp snmp socks ssh ssl stun syslog tunnel vpn weird wireguard x509" /usr/local/var/logs
kubectl proxy
when you input the following command you can call the API without the need to authenticate using short-lived token.
The rules say: translate only natural language, preserve code blocks, etc.
So we'll preserve the shell kubectl proxy exactly. Then translate the following sentence: "when you input the following command you can call the API without the need to authenticate using short-lived token."
Translation: "以下のコマンドを入力すると、短期間のトークンを使用して認証する必要なくAPIを呼び出すことができます。"
But careful: "without the need to authenticate using short-lived token" could be ambiguous: it might mean "without the need for authentication using a short-lived token", i.e., you can call API without needing to authenticate with a short-lived token. That's the intended meaning.
So: "以下のコマンドを入力すると、短期間のトークンで認証する必要なくAPIを呼び出せます。"
But "using short-lived token" is likely the authentication method. "authenticate using short-lived token" = 短期間のトークンを使用した認証. So "without the need to authenticate using short-lived token" = 短期間のトークンを使用した認証の必要なしに.
I'll phrase: "以下のコマンドを入力すると、短期間のトークンによる認証を必要とせずにAPIを呼び出すことができます。"
That's clear. No code changes.
So output:
kubectl proxy
以下のコマンドを入力すると、短期間のトークンによる認証を必要とせずにAPIを呼び出すことができます。
But ensure that there's a newline after the code block? The input has a newline: the code block, then a blank line? Let's examine input: it's:
kubectl proxy
when you input the following command you can call the API without the need to authenticate using short-lived token.
So after the closing triple backticks, there's a newline, then the natural language sentence. We need to preserve that structure exactly: after the code block, a blank line? Actually, the input shows:
kubectl proxy
(blank line?) Actually it's:
kubectl proxy
when you input...
I'll preserve exactly: the code block with triple backticks, the shell, command, closing triple backticks, then a newline and then the translated sentence. I'll just output that.
No additional text.```shell kubectl proxy
以下のコマンドを入力すると、短期間のトークンによる認証を必要とせずにAPIを呼び出すことができます。```
$ ./process_log.sh
Usage: ./process_log.sh LOGFILENAME "ADDITIONAL_ARGS_TO_ZEEK2ES"
Example:
fswatch -m poll_monitor --event Created -r /data/logs/zeek | awk '/^.*\/(conn|dns|http)\..*\.log\.gz$/' | parallel -j 16 ./process_log.sh {} "" :::: -
これらのスクリプトとコマンドラインは、お使いの環境に合わせて編集する必要があります。
lambda_filter_file_dir(デフォルトではホームディレクトリ)内にある、conn_filter.txt のようなログ名のファイルは、対応するログ入力にラムダフィルタファイルとして適用されます。これにより、すべてのフィルタを1つのディレクトリにまとめて設定し、process_logs_as_datastream.sh を使用した1つのコマンドで、そのフィルタセットを使って複数のログファイルをインポートできます。
次の行は、インデックスを使用するかデータストリームを使用するか、またはこれらのヘルパースクリプトを使用するかにかかわらず、ElasticSearch 内のすべての Zeek データを削除するはずです。``` curl -X DELETE http://localhost:9200/zeek*?pretty curl -X DELETE http://localhost:9200/_data_stream/zeek*?pretty curl -X DELETE http://localhost:9200/_data_stream/logs-zeek*?pretty curl -X DELETE http://localhost:9200/_index_template/zeek*?pretty curl -X DELETE http://localhost:9200/_index_template/logs-zeek*?pretty curl -X DELETE http://localhost:9200/_ilm/policy/zeek-lifecycle-policy?pretty
... または Elastic v8+ を使用している場合 ...```
curl -X DELETE -k -u elastic:password https://localhost:9200/zeek*?pretty
curl -X DELETE -k -u elastic:password https://localhost:9200/_data_stream/zeek*?pretty
curl -X DELETE -k -u elastic:password https://localhost:9200/_data_stream/logs-zeek*?pretty
curl -X DELETE -k -u elastic:password https://localhost:9200/_index_template/zeek*?pretty
curl -X DELETE -k -u elastic:password https://localhost:9200/_index_template/logs-zeek*?pretty
curl -X DELETE -k -u elastic:password https://localhost:9200/_ilm/policy/zeek-lifecycle-policy?pretty
ただし、v8+ でこれを実行するには、Elastic v8.0+ のセクションで説明されているように Elastic を設定する必要があります。
Cython を試したい場合は、最初に python setup.py build_ext --inplace を実行して
コンパイル済みファイルを生成する必要があります。 zeek2es を更新するたびに、この操作を行う必要があります。