designetwork

ネットワークを軸としたIT技術メモ

FluentdでIPアドレスから名前解決してホスト名フィールドを追加する(fluent-plugin-resolv)

f:id:daichi703n:20171014160852p:plain

こちらの記事でHerokuのアクセスログ (はてなブログに仕込んだJavaScript) を収集したが、単純なパースでアクセス元はIPアドレスでの表示となっている。

designetwork.hatenablog.com

ログから知りたいことの一つとして「だれ・どこからアクセスされているか」があるため、IPアドレスDNS逆引きしてドメイン・企業がわかるようにする。

DNS逆引きFluentdプラグイン

2017/10月時点では以下の二つのプラグインがメジャーだと思われる。

  • fluent-plugin-resolv

github.com

d.hatena.ne.jp

  • fluent-plugin-filter-resolv

fluent-plugin-resolvはメンテナンスが止まっており、filterディレクティブに対応していないため、tagルーティング設計が必要だった。Filterプラグインを作成してみようかとも思ったが、既に開発しリリースされているものがあった。

github.com

プラグインでの実装

それぞれのプラグインを導入し、アクセス元のホストFQDNのフィールドを追加する。

ログは以下の通りパースされている状態から開始する。

2017-10-10T22:12:07+09:00   designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"103.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2016/12/05/home-server-selection"}
2017-10-10T22:15:33+09:00   designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"117.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2016/11/19/sync-request-post-node-js"}
2017-10-10T22:19:43+09:00   designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"27.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2016/04/09/Windows-Server-2016-Technical-Preview"}

バージョンはこちら

$ td-agent --version
td-agent 0.12.31

fluent-plugin-resolv

(参考)こちらで実装例の紹介あり。

komeiy.hatenablog.com

$ sudo td-agent-gem install fluent-plugin-resolv

sourceディレクティブで前述の形式でログを取り込んでいる。record_transformerでフォールドをコピーして追加し、resolvでコピーで作成したフィールドsrc_hostを名前解決してホスト名に変換する。

fluent-plugin-resolvプラグインは、IPアドレスのフィールドをFQDNに変換するものだが、他用途を考慮してIPアドレスの状態でも保存しておきたいため、record_transformerプラグインでフィールドを複製する。

tagルーティングのために変換前はtagプレフィクスを付与しておく必要があある。プレフィクス除外後は他ログと同様のoutputフローに乗せる。

<source>
  @type tail
  path /var/log/td-agent/designetwork/access_log.raw.*.b*
  pos_file /var/log/td-agent/pos/designetwork/access_log.raw.pos
  format multiline
  multiline_flush_interval 5s
  format_firstline /heroku router/
  format1 /.*\"message\":\"\d+ <\d+>\d+ (?<time>\d+-\d+-\d+T\d+:\d+:\d+\.\d+\+\d+:\d+) (?<container_id>[^ ]+) .* fwd=\\\"(?<src_ip>\d+\.\d+\.\d+\.\d+)\\\" .*/
  format2 /.*://(?<access_host>[^/]+)(?<access_path>[^"]+)\\" .*/
  time_key time
  tag pre_resolv.designetwork.access_log.heroku
</source>

<filter pre_resolv.designetwork.access_log.heroku>
  @type record_transformer
  <record>
    src_host ${record["src_ip"]}
  </record>
</filter>

<match pre_resolv.designetwork.access_log.heroku>
  @type resolv
  key_name src_host
  remove_prefix pre_resolv
</match>

fluent-plugin-filter-resolv

プラグインをインストールする。

$ sudo td-agent-gem install fluent-plugin-resolv-filter

こちらはFilterプラグインなので、tagプレフィクス等を考慮する必要なく、処理順序(設定ファイル読み込み順)のみを意識すればよくシンプルにできる。

fluent-plugin-resolvで実装されておらず独自設計したフィールドのコピーがこちらでは含まれており、key_postfixを付与してフィールドを追加してくれる。DNSタイムアウト値も設定できる。

<source>
  @type tail
  path /var/log/td-agent/designetwork/access_log.raw.*.b*
  pos_file /var/log/td-agent/pos/designetwork/access_log.raw.pos
  format multiline
  multiline_flush_interval 5s
  format_firstline /heroku router/
  format1 /.*\"message\":\"\d+ <\d+>\d+ (?<time>\d+-\d+-\d+T\d+:\d+:\d+\.\d+\+\d+:\d+) (?<container_id>[^ ]+) .* fwd=\\\"(?<src_ip>\d+\.\d+\.\d+\.\d+)\\\" .*/
  format2 /.*://(?<access_host>[^/]+)(?<access_path>[^"]+)\\" .*/
  time_key time
#  tag pre_resolv.designetwork.access_log.heroku
  tag designetwork.access_log.heroku
</source>

<filter designetwork.access_log.heroku>
  @type resolv
  key_name src_ip
  key_postfix fqdn
  dns_timeout 2
</filter>

ホスト名フィールド追加ログ

それぞれの実装でいずれも逆引き名前解決されたホスト名フィールド(src_host/src_ip_fqdn)が追加されている。

# fluent-plugin-resolv
2017-10-14T07:54:28+09:00       designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"175.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2016/10/18/win-symbolic-link-deletion","src_host":"xxx.xxx.catv-yokohama.ne.jp"}
2017-10-14T08:56:33+09:00       designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"126.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2017/05/05/esxi-vib-from-web","src_host":"softbankXXX.bbtec.net"}
...
# fluent-plugin-filter-resolv
2017-10-14T15:37:22+09:00       designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"103.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2016/04/09/Windows-Server-2016-Technical-Preview","src_ip_fqdn":"x.x.x.x.shared.user.transix.jp"}
2017-10-14T15:37:57+09:00       designetwork.access_log.heroku  {"container_id":"d.fd8d2572-7604-4521-94df-9fe4dae8fabb","src_ip":"118.x.x.x","access_host":"designetwork.hatenablog.com","access_path":"/entry/2017/03/05/ubuntu-kernel-version","src_ip_fqdn":"KDxxx.ppp-bb.dion.ne.jp"}

まとめ - FluentdでIPアドレスから名前解決してホスト名フィールドを追加する(fluent-plugin-resolv)

fluent-plugin-resolv, fluent-plugin-resolv-filterにより、ログのIPアドレスから逆引き名前解決してホスト名フィールドを追加した。

これにより、アクセス元の企業・ドメインを確認できる。