wazuh agent が入っているホストの任意のファイルを td-agent に送る方法をメモしておく。

単純にログを収集するのであればホストに td-agent を入れればいいのだが、例えば管理している全てのホストにおいて、特定のログを収集したい場合、全部に td-agent を入れるのは面倒くさい。
(wazuh agent を全部入れるのも面倒じゃないか!というのは、それはそうなのだが…)

wazuh には Fluentd forwarder という機能があって、わざわざ td-agent を追加で入れなくても ossec-logcollector と併用することで、リモート / ローカルの td-agent に forward することが可能。

wazuh は閾値を使った監視に弱いが、これを使うことで例えば CloudWatch や BigQuery などの wazuh とは別のログ分析システムに送信することで、閾値を使った監視も可能になる。

まぁ td-agent が入っているならそれを使えばいいのだけど、あえて wazuh でやるメリットとしては Centralized configuration によって全 agent に対して集中的に管理ができるということかな。

使い方は上記ドキュメントの通りなのだが、メモ程度に書いておく。

まずは td-agent の設定。forward の設定と CloudWatch に送信する設定を入れておく。

<source>
  @type forward
  port 24224
  bind 0.0.0.0
</source>
<match **>
  @type cloudwatch_logs
  @id out_cloudwatch_logs
  log_group_name "#{ENV['LOG_GROUP_NAME']}"
  auto_create_stream true
  use_tag_as_stream true
  retention_in_days "#{ENV['RETENTION_IN_DAYS'] || 'nil'}"
  json_handler yajl
  log_rejected_request "#{ENV['LOG_REJECTED_REQUEST']}"
</match>

続いて agent に fluentd-forwarder の設定を入れる。

localfiletarget に指定した socket に logcollector が書き込み、td-agent に送信される仕組みっぽい。
なので socket というのは td-agent が生やしている socket とは全く関係なくて、logcollector で使うために socket のパス。
object_key を指定すると、指定した値をキーとして送信してくれる。ここでは message と指定しているので {"message": "..."} のようになる。
agent なので profile を使ってロールごとに tag を入れるということもできる気がする。試してないけど。

<agent_config>
  <fluent-forward>
    <enabled>yes</enabled>
    <tag>wazuh.test</tag>
    <address>fluentd.monitor.svc.cluster.local</address>
    <socket_path>/var/run/fluentd.sock</socket_path>
    <port>24224</port>
    <object_key>message</object_key>
  </fluent-forward>
  
  <socket>
    <name>fluent_socket</name>
    <location>/var/run/fluentd.sock</location>
    <mode>udp</mode>
  </socket>
  
  <localfile>
    <log_format>json</log_format>
    <location>/path/to/log.json</location>
    <target>fluent_socket</target>
  </localfile>
</agent_config>

これで agent を起動し、設定が正しければ次のようなログが出る。

2020/06/07 23:31:14 fluent-forward: INFO: Connected to host fluentd.monitor.svc.cluster.local:24224

/path/to/log.json に書き込むと CloudWatch に流れる。

$ echo '{"source": "192.168.1.1", "username": "admin"}' >> /path/to/log.json
$ echo '{"source": "192.168.1.1", "username": "john"}' >> /path/to/log.json
$ echo '{"source": "192.168.1.1", "username": "test"}' >> /path/to/log.json
$ echo '{"source": "10.1.1.1", "username": "alice"}' >> /path/to/log.json
$ echo '{"source": "10.1.1.1", "username": "alice"}' >> /path/to/log.json

こんな感じで入っているので、あとはアラートなり可視化なりをお好きに調理する。

cloudwatch

master / worker の ossec.conf に /var/ossec/alerts/alerts.json などを収集するように指定しておくと ELK 用意しなくていいかも。