SquidのFilebeatモジュールをElastic Common Schema（ECS）へ対応させてみる

# はじめに
「[標的型攻撃に対するJPCERT/CCのおすすめログ設定をElasticsearchで構築してみる（プロキシサーバ編）](https://qiita.com/rhpenguin/items/7ec7ddf562906257e297)」ではJPCERT/CCによる[「高度サイバー攻撃への対処におけるログの活用と分析方法」](https://www.jpcert.or.jp/research/apt-loganalysis.html)をもとに、以下の情報を[Elasticsearch](https://www.elastic.co/jp/products/elasticsearch)へ出力するように設定してみました。

* URL
* HTTPリクエストメソッド
* タイムスタンプ
* 送信先サーバのFQDN
* 送信先サーバのIPアドレス
* 送信先サーバのポート番号
* 送信元クライアントのIPアドレス
* ユーザエージェント
* リファラ
* 送受信量
* 送信元クライアントのポート番号

※プロキシサーバとして[Squid](http://www.squid-cache.org/)を利用しています。

本記事ではこれらの情報出力を[Elastic Common Schema（ECS）](https://www.elastic.co/guide/en/ecs/current/index.html)へ対応させてみます。

* [Elastic Common Schemaについて](https://www.elastic.co/jp/blog/introducing-the-elastic-common-schema) (Elastic社)

※本記事で作成する[Filebeat](https://www.elastic.co/jp/products/beats/filebeat)モジュールやSquidの設定例は[こちら](https://github.com/rhpenguin/Filebeat-module-for-Squid)へ置いておきました。


#利用するソフトウェア
- OS: Ubuntu 18.04
- プロキシサーバ: Squid (3.5.27)
- DNSサーバ: Dnsmasq (2.79)
- Elasticsearch (7.3.2) 
- Kibana (7.3.2)
- Filebeat (7.4.1)
- VMware Workstation Player等のVMソフトウェア
- Windows 10 (クライアントPC)

#ネットワーク構成例
「[標的型攻撃に対するJPCERT/CCのおすすめログ設定をElasticsearchで構築してみる（プロキシサーバ編）](https://qiita.com/rhpenguin/items/7ec7ddf562906257e297)」から変更はありません。

![log_network_squid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362125/33264e29-e5a6-054d-7a5f-219a63d15c56.png)

|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|説明|
|---|---|
|Webアクセス|Windows 10上のWebブラウザはインターネットへdmz.example.comで動作するプロキシサーバ(Squid)経由でアクセス|
ログ|dmz.example.com上で動作するプロキシサーバのログをFilebeatがElasticsearch(log.example.com)へ転送|

#プロキシサーバ(Squid)のログ設定とフォーマット追加
特に変更はありません。

Squidの設定ファイル**/etc/squid/squid.conf**に以下の設定を追加します。Squidログフォーマットの詳細仕様については[こちら](http://www.squid-cache.org/Doc/config/logformat/)を参照。

```/etc/squid/squid.conf
logformat combined   %>a:%>p %[ui %[un "%rm %ru HTTP/%rv" %>Hs %>st %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh [%ts%03tu] %<a:%<p %<A
access_log daemon:/var/log/squid/access.log combined
```

#Squid用Filebeatモジュールの作成
「[標的型攻撃に対するJPCERT/CCのおすすめログ設定をElasticsearchで構築してみる（プロキシサーバ編）](https://qiita.com/rhpenguin/items/7ec7ddf562906257e297)」で作成したFilebeatモジュールを[Elastic Common Schema（ECS）](https://www.elastic.co/guide/en/ecs/current/index.html)へ対応させます。

### Squid用モジュールのファイル構成
以下のような構成でモジュールのファイルを配置します（変更ありません）。

```
/usr/share/filebeat/
   `- module/
        `- squid/
             |- module.yml
             `- access/
                  |- manifest.yml
                  |- config/
                  |    `- access.yml
                  `- ingest/
                       `- default.json 
```

##squid/access/manifest.ymlの設定
変更はありません。

```yml:manifest.yml
module_version: 1.0

var:
  - name: paths
    default:
      # Squidのログファイルパス（FilebeatへのInputソース）
      - /var/log/squid/access.log*

# Ingestノードのパイプライン設定ファイルパス
ingest_pipeline: ingest/default.json

# 入力ソースの設定ファイルパス
input: config/access.yml

# Ingestノードのプラグインの指定
requires.processors:
- name: user_agent
  # ユーザエージェント情報のパーシング
  plugin: ingest-user-agent
- name: geoip
  # 送信先サーバの地理情報の付加
  plugin: ingest-geoip
```

##squid/access/config/access.ymlの設定
変更はありません。

```yml:access/access.yml
type: log
paths:
{{ range $i, $path := .paths }}
 - {{$path}}
{{ end }}
exclude_files: [".gz$"]
```

##squid/module.yml
変更はありません。

```yml:module.yml
dashboards:
- id: Filebeat-Squid-Dashboard
```

##squid/access/ingest/default.json
Ingestノードに注入するPipeline設定を記述します。利用するプロセッサは同じです。

![filebeat_json4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362125/7829720d-853e-f1ba-0b73-36ea9f475171.png)

|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|説明|
|---|---|
|[Grokプロセッサ](https://www.elastic.co/guide/en/elasticsearch/reference/current/grok-processor.html)|ログメッセージのテキストデータをパーシングしてJSON形式へ変換するプロセッサ。<br>パース形式を正規表現を組み合わせたパターンで記述するだけでOKです|
|<nobr>[Dateプロセッサ](https://www.elastic.co/guide/en/elasticsearch/reference/current/date-processor.html)</nobr>|SquidログのUNIXタイムスタンプからISO8601形式タイムスタンプへ変換します|
|<nobr>[User Agentプロセッサ](https://www.elastic.co/guide/en/elasticsearch/reference/current/user-agent-processor.html)</nobr>|Webブラウザが送信するユーザエージェント情報（ブラウザ情報）をパーシングします|
|[GeoIPプロセッサ](https://www.elastic.co/guide/en/elasticsearch/reference/current/geoip-processor.html)|接続先サーバIPの地理情報を追加します|
|[Removeプロセッサ](https://www.elastic.co/guide/en/elasticsearch/reference/current/remove-processor.html)  |不要な情報を削除。<br>Grokによってパーシングされた後で不要な情報をElasticsearchへ保存する前に削除します|
|[Renameプロセッサ](https://www.elastic.co/guide/en/elasticsearch/reference/current/rename-processor.html)  |上図には含まれていませんが、ログ内のフィールド名を変更します。例えばECSの名前（空間）へ変換するためによく利用されます|

設定の全体は以下の通りとなります。それぞれのプロセッサ設定について説明していきます。

```json-doc:ingest/default.json
{
    "description": "Pipeline for parsing Squid access logs. Requires the geoip and user_agent plugins.",
    "processors": [
        {
            "grok": {
                "field": "message",
                "patterns": [
                    "%{IPORHOST:source.address}:%{NUMBER:source.port} %{DATA:user.id} %{DATA:user.name} \"%{WORD:http.request.method} %{DATA:url.original} HTTP/%{NUMBER:http.version}\" %{NUMBER:http.response.status_code:long} %{NUMBER:http.request.bytes:long} %{NUMBER:http.response.bytes:long} \"%{DATA:http.request.referrer}\" \"%{DATA:user_agent.original}\" %{DATA:squid.access.squid_status}:%{DATA:squid.access.squid_hier} \\[%{NUMBER:squid.access.unix_time}\\] %{IPORHOST:destination.ip}:%{NUMBER:destination.port} %{IPORHOST:destination.domain}",
                    "%{IPORHOST:source.address}:%{NUMBER:source.port} %{DATA:user.id} %{DATA:user.name} \"%{WORD:http.request.method} %{DATA:url.original} HTTP/%{NUMBER:http.version}\" %{NUMBER:http.response.status_code:long} %{NUMBER:http.request.bytes:long} %{NUMBER:http.response.bytes:long} \"%{DATA:http.request.referrer}\" \"%{DATA:user_agent.original}\" %{DATA:squid.access.squid_status}:%{DATA:squid.access.squid_hier} \\[%{NUMBER:squid.access.unix_time}\\] -:- -"
                ],
                "ignore_missing": true,
                "ignore_failure": true
            }
        },
        {
            "grok": {
                "field": "source.address",
                "ignore_missing": true,
                "ignore_failure": true,
                "patterns": [
                    "^(%{IP:source.ip}|%{HOSTNAME:source.domain})$"
                ]
            }
        },
        {
            "rename": {
                "field": "@timestamp",
                "target_field": "event.created",
                "ignore_failure": true
            }
        },
        {
            "date": {
                "field": "squid.access.unix_time",
                "target_field": "@timestamp",
                "formats": [
                    "UNIX_MS"
                 ],
                "ignore_failure": true
            }
        },
        {
            "user_agent": {
                "field": "user_agent.original",
                "ignore_failure": true
            }
        },
        {
            "geoip": {
                "field": "source.ip",
                "target_field": "source.geo",
                "ignore_missing": true
            }
        },
        {
            "geoip": {
                "database_file": "GeoLite2-ASN.mmdb",
                "field": "source.ip",
                "target_field": "source.as",
                "properties": [
                    "asn",
                    "organization_name"
                ],
                "ignore_missing": true
            }
        },
        {
            "rename": {
                "field": "source.as.asn",
                "target_field": "source.as.number",
                "ignore_missing": true
            }
        },
        {
            "rename": {
                "field": "source.as.organization_name",
                "target_field": "source.as.organization.name",
                "ignore_missing": true
            }
        },
        {
            "geoip": {
                "field": "destination.ip",
                "target_field": "destination.geo",
                "ignore_missing": true
            }
        },
        {
            "geoip": {
                "database_file": "GeoLite2-ASN.mmdb",
                "field": "destination.ip",
                "target_field": "destination.as",
                "properties": [
                    "asn",
                    "organization_name"
                ],
                "ignore_missing": true
            }
        },
        {
            "rename": {
                "field": "destination.as.asn",
                "target_field": "destination.as.number",
                "ignore_missing": true
            }
        },
        {
            "rename": {
                "field": "destination.as.organization_name",
                "target_field": "destination.as.organization.name",
                "ignore_missing": true
            }
        }, 
        {
            "remove": {
                "field": "message",
                "ignore_missing": true,
                "ignore_failure": true
            }
        }
    ],
    "on_failure": [
        {
            "set": {
                "field": "error.message",
                "value": "{{ _ingest.on_failure_message }}"
            }
        }
    ]
}
```

###GrokプロセッサによるログメッセージのJSON変換
GrokプロセッサによりFilebeatから転送されたJSONドキュメント内の**message**フィールドをパーシングし各フィールドを生成します。

※Grokのしくみについては「[標的型攻撃に対するJPCERT/CCのおすすめログ設定をElasticsearchで構築してみる（プロキシサーバ編）](https://qiita.com/rhpenguin/items/7ec7ddf562906257e297)」を参照してください。

###変換先のテンプレート定義

まずGrokプロセッサがインデクスへ格納するログ情報のJSON形式（テンプレート）を定義します。テンプレートはデフォルトでは**/etc/filebeat/fields.yml**に定義されています。このファイルを**my_fields.yml**としてコピーしSquidモジュール用の定義を追加します。

```
cd /etc/filebeat
cp fields.yml my_fields.yml
```

###Elastic Common Schema (ECS)を利用
[ECS](https://github.com/elastic/ecs)の定義は既に上述のfields.ymlに含まれていますので特に追加は必要ありません。

本モジュールでは以下のように[ECS](https://github.com/elastic/ecs)を利用します。

|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|説明|
|---|---|
|[source](https://github.com/elastic/ecs/blob/master/schemas/source.yml)|クライアント（例：Webブラウザ）の接続元情報が設定されます|
|[destination](https://github.com/elastic/ecs/blob/master/schemas/destination.yml)|接続先サーバー（例：インターネットのWebサーバ）の接続先情報が設定されます|
|[user](https://github.com/elastic/ecs/blob/master/schemas/user.yml)|プロキシ認証情報が設定されます|
|[http](https://github.com/elastic/ecs/blob/master/schemas/http.yml)|HTTPプロトコル情報が設定されます|
|[user_agent](https://github.com/elastic/ecs/blob/master/schemas/user_agent.yml)|UserAgent情報が設定されます|
|[url](https://github.com/elastic/ecs/blob/master/schemas/url.yml)|URL情報が設定されます|

###Squid用モジュールのテンプレート定義
ECSに含まれていないSquid特有の情報については別途定義を**/etc/filebeat/my_fields.yml**へ追加します。

```/etc/filebeat/my_fields.yml
- key: squid
  title: "Squid"
  description: >
    Squid Module
  short_config: true
  fields:
    - name: squid
      type: group
      description: >
        Squid fields.
      fields:
        - name: access
          type: group
          description: >
            Contains fields for the Squid HTTP Server access logs.
          fields:
            - name: squid_status
              type: keyword
              description: >
                Squid request status (TCP_MISS etc).
            - name: squid_hier
              type: keyword
              description: >
                Squid hierarchy status (DEFAULT_PARENT etc).
            - name: unix_time
              type: keyword
              description: >
                Timestamp by UNIX_MS.
```

###Grokプロセッサの詳細
Grokプロセッサによるログメッセージのパーシング結果を変換するJSON形式を定義できました。次にプロセッサの設定を以下の通り行います。

```json-doc:ingest/default.json
{
  "description": "Pipeline for parsing Squid access logs. Requires the geoip and user_agent plugins.",
  "processors": [{
        {
            "grok": {
                "field": "message",
                "patterns": [
                    "%{IPORHOST:source.address}:%{NUMBER:source.port} %{DATA:user.id} %{DATA:user.name} \"%{WORD:http.request.method} %{DATA:url.original} HTTP/%{NUMBER:http.version}\" %{NUMBER:http.response.status_code:long} %{NUMBER:http.request.bytes:long} %{NUMBER:http.response.bytes:long} \"%{DATA:http.request.referrer}\" \"%{DATA:user_agent.original}\" %{DATA:squid.access.squid_status}:%{DATA:squid.access.squid_hier} \\[%{NUMBER:squid.access.unix_time}\\] %{IPORHOST:destination.ip}:%{NUMBER:destination.port} %{IPORHOST:destination.domain}",
                    "%{IPORHOST:source.address}:%{NUMBER:source.port} %{DATA:user.id} %{DATA:user.name} \"%{WORD:http.request.method} %{DATA:url.original} HTTP/%{NUMBER:http.version}\" %{NUMBER:http.response.status_code:long} %{NUMBER:http.request.bytes:long} %{NUMBER:http.response.bytes:long} \"%{DATA:http.request.referrer}\" \"%{DATA:user_agent.original}\" %{DATA:squid.access.squid_status}:%{DATA:squid.access.squid_hier} \\[%{NUMBER:squid.access.unix_time}\\] -:- -"
                ],
                "ignore_missing": true,
                "ignore_failure": true
            }
        },
        {
            "grok": {
                "field": "source.address",
                "ignore_missing": true,
                "ignore_failure": true,
                "patterns": [
                    "^(%{IP:source.ip}|%{HOSTNAME:source.domain})$"
                ]
            }
        },
......
  }]
}
```

Squidの元ログは以下のように記録されます。

```text:access.log（処理前）
192.168.0.134:50435 - - \"GET http://xxx.example.com HTTP/1.1\" 200 2991 918 \"http://xxx.example.com/xxx.js\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36\" TCP_MISS:HIER_DIRECT [xxxxxxxx35237] 10.0.0.3:80 xxx.example.com
```
例えばsource.addressやsource.ipには「192.168.0.134」が、destination.ipには「10.0.0.3」が代入されます。またurl.originalには「xxx.example.com/xxx.js」が入ります。


設定の詳細については[こちら](https://www.elastic.co/guide/en/elasticsearch/reference/current/grok-processor.html)を参照。


###DateプロセッサによるISO8601形式タイムスタンプの追加
Squidのログで記録されるUNIXタイムスタンプからISO8601形式タイムスタンプを生成し追加します。

```json-doc
{
  "description": "Pipeline for parsing Squid access logs. Requires the geoip and user_agent plugins.",
  "processors": [{
  ......
        {
            "date": {
                "field": "squid.access.unix_time",
                "target_field": "@timestamp",
                "formats": [
                    "UNIX_MS"
                 ],
                "ignore_failure": true
            }
        },
  ......
  }],
  ......
}
```

###User Agentプロセッサによるブラウザ情報のパーシング
ユーザエージェント情報(**user_agent.original**フィールド)をパーシングします。

```json-doc:ingest/default.json
{
  "description": "Pipeline for parsing Squid access logs. Requires the geoip and user_agent plugins.",
  "processors": [{
  ......
        {
            "user_agent": {
                "field": "user_agent.original",
                "ignore_failure": true
            }
        },
  ......
  }],
  ......
}
```

詳細については[こちら](https://www.elastic.co/guide/en/elasticsearch/reference/current/user-agent-processor.html)を参照。

※以前はUser Agentプロセッサを利用するためにはElasticsearchへプラグインを別途追加する必要がありましたが、7.x.x系ではデフォルトで組み込まれています。


###GeoIPプロセッサによる接続先サーバの地理情報の付加
接続元また接続先IPアドレスの地理情報を付加します。

```json-doc:ingest/default.json
{
  "description": "Pipeline for parsing Squid access logs. Requires the geoip and user_agent plugins.",
  "processors": [{
  ......
        {
            "geoip": {
                "field": "source.ip",
                "target_field": "source.geo",
                "ignore_missing": true
            }
        },
        {
            "geoip": {
                "database_file": "GeoLite2-ASN.mmdb",
                "field": "source.ip",
                "target_field": "source.as",
                "properties": [
                    "asn",
                    "organization_name"
                ],
                "ignore_missing": true
            }
        },
  ......
        {
            "geoip": {
                "field": "destination.ip",
                "target_field": "destination.geo",
                "ignore_missing": true
            }
        },
        {
            "geoip": {
                "database_file": "GeoLite2-ASN.mmdb",
                "field": "destination.ip",
                "target_field": "destination.as",
                "properties": [
                    "asn",
                    "organization_name"
                ],
                "ignore_missing": true
            }
        },
        {
  ......
  }],
  ......
}
```

詳細については[こちら](https://www.elastic.co/guide/en/elasticsearch/reference/current/geoip-processor.html)を参照。

※以前はGeoIPプロセッサを利用するためにはElasticsearchへプラグインを別途追加する必要がありましたが、7.x.x系ではデフォルトで組み込まれています。

###Removeプロセッサによる不要な情報の削除
不要または冗長な情報を削除します。
パーシングしたmessageフィールドは不要のため削除します。

```json-doc:ingest/default.json
{
  "description": "Pipeline for parsing Squid access logs. Requires the geoip and user_agent plugins.",
  "processors": [{
  ......
  }, {
    "remove": {
      "field": "message",
      "ignore_missing": true,
      "ignore_failure": true
    }
  ......
  }],
  ......
}
```
※後述の「Kibanaでログを確認」ではこの設定はデバッグ用にはずしてあります。必要に応じて追加してください。

詳細については[こちら](https://www.elastic.co/guide/en/elasticsearch/reference/current/remove-processor.html)を参照。

#Filebeatモジュールの設定手順
Squid用のモジュールが完成しましたのでそれをdmz.example.comへデプロイします。

###モジュールの設定ファイル作成
特に変更はありません。

```
/etc/filebeat/
   `- modules.d/
       `- squid.yml.disabled
```

```yml:/etc/modules.d/squid.yml.disabled
- module: squid
  # Access logs
  access:
    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
```
|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|説明|
|---|---|
|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|既存のテンプレート設定を更新|
|setup.ilm.enabled: false|本記事では[ILM](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-lifecycle-management.html)は無効にしておきます。そのためインデクスは日付単位で生成されます|

詳細は**/etc/filebeat/filebeat.reference.yml**を参照してください。

```yml:/etc/filebeat/filebeat.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
setup.ilm.enabled: false
```

設定を確認します。log.example.com:9200(Elasticsearch)への接続確認も行っておきましょう。

```text
cd /etc/filebeat
/usr/share/filebeat/bin/filebeat test config
/usr/share/filebeat/bin/filebeat test output
```


Filebeatを再起動します。

```text
systemctl restart filebeat.service
```

###モジュールの有効化 
以上の設定作業が終わったらSquid用のモジュールを有効化します。

```text
filebeat modules enable squid
```

###モジュールのテンプレート設定をElasticsearchへ注入

```text
filebeat setup --index-management
```

###モジュールのパイプライン設定をElasticsearchへ注入

```text
filebeat setup --pipelines -modules squid
```

###補足
```
テンプレートの参照
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-*

registryファイルのクリア
rm /var/lib/filebeat/registry
```

#Kibanaでログを確認

* Management/Create Index Patternにて filebeat-*を指定してインデクスパターンを生成
* Discoverにてパーシングされたログを確認できます。

<img width="717" alt="kibana_squid3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362125/5530ba29-0add-5b91-aeff-47aedf770e41.png">

```json-doc:最終的に生成されたログ
{
  "_index": "filebeat-7.4.1-2019.10.24",
  "_type": "_doc",
  "_id": "X-Ly_xxxu7mxxxxxxxxxxxxxxxxx",
  "_version": 1,
  "_score": null,
  "_source": {
    "agent": {
      "hostname": "dmz_server",
      "id": "xxxxxxx-xxxx-xxxx-xxxx-xxxxxx",
      "type": "filebeat",
      "ephemeral_id": "xxxxxxx-xxxx-xxx-xxxx-xxxxxxxxxxxxxxxxx",
      "version": "7.4.1"
    },
    "log": {
      "file": {
        "path": "/var/log/squid/access.log"
      },
      "offset": 204461
    },
    "destination": {
      "geo": {
        "continent_name": "North America",
        "country_iso_code": "US",
        "location": {
          "lon": -97.822,
          "lat": 37.751
        }
      },
      "as": {
        "number": 15169,
        "organization": {
          "name": "Google LLC"
        }
      },
      "port": "443",
      "domain": "www.google.com",
      "ip": "172.217.161.36"
    },
    "source": {
      "address": "192.168.0.134",
      "port": "51325",
      "ip": "192.168.0.134"
    },
    "message": "192.168.0.134:51325 - - \"CONNECT www.google.com:443 HTTP/1.1\" 200 3541 66346 \"-\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0\" TCP_TUNNEL:HIER_DIRECT [1571940395920] 172.217.161.36:443 www.google.com",
    "fileset": {
      "name": "access"
    },
    "url": {
      "original": "www.google.com:443"
    },
    "input": {
      "type": "log"
    },
    "@timestamp": "2019-10-24T18:06:35.920Z",
    "ecs": {
      "version": "1.1.0"
    },
    "service": {
      "type": "squid"
    },
    "host": {
      "hostname": "dmz_server",
      "os": {
        "kernel": "4.15.0-66-generic",
        "codename": "bionic",
        "name": "Ubuntu",
        "family": "debian",
        "version": "18.04.1 LTS (Bionic Beaver)",
        "platform": "ubuntu"
      },
      "containerized": false,
      "name": "dmz_server",
      "id": "xxxxxxxxxxxxxxxxxxxxxxx",
      "architecture": "x86_64"
    },
    "http": {
      "request": {
        "referrer": "-",
        "method": "CONNECT",
        "bytes": 3541
      },
      "response": {
        "status_code": 200,
        "bytes": 66346
      },
      "version": "1.1"
    },
    "squid": {
      "access": {
        "squid_hier": "HIER_DIRECT",
        "unix_time": "1571940395920",
        "squid_status": "TCP_TUNNEL"
      }
    },
    "event": {
      "created": "2019-10-24T18:06:37.572Z",
      "module": "squid",
      "dataset": "squid.access"
    },
    "user": {
      "name": "-",
      "id": "-"
    },
    "user_agent": {
      "original": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:70.0) Gecko/20100101 Firefox/70.0",
      "os": {
        "name": "Windows 10"
      },
      "name": "Firefox",
      "device": {
        "name": "Other"
      },
      "version": "70.0"
    }
  },
  "fields": {
    "suricata.eve.timestamp": [
      "2019-10-24T18:06:35.920Z"
    ],
    "@timestamp": [
      "2019-10-24T18:06:35.920Z"
    ],
    "event.created": [
      "2019-10-24T18:06:37.572Z"
    ]
  },
  "highlight": {
    "suricata.eve.http.url": [
      "@kibana-highlighted-field@www.google.com:443@/kibana-highlighted-field@"
    ],
    "url.original": [
      "@kibana-highlighted-field@www.google.com:443@/kibana-highlighted-field@"
    ]
  },
  "sort": [
    01234567890
  ]
}
```

#まとめ

Filebeatで収集するSquidログを[Elastic Common Schema (ECS)](https://github.com/elastic/ecs)へ対応させてみました。こうすることで例えば[Elastic SIEM](https://www.elastic.co/jp/blog/introducing-elastic-siem)で分析する際にもSquidのログを利用可能となります。

※本記事で作成した[Filebeat](https://www.elastic.co/jp/products/beats/filebeat)モジュールやSquidの設定例は[こちら](https://github.com/rhpenguin/Filebeat-module-for-Squid)へ置いておきました。