はじめに
「標的型攻撃に対するJPCERT/CCのおすすめログ設定をElasticsearchで構築してみる」のメールサーバ編です。メールサーバとして(Postfix)を利用します。
(これまでの記事)
※本記事で作成するFilebeatモジュールやPostfixの設定例はこちらへ仮置きしておきます(今後、もう少しわかりやすい配置にする予定です)。
※Ubuntu18.04上で構築(FilebeatはDEBパッケージでインストール)しますので他のディストリビューションやFilebeatインストール方法の場合にはファイルの配置場所などを読みかえてください。
※実際の環境で運用するには、ネットワーク設定、個々のソフトウェアのインストール/初期設定や認証/通信の暗号、冗長構成や負荷分散などで相応の設定が必要となります。それぞれ個別のドキュメントをご参照ください。本記事ではログ設定に関係する基本的なコンフィグレーションにフォーカスして記載します。
#利用するソフトウェア
- OS: Ubuntu 18.04
- メールサーバ: Postfix (3.3.0) / Dovecot (2.2.33.2)
- DNSサーバ: Dnsmasq (2.79)
- Elasticsearch (6.6.0)
- Kibana (6.6.0)
- Filebeat (6.6.0)
- VMware Workstation Player等のVMソフトウェア
- Windows 10 (クライアントPC)
#ネットワーク構成例
ここでは「準備編」で説明した以下のようなシンプルなネットワーク構成を想定。
説明 | |
---|---|
メール | Windows 10クライアントPC上のメールクライアントはdmz.example.comで動作するメールサーバ(Postfix)へアクセス |
ログ | dmz.example.com上で動作するメールサーバのログをFilebeatがElasticsearch(log.example.com)へ転送 |
#作業内容
- ネットワーク構築および各ソフトウェアのインストールと設定
- Postfixログ設定およびフォーマット追加
- Postfix用のFilebeatモジュール作成
- Postfix用のFilebeatモジュールをdmz.example.comに配置し設定
- Kibanaで確認
#JPCERT/CCのおすすめログ設定
「高度サイバー攻撃への対処におけるログの活用と分析方法」をもとに以下の情報を出力するように設定します。
- メールヘッダのFromに含まれる情報
- MIMEヘッダ(Content-Type/Content-Disposition)の添付ファイル名
Alice(alice@example.com)からBob(bob@example.com)へメール送信した例 (SMTP)
これらの情報より以下の攻撃を検出できる可能性があります。
- 送信元を偽装したメールを送り付けて、その添付ファイルを開かせる、またはメッセージ中のURLをクリックさせる
- マルウエアである実行ファイルを添付したメールを送り付ける
(JPCERT/CCの同資料より抜粋)
これらのログを利用した分析手法の詳細についても同資料に説明されていますのでぜひご参照ください。
またメールに添付されるファイルを利用した典型的な攻撃例(例えばMicrosoft Officeドキュメント(.docx, .xlsx)やWindowsショートカットファイル(.lnk)が添付される場合など)では、そのファイル開封後にマルウェアの実体がダウンロードされる処理が続けて実行される場合があります。その際にはHTTP/HTTPSトラフィックを偽装またはそれらをトランスポートにすることも多く、前回の記事で扱ったプロキシサーバログとの照合が重要になるかもしれません。
参考:
- IQYファイル(※)を悪用する攻撃手に関する注意点 (第二版) [IPA 2018/08]
- IQYファイルを利用するマルウェアスパム、日本のみを標的に 50 万通拡散 [Trend Micro 2018/09]
このような疑わしい添付ファイルも既知のものはvirustotalなどで無償でチェックできますが、ファイルハッシュで照合するのではなく、ファイルを検体としてアップロードする場合には情報漏洩につながらないように十分にご注意ください。
参考: [ウイルスチェックのつもりで情報漏えい? VirusTotalの使い方に注意]
(https://www.itmedia.co.jp/enterprise/articles/1603/14/news104.html) [ITmediaエンタープライズ 2016/3/14]
#メールサーバ(Postfix)のログ設定とフォーマット追加
###Fromヘッダ情報の採取
送信元を偽装したメールを検出するためにメールヘッダのFromフィールドのdisplay nameと実際のメールアドレスの情報を採取します。以下のように設定ファイルを変更します。
header_checks = regexp:/etc/postfix/header_checks
次にファイルheader_checksを作成し実際にログ採取するメールヘッダのフィールドパターンを指定します。
cd /etc/postfix
touch header_checks
nano header_checks
Fromヘッダのパターンを設定します。
/^From:/ WARN
この設定により以下のようなPostfixログが採取されます。
Apr 21 08:01:14 dmz_server postfix/cleanup[6615]: 4B19A1000EB: warning: header From: alice <alice@example.com> from unknown[192.168.0.xx]; from=<alice@example.com> to=<bob@example.com> proto=ESMTP helo=<[192.168.0.xx]>
header From: alice <alice@example.com>
from=<alice@example.com> to=<bob@example.com>
###MIMEヘッダ情報の採取
以下のMIMEヘッダ情報を採取します。
- Content-Type
- Content-Disposition
mime_header_checks = regexp:/etc/postfix/mime_header_checks
ファイルmime_header_checksを作成し実際にログ採取するメールヘッダのフィールドパターンを指定します。
cd /etc/postfix
touch mime_header_checks
nano mime_header_checks
MIMEヘッダのパターンを設定します。
/^\s*Content-(Disposition|Type).*name\s*=\s*"?(.+)"?\s*$/ WARN
この設定により以下のようなPostfixログが採取されます。
Apr 21 08:01:14 dmz_server postfix/cleanup[6615]: 4B19A1000EB: warning: header Content-Type: image/png;? name="Test.png" from unknown[192.168.0.xx]; from=<alice@example.com> to=<bob@example.com> proto=ESMTP helo=<[192.168.0.xx]>
Apr 21 08:01:14 dmz_server postfix/cleanup[6615]: 4B19A1000EB: warning: header Content-Disposition: attachment;? filename="Test.png" from unknown[192.168.0.xx]; from=<alice@example.com> to=<bob@example.com> proto=ESMTP helo=<[192.168.0.xx]>
Test.pngというファイル名を採取。この値はBase64エンコードされている場合があります。
#PostfixログメッセージのJSON変換
「プロキシサーバ編」と同様にPostfixログメッセージはFilebeatによりJSON形式へ変換されてElasticsearchへ転送されます。
Apr 21 08:01:14 dmz_server postfix/cleanup[6615]: 4B19A1000EB: warning: header Content-Type: image/png;? name="Test.png" from unknown[192.168.0.xx]; from=<alice@example.com> to=<bob@example.com> proto=ESMTP helo=<[192.168.0.xx]>
このログメッセージはFilebeatにより以下のようにJSON形式へ変換されます。
{
"_index": "filebeat-6.6.0-2019.xx.xx",
"_type": "doc",
"_id": "ge2SdmoBsFF1POM-ajN-",
"_version": 1,
"_score": null,
"_source": {
"offset": 23700,
"log": {
"file": {
"path": "/var/log/mail.log"
}
},
"prospector": {
"type": "log"
},
"source": "/var/log/mail.log",
"fileset": {
"module": "postfix",
"name": "mail"
},
"message" : "Apr 21 08:01:14 dmz_server postfix/cleanup[6615]: 4B19A1000EB: warning: header Content-Type: image/png;? name=\"Test.png\" from unknown[192.168.0.xx]; from=<alice@example.com> to=<bob@example.com> proto=ESMTP helo=<[192.168.0.xx]>",
"input": {
"type": "log"
},
"@timestamp": "2019-04-20T23:01:31.000Z",
"beat": {
"hostname": "dmz_server",
"name": "dmz_server",
"version": "6.6.0"
},
"host": {
"os": {
"codename": "bionic",
"name": "Ubuntu",
"family": "debian",
"version": "18.04.1 LTS (Bionic Beaver)",
"platform": "ubuntu"
},
"containerized": false,
"name": "dmz_server",
"id": "39557a23335243cb9d4740a1a210ae3d",
"architecture": "x86_64"
},
"event": {
"dataset": "postfix.mail"
}
},
"fields": {
"@timestamp": [
"2019-04-20T23:01:31.000Z"
]
},
"sort": [
1556767467095
]
}
その後Elasticsearch/Ingestノードにより_source.messageフィールドがパーシングおよびパイプライン処理され以下のように変換されます(詳細は後述)。
{
"_index": "filebeat-6.6.0-2019.xx.xx",
"_type": "doc",
"_id": "ge2SdmoBsFF1POM-ajN-",
"_version": 1,
"_score": null,
"_source": {
"offset": 23700,
"log": {
"file": {
"path": "/var/log/mail.log"
}
},
"prospector": {
"type": "log"
},
"source": "/var/log/mail.log",
"fileset": {
"module": "postfix",
"name": "mail"
},
"input": {
"type": "log"
},
"@timestamp": "2019-04-20T23:01:31.000Z",
"beat": {
"hostname": "dmz_server",
"name": "dmz_server",
"version": "6.6.0"
},
"host": {
"os": {
"codename": "bionic",
"name": "Ubuntu",
"family": "debian",
"version": "18.04.1 LTS (Bionic Beaver)",
"platform": "ubuntu"
},
"containerized": false,
"name": "dmz_server",
"id": "39557a23335243cb9d4740a1a210ae3d",
"architecture": "x86_64"
},
"postfix": {
"mail": {
"process": "cleanup",
"to_email": "bob@example.com",
"remote_ip": "192.168.0.xx",
"from_email": "alice@example.com",
"mime_type": "image/png",
"header": "Content-Type",
"pid": "2368",
"mime_name": "Test.png",
"time": "2019-04-20T23:01:14.000Z",
"mail_server": "dmz_server",
"queue_id": "304A6101243",
"remote_host": "unknown"
}
},
"event": {
"dataset": "postfix.mail"
}
},
"fields": {
"@timestamp": [
"2019-04-20T23:01:31.000Z"
]
},
"sort": [
1556767467095
]
}
ご覧の通り_soruce/messageフィールドが_source.postfixフィールドへオブジェクトとして展開されています。こうすることでKibanaで各情報単位で検索や集計したり、自作ツール等で扱いやすくなります。
#Postfix用Filebeatモジュールの作成
(現状)FilebeatのパッケージにはPostfix用モジュールが含まれていないようです。そのためPostfixログ用のモジュールを作成します。
Filebeatのモジュール作成方法はこちらの公式サイトで解説されていますが(テンプレートファイルを生成するMakeファイルも用意されています)、前回同様にFilebeatのパッケージに同梱されているApache用のモジュールを雛形にして作成してみます。
基本的な作業は前回の「プロキシサーバ編」とほぼ同様ですので詳細についてはあわせて参照してください。
Apache用モジュールをコピー
cd /usr/share/filebeat/module
cp -r ./apache2 ./postfix
error.log用の設定は必要ないので削除する
cd postfix
rm -rf error
(logファイル名による)ディレクトリ名を変更する
mv access mail
Postfix用モジュールのファイル構成
「準備編」にて説明しました通り以下のような構成でモジュールのファイルを配置します。
/usr/share/filebeat/
`- module/
`- postfix/
|- module.yml
`- mail/
|- manifest.yml
|- config/
| `- mail.yml
`- ingest/
`- default.json
説明 | |
---|---|
manifest.yml | モジュール関連のファイルパスつまりingest/default.jsonなどの設定を記述します |
config/mail.yml | Filebeatへの入力ファイル設定(Postfixのログファイルパス)を生成するテンプレートを記述。Filebeatの開発言語であるGOのテンプレート機能を利用します。今回は特に変更しません |
module.yml | ダッシュボード(Kibana)の設定を記述するファイルですが今回はダッシュボードは扱わないのでフィールドの名前だけ変更します |
ingest/default.json | Elasticsearch/Ingestノードへ注入するPipeline設定(プロセッサの設定)を記述します。PostfixモジュールではGrok、Date、Remove、Dropプロセッサを利用しますのでその設定を行います |
##manifest.ymlの設定
module_version: 1.0
var:
- name: paths
default:
# Postfixのログファイルパス(FilebeatへのInputソース)
- /var/log/mail.log*
# Ingestノードのパイプライン設定ファイルパス
ingest_pipeline: ingest/default.json
# 入力ソースの設定ファイルパス
input: config/mail.yml
requires.processors:
##config/mail.ymlの設定
Apache用モジュールからコピーしたまま変更しません。
type: log
paths:
{{ range $i, $path := .paths }}
- {{$path}}
{{ end }}
exclude_files: [".gz$"]
##module.yml
ID値だけ変更しておきます。
dashboards:
- id: Filebeat-Postfix-Dashboard
##ingest/default.json
Ingestノードに注入するPipeline設定を記述します。
###Ingestノードのパイプライン(プロセッサ)の設定
Postfix用のログメッセージをパーシングしてJSON形式へ変換します。以下のプロセッサを利用します。
説明 | |
---|---|
Grokプロセッサ | ログメッセージのテキストデータをパーシングしてJSON形式へ変換するプロセッサ。 パース形式を正規表現を組み合わせたパターンで記述するだけでOKです |
Dateプロセッサ | PostfixログのSyslog形式タイムスタンプからISO8601形式へ変換します |
Removeプロセッサ | 不要な情報を削除。 Grokによってパーシングされた後で不要なログメッセージ情報をElasticsearchへ保存する前に削除します |
Dropプロセッサ | 採取対象外のログをElasticsearchへ保存する前に削除します |
設定の全体は以下の通りとなります。それぞれのプロセッサ設定について説明していきます。
{
"description": "Pipeline for parsing postfix mail.log.",
"processors": [{
"grok": {
"field": "message",
"patterns":[
"%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.header_display_name} <%{DATA:postfix.mail.header_from_email}> from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>",
"%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.mime_type};(\\?)* name=\"%{DATA:postfix.mail.mime_name}\" from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>",
"%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.mime_type};(\\?)* filename=\"%{DATA:postfix.mail.mime_filename}\" from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>"
],
"ignore_missing": false,
"ignore_failure": false
}
}, {
"date": {
"field": "postfix.mail.time",
"target_field": "postfix.mail.time",
"formats": [
"MMM d HH:mm:ss",
"MMM dd HH:mm:ss"
],
"ignore_failure": true
}
}, {
"remove": {
"field": "message",
"ignore_missing": true,
"ignore_failure": true
}
}],
"on_failure" : [{
"drop" : {
"ignore_failure" : true
}
}]
}
###GrokプロセッサによるログメッセージのJSON変換
GrokプロセッサによりFilebeatから転送された(b)JSONドキュメント内の**_source.messageフィールドのログメッセージは、(c)JSONドキュメントのようにパーシングされ_source.postfix**のJSONオブジェクト形式へ変換されます。
{
"_index" : "filebeat-6.6.0-2019.xx.xx",
"_type" : "doc",
"_id" : "SKMrAmoB5yTtiEEfLG6k",
"_score" : 1.0,
"_source" : {
......
"message" : "Apr 21 08:01:14 dmz_server postfix/cleanup[6615]: 4B19A1000EB: warning: header Content-Type: image/png;? name=\"Test.png\" from unknown[192.168.0.xx]; from=<alice@example.com> to=<bob@example.com> proto=ESMTP helo=<[192.168.0.xx]>",
......
}
}
{
"_index" : "filebeat-6.6.0-2019.xx.xx",
"_type" : "doc",
"_id" : "SKMrAmoB5yTtiEEfLG6k",
"_score" : 1.0,
"_source" : {
......
"postfix": {
"mail": {
"process": "cleanup",
"to_email": "bob@example.com",
"remote_ip": "192.168.0.xx",
"from_email": "alice@example.com",
"mime_type": "image/png",
"header": "Content-Type",
"pid": "2368",
"mime_name": "Test.png",
"time": "2019-04-20T23:01:14.000Z",
"mail_server": "dmz_server",
"queue_id": "304A6101243",
"remote_host": "unknown"
}
},
......
}
}
###変換先のテンプレート定義
まずGrokプロセッサがインデクスへ格納するログ情報のJSON形式(_source.postfixオブジェクト)を定義します。
テンプレートはデフォルトでは**/etc/filebeat/fields.ymlに定義されています。このファイルをmy_fields.yml**としてコピーしPostfixモジュール用の定義を追加します(前回Squidモジュールの作業を行っている場合には同じファイルを利用してください)。
cd /etc/filebeat
cp fields.yml my_fields.yml
モジュール本体と同様にここでもApache用のテンプレート定義(- key: apache2)を雛形にして作業します。詳細については前回の「プロキシサーバ編」に説明していますのであわせて参照してください。
###Postfix用モジュールのテンプレート定義
Postfix用モジュールの定義を**/etc/filebeat/my_fields.yml**へ追加します。
- key: postfix
title: "postfix"
description: >
Postfix Module
short_config: true
fields:
- name: postfix
type: group
description: >
Postfix fields.
fields:
- name: mail
type: group
description: >
Contains fields for the Postfix mail log.
fields:
- name: time
type: keyword
description: >
log_time.
- name: mail_server
type: text
description: >
mail_server.
- name: process
type: keyword
description: >
process.
- name: pid
type: long
description: >
PID.
- name: queue_id
type: keyword
description: >
queue_id.
- name: header
type: keyword
description: >
header.
- name: header_display_name
type: text
description: >
header_display_name.
- name: header_from_email
type: text
description: >
header_from_email.
- name: remote_host
type: text
description: >
remote_host.
- name: remote_ip
type: keyword
description: >
remote_ip.
- name: from_email
type: text
description: >
from_email.
- name: to_email
type: text
description: >
to_email.
- name: mime_type
type: text
description: >
mime_type.
- name: mime_name
type: text
description: >
mime_name.
- name: mime_filename
type: text
description: >
mime_filename.
###Grokプロセッサの詳細
Grokプロセッサによるログメッセージのパーシング結果を変換するJSON形式を定義できました。次にプロセッサの設定を以下の通り行います。
{
"description": "Pipeline for parsing postfix mail.log.",
"processors": [{
"grok": {
"field": "message",
"patterns":[
"%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.header_display_name} <%{DATA:postfix.mail.header_from_email}> from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>",
"%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.mime_type};(\\?)* name=\"%{DATA:postfix.mail.mime_name}\" from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>",
"%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.mime_type};(\\?)* filename=\"%{DATA:postfix.mail.mime_filename}\" from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>"
],
"ignore_missing": false,
"ignore_failure": false
}
......
}
説明 | |
---|---|
field: message | Grokプロセッサが処理するフィールド名。ログメッセージが設定されている(b)JSONドキュメントのmessageフィールドを指定します |
patterns:[...] | fieldで指定されたフィールド値のパーシング規則を正規表現を利用して記述します(詳細については前回の「プロキシサーバ編」を参照) |
ignore_missing: false | フィールドが存在しない場合にはログ採取の対象外としてDropプロセッサへ渡します |
ignore_failure: false | パーシング等に失敗した場合にはログ採取の対象外としてDropプロセッサへ渡します |
設定の詳細についてはこちらを参照。
####Grok patterns(パターン)の説明
Grokプロセッサの詳細については前回の「プロキシサーバ編」に説明していますので参照してください。
####Postfixログパーシング用のGrok patterns(パターン)
Squidモジュールと同様にKibanaのGrok Debuggerを利用して作成したパターンが以下です。
%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.header_display_name} <%{DATA:postfix.mail.header_from_email}> from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>
%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.mime_type};(\\?)* name=\"%{DATA:postfix.mail.mime_name}\" from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>
%{SYSLOGTIMESTAMP:postfix.mail.time} %{DATA:postfix.mail.mail_server} postfix/%{DATA:postfix.mail.process}\\[%{NUMBER:postfix.mail.pid}\\]: %{BASE16NUM:postfix.mail.queue_id}: %{LOGLEVEL}: header %{DATA:postfix.mail.header}: %{DATA:postfix.mail.mime_type};(\\?)* filename=\"%{DATA:postfix.mail.mime_filename}\" from %{DATA:postfix.mail.remote_host}\\[%{IP:postfix.mail.remote_ip}\\]; from=<%{DATA:postfix.mail.from_email}> to=<%{DATA:postfix.mail.to_email}>
- '['および']'は''でエスケープします。
- ingest/default.jsonのgrok/patternsは配列型ですので複数パターンを同時に記述できます。
- フィールド名は前回「プロキシサーバ編」のテンプレート定義で説明した通り、階層(ネスト)構造で指定します。
- ingest/default.jsonへ設定する場合には'"'および''をさらに''でエスケープします。
###DateプロセッサによるISO8601形式タイムスタンプの追加
Postfixのログで記録されるSyslog形式のタイムスタンプからISO8601形式タイムスタンプを生成し追加します。
{
"description": "Pipeline for parsing postfix mail.log.",
"processors": [{
......
}, {
"date": {
"field": "postfix.mail.time",
"target_field": "postfix.mail.time",
"formats": [
"MMM d HH:mm:ss",
"MMM dd HH:mm:ss"
],
"ignore_failure": true
}
......
}],
......
}
説明 | |
---|---|
field | Syslogタイムスタンプのフィールド名を指定します |
target_field | 変換結果を書き込むフィールド名を指定します |
formats | 変換元のSyslog形式フォーマットを指定します |
ignore_failure: true | パーシング等でエラーが発生した場合に処理をスキップします |
###Removeプロセッサによる不要な情報の削除
不要または冗長な情報を削除します。
####Removeプロセッサの設定
パーシングしたmessageフィールドは不要なため削除します。
{
"description": "Pipeline for parsing postfix mail.log.",
"processors": [{
......
}, {
"remove": {
"field": "message",
"ignore_missing": true,
"ignore_failure": true
}
......
}],
......
}
説明 | |
---|---|
field | 削除するフィールド名を指定します |
ignore_missing: true | フィールド値が見つからない場合に処理をスキップします |
ignore_failure: true | エラーが発生した場合に処理をスキップします |
詳細についてはこちらを参照。
###Dropプロセッサによって採取対象外のログメッセージを削除
本記事の設定例では採取対象外のログメッセージを削除します。
####Dropプロセッサの設定
{
"description": "Pipeline for parsing postfix mail.log.",
"processors": [{
......
......
}],
"on_failure" : [{
"drop" : {
"ignore_failure" : true
}
}]
}
説明 | |
---|---|
ignore_failure: true | エラーが発生した場合に処理をスキップします |
詳細についてはこちらを参照。
#Filebeatモジュールの設定手順
Postfix用のモジュールが完成しましたのでそれをdmz.example.comへデプロイします。
###モジュールの設定ファイル作成
/etc/filebeat/
`- modules.d/
`- postfix.yml.disabled
こちらもApache用の設定ファイルを雛形にして多少変更するだけです。
cd /etc/filebeat/modules.d
cp apache2.yml.disabled postfix.yml.disabled
- module: postfix
# Access logs
mail:
enabled: true
# Set custom paths for the log files. If left empty,
# Filebeat will choose the paths depending on your OS.
#var.paths:
###モジュールのテンプレート設定を追加
前回「プロキシサーバ編」で設定している場合には必要ありません。
/etc/filebeat/
`- my_fields.yml
さきほど作成したmy_fields.ymlのパスをFilebeatの設定ファイル(/etc/filebeat/filebeat.yml)で変更します。以下のsetup.template.fieldsで説明します。
Filebeatの設定ファイルを修正
こちらも前回「プロキシサーバ編」で設定している場合には必要ありません。
/etc/filebeat/
`- filebeat.yml
説明 | |
---|---|
hosts: ["log.example.com:9200"] | Elasticsearchが動作するホストアドレスとポート番号を指定 |
filebeat.overwrite_pipelines: true | Elasticsearchへの接続毎にIngestノードのパイプライン設定を注入(デバッグ用) |
setup.template.enabled: true | テンプレート設定の注入を有効化 |
setup.template.fields: "/etc/filebeat/my_fields.yml" | テンプレート設定ファイルの場所を変更 |
setup.template.overwrite: true | 既存のテンプレート設定を更新 |
詳細は**/etc/filebeat/filebeat.reference.yml**を参照してください。
hosts: ["log.example.com:9200"]
#運用時にはコメントアウト
filebeat.overwrite_pipelines: true
setup.template.enabled: true
setup.template.fields: "/etc/filebeat/my_fields.yml"
setup.template.overwrite: true
Filebeatを再起動します。
systemctl restart filebeat.service
###モジュールの有効化
以上の設定作業が終わったらSquid用のモジュールを有効化します。
filebeat modules enable postfix
###モジュールのテンプレート設定をElasticsearchへ注入
filebeat setup --template
###モジュールのパイプライン設定をElasticsearchへ注入
filebeat setup --pipelines -modules postfix
###補足
テンプレートの参照
curl -XGET http://log.example.com:9200/_template/filebeat-*?pretty
テンプレートの削除
curl -XDELETE http://log.example.com:9200/_template/filebeat-*
パイプライン設定の参照
curl -XGET http://log.example.com:9200/_ingest/pipeline/filebeat-*?pretty
パイプライン設定の削除
curl -XDELETE http://log.example.com:9200/_ingest/pipeline/filebeat-*
ログの取得
curl -XGET http://log.example.com:9200/filebeat-*/_search?pretty -H 'Content-Type: application/json' -d
'{
"query": {
"match_all":{}
},
"size":100
}'
インデクスのリスト
curl http://log.example.com:9200/_cat/indices?v
registryファイルのクリア
rm /var/lib/filebeat/registry
#Kibanaでログを確認
- Management/Create Index Patternにて **filebeat-***を指定してインデクスパターンを生成または更新(Refresh field list)。
-
Discoverにて**squid.access.***フィールドへパーシングされたログを確認できます。
#まとめ
JPCERT/CCによる「高度サイバー攻撃への対処におけるログの活用と分析方法」で推奨されるメールサーバのログ設定をもとにPostfixおよびElasticsearchを利用したログ解析基盤を構築してみました。
次回の記事ではWinlogbeatを利用してエンドポイントログ採取(Windows 10 PC)のコンフィグレーションを追加していきます。