MapR-DBとAudit機能について 前編


[以前の記事](https://qiita.com/bigt23/items/ec9dd7012b7ed9c89665)ではMapR 6.0から導入されたCDC機能を使って、テーブルへの更新をリアルタイムに補足するサンプルを紹介しました。
MapRをよくご存知の方であれば、MapRのAudit機能と何が違うのか疑問に思った方もいるかと思います。
そこで本エントリでは古来から存在するAudit機能についてあらためて紹介し、MapR-DBのAudit機能とCDCについて比較してみたいと思います。
さらにMapR 6.0.1から導入されたAudit Stream機能についても紹介しようと思いますが、これら全てを網羅しようとするとボリュームが大きくなりますので、以下のように3編に分けて紹介します。
構成は以下のようになっています。

* 前編
    * Audit機能の概要と種類
    * dataレベルのAudit機能ログの出力
* 中編
    * Auditログ中のIDの復号と解析  
    * MapR-DBのAudit機能とCDCの比較
* 後編
    * Audit Streamについて
    * Audit Streamの起動
    * Audit StreamのConsume

本記事は前編となり、まずはログの出力までしてみましょう。

# Audit機能の概要と種類

## 概要

MapRのAuditはユーザによるデータアクセスの把握やアクセス規制に関するコンプライアンスを実現するための機能となります。
Audit機能によりMCS、ディレクトリ・ファイル、MapR-DB、MapR-ESへのアクセス状況を把握することが出来ます。
また、Audit機能を利用することで、どのユーザが一番アクセス頻度が高いか、どんなアクションが一番実行されるか、セキュアなIPから気密性の高いデータへのアクセスが発生しているか、といったセキュリティ関連からの解析も可能です。
一方で、どのデータが一番アクセス頻度が高く、よりシェアされるべきか、逆にどのデータが一番アクセス頻度が低く価値も低いと言えるか、どのadmin作業がより多く実行されており、自動化の恩恵を受けやすいか、といったデータサイエンティスト的な観点からの解析も可能となります。

## 種類

Audit機能は **clusterレベル** と **dataレベル** の2つの種類に大別されます。
clusterレベルのAudit機能はmaprcliコマンドの実行、MCSへのログイン、Volume単位の操作などがAudit対象となり、`/opt/mapr/logs/cldbaudit.log.json`, `/opt/mapr/logs/authaudit.log.json`, `/opt/mapr/mapr-cli-audit-log/audit.log.json`といったファイルに書き込まれます。
詳細に関しましては[こちら](https://mapr.com/docs/61/SecurityGuide/AuditingClusterAdminActivity.html)をご参照下さい。

一方で、[dataレベルのAudit機能](https://mapr.com/docs/61/SecurityGuide/Auditing-FilesystemTableOperations.html)は実際のテーブルやファイルシステムへの操作が対象となります。
本記事のハイライトの1つは、dataレベルのAudit機能の一部であるMapR-DBのAuditとCDCとの比較になり、こちらについては中編で紹介します。

# dataレベルのAudit機能ログの出力

Audit機能を有効にする上では、以下のような階層を意識して設定を行う必要があります。


* (上位)システムレベル
    * Volumeレベル
        * (下位)Filesystem, DB, ESレベル

こちらの階層は上位レベルでの設定が下位の設定内容に影響することを示していますので、Auditを有効にする上では上位レベルから有効にしていく必要があります[^1]。
逆に言うと、あるタイミングでAuditをまとめて無効にしたい場合は上位のみの設定で無効にすることが出来ます。
以下、それぞれ順を追って説明していきます。


## システムレベルの設定

まず、システムレベルのAudit機能の有効化に必要なコマンドは`maprcli audit data`コマンドとなります。
以下のように有効にしてみましょう。

```bash

$ maprcli audit info -json
{
        "timestamp":1542617878853,
        "timeofday":"2018-11-19 05:57:58.853 GMT+0900",
        "status":"OK",
        "total":1,
        "data":[
                {
                        "data":{
                                "enabled":"0",
                                "maxSizeGB":"32",
                                "retentionDays":"30"
                        },
                        "cluster":{
                                "enabled":"1",
                                "maxSizeGB":"NA",
                                "retentionDays":"NA"
                        }
                }
        ]
}

$ maprcli audit data -enabled true -maxsize 1 -retention 28
$ maprcli audit info -json
{
        "timestamp":1542617961914,
        "timeofday":"2018-11-19 05:59:21.914 GMT+0900",
        "status":"OK",
        "total":1,
        "data":[
                {
                        "data":{
                                "enabled":"1",
                                "maxSizeGB":"1",
                                "retentionDays":"28"
                        },
                        "cluster":{
                                "enabled":"1",
                                "maxSizeGB":"NA",
                                "retentionDays":"NA"
                        }
                }
        ]
}
```

`maprcli audit info`コマンドより"cluster"カラムで出力されるのがclusterレベル、"data"カラムで出力されるのがdataレベルのAuditの有無の設定となります。
dataレベルのAuditの設定を有効にする上では、追加項目としてAuditログの最大サイズや保持期間も設定してみました。
コマンドの詳細の確認については[こちら](https://mapr.com/docs/61/ReferenceGuide/audit-data.html)をどうぞ。


## Volumeレベルの設定

VolumeレベルのAudit機能はVolumeの`audited`パラメタによりコントロールされます。
`audited`パラメタを設定した場合には、そのVolume内でさらに[下位層での設定](https://qiita.com/bigt23/items/5a220cce8674abf9e379#filesystem-db-es%E3%83%AC%E3%83%99%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A)で指定したファイル・ディレクトリ、テーブル、ESがAudit対象となります。

Volumeレベルの設定には以下の方法があります
1. Volumeの[作成](https://mapr.com/docs/61/ReferenceGuide/volume-create.html)もしくは[編集](https://mapr.com/docs/61/ReferenceGuide/volume-modify.html)時に`-auditenabled`パラメタを付与
2. [`volume audit`コマンド](https://mapr.com/docs/61/ReferenceGuide/volume-audit.html)に`-enabled`パラメタを付与

`volume audit`コマンドはAuditの設定のみ行うためのコマンドとなります。
Volumeの作成、編集コマンドでVolumeの全てのパラメタの設定が可能となりますが、Volumeのパラメタが多岐に渡るためAuditの設定用にコマンドを切り出したと考えられます。

早速Audit機能を有効にしたVolumeを作成し、各パラメタを確認します

```bash
$ maprcli volume create -name enable_audit -auditenabled true  -path /enable_audit -type rw -coalesce 1
$ maprcli volume info -name enable_audit -json
{
        "timestamp":1542639292991,
        "timeofday":"2018-11-19 09:54:52.991 GMT-0500 午前",
        "status":"OK",
        "total":1,
        "data":[
...
〜中略〜
...
                        "auditVolume":0,
                        "audited":1,
...
以下省略

```

ここで設定した`coalesce`はログの粒度を設定するパラメタとなります。
` coalesce`で設定された時間(単位は分)の中で同じIPアドレスのクライアントから同じファイルに対して同じ操作(READ, WRITE, もしくは GETATTRのいずれか)が繰り返し行われた場合、これらの記録は単一の記録にまとめられます。
` coalesce`を0に設定した場合は、すべての処理が記録されます。
また、詳細は中編に譲りますが`dataauditops`を設定することにより監視する操作を選択することもできます。 これらの設定は`enableddataauditoperations`、`disableddataauditoperations`に反映されます。

## Filesystem, DB, ESレベルの設定

Volumeレベルの設定まで終わったら次は監視対象の設定です。
設定はディレクトリ、ファイル、テーブル、ESを対象に`mfs -setaudit`コマンドを使って以下のように行います。

```bash
$ hadoop fs -mkdir /enable_audit/set_audit
$ hadoop fs -mkdir /enable_audit/non_set_audit
$ hadoop mfs -setaudit on /enable_audit/set_audit
```

上記で作ったVolumeのあるディレクトリを対象に設定してみました。
設定を行ったディレクトリを`mfs -ls`コマンドで見ると、以下のように監視対象かどうかを示すフラグ(4つ目)を確認できます。

```bash
$ hadoop mfs -ls /enable_audit
Found 2 items
drwxr-xr-x  Z U U U   - mapr mapr          0 2018-11-24 09:38  268435456 /enable_audit/non_set_audit
               p 2305.34.397702  ov0:5660 ov1:5660 ov2:5660
drwxr-xr-x  Z U A U   - mapr mapr          0 2018-11-24 09:38  268435456 /enable_audit/set_audit
               p 2305.32.397698  ov0:5660 ov1:5660 ov2:5660
```

このフラグが **A** の場合監視対象ON、 **U** の場合監視対象OFFとなります。

これでやっと準備が出来ました

## data Audit機能の確認

Audit機能の確認のため、`non_set_audit`、`set_audit`ディレクトリに対して操作を行ってみます。

```bash
$ for i in {0..100} ; do \ 
    hadoop fs -put test.yaml /enable_audit/set_audit/${i}.yaml ;  \
    hadoop fs -put test.yaml /enable_audit/non_set_audit/${i}.yaml ; \
    hadoop fs -chmod 777 /enable_audit/set_audit/${i}.yaml ; \
    hadoop fs -chmod 777 /enable_audit/non_set_audit/${i}.yaml ; \
    hadoop fs -rm /enable_audit/set_audit/${i}.yaml ; \
    hadoop fs -rm /enable_audit/non_set_audit/${i}.yaml ; \
    echo "${i} finished"  ; \
done
```

Auditログが記録されると、デフォルトの設定で `/var/mapr/local/<ホスト名>/audit/5660/<Auditの種類>.log-YYYY-mm-DD-<index>.json` にデータが記録されます。

今回はファイルシステムの操作を行ったので`FSAudit.log`を見てみましょう。

```
...
{"timestamp":{"$date":"2018-11-24T15:17:02.095Z"},"operation":"WRITE","uid":5000,"ipAddress":"10.10.75.127","srcFid":"2305.233.398100","volumeId":27878493,"status":0}
{"timestamp":{"$date":"2018-11-24T15:17:02.096Z"},"operation":"LOOKUP","uid":5000,"ipAddress":"10.10.75.127","srcFid":"2305.32.397698","srcName":"99.yaml","volumeId":27878493,"status":2}
{"timestamp":{"$date":"2018-11-24T15:17:02.096Z"},"operation":"RENAME","uid":5000,"ipAddress":"10.10.75.81","srcFid":"2305.32.397698","dstFid":"2305.32.397698","srcName":"99.yaml._COPYING_","dstName":"99.yaml","volumeId":27878493,"status":0}
{"timestamp":{"$date":"2018-11-24T15:17:05.215Z"},"operation":"CHPERM","uid":5000,"ipAddress":"10.10.75.81","srcFid":"2305.233.398100","permissions":"0777","volumeId":27878493,"status":0}
{"timestamp":{"$date":"2018-11-24T15:17:08.460Z"},"operation":"LOOKUP","uid":5000,"ipAddress":"10.10.75.81","srcFid":"2305.32.397698","dstFid":"2305.233.398100","srcName":"99.yaml","volumeId":27878493,"status":0}
{"timestamp":{"$date":"2018-11-24T15:17:08.461Z"},"operation":"DELETE","uid":5000,"ipAddress":"10.10.75.127","parentFid":"2305.32.397698","childFid":"2305.233.398100","childName":"99.yaml","volumeId":27878493,"status":0}
...
```

operation欄がWRITE, LOOKUP, RENAME, CHPERMと今回の作業らしきものが記録されていますね。
しかし、肝心の対象ファイルやユーザはMapRで利用するIDが使われているために、内容の把握にはこれらIDを復号する必要があります。
とりあえずログの出力までは出来ましたので今回はここまでとし、次回はIDの復号から始めましょう。


[^1]: MapR 6.0からはVolume内のデータを全てAudit対象とするforce audit機能が追加されました。これによりVolume内のすべてのデータアクセスを監視対象とすることも出来ますので下位層の設定を簡略化することが出来ますが、本記事では省略し昔ながらの設定方法を紹介します。