MySQLで監査ログを取得する

# MySQLの監査ログを取得したい
WEBアプリケーションの保守をしていると、本番DBに対してクエリを投げる機会がある。
いつ、誰が、何を発行したのかを確認する必要があるので、監査ログを取得したい。


# Audit log
MySQL Enterpriseでは監査ログの取得機能がある。
これの出力で、DBへのアクセス記録や変更履歴を確認することができる。
「Oracleの監査仕様を満たすように設計されており」とあることから、Oracleと同様の水準で取得できるよう。

https://dev.mysql.com/doc/refman/8.0/ja/audit-log.html

# Amazon RDS for MySQL でAudit logを取得する。
主な作業は2つ
1. Option group を作成する。
2. RDSにOption groupを設定する。

### Option group を作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321173/f61aafc8-3770-9713-55ce-47ecd642bbd9.png)


作成したOption groupに「MARIADB_AUDIT_PLUGIN」を設定してOptionを設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321173/7aeddf65-802e-d280-10b4-99e2c2e8da1e.png)


設定可能なオプションの一覧

|  オプション設定  |  許可された値  | 説明 |
| ---- | ---- | ---- |
| SERVER_AUDIT | FORCE_PLUS_PERMANENT | セキュリティのために有効になっており、実行時にプラグインをアンインストールできないようになっています。 |
| SERVER_AUDIT_EVENTS | CONNECT, QUERY, QUERY_DDL, QUERY_DML, QUERY_DCL, QUERY_DML_NO_SELECT | ログに記録するアクティビティのタイプ。MariaDB 監査プラグインのインストール自体も記録される。CONNECTとQUERYを基本に、DDLだけ取得するとか、SELECTは取得しないとかを選択できる。 |
| SERVER_AUDIT_EXCL_USERS | 複数のカンマ区切り値（user） | 指定されたユーザーからのアクティビティを除外する。 |
| SERVER_AUDIT_INCL_USERS | 複数のカンマ区切り値（user） | 指定されたユーザーからのアクティビティのみを含る。SERVER_AUDIT_EXCL_USERSとSERVER_AUDIT_INCL_USERSの設定は排他的なのでどちらか。 | 
| SERVER_AUDIT_FILE_PATH | パス（デフォルトは/rdsdbdata/log/audit/） | ログファイルの場所。 |
| SERVER_AUDIT_FILE_ROTATE_SIZE | 1–1000000000 | ファイルがローテーションするサイズ（バイト） |
| SERVER_AUDIT_FILE_ROTATIONS | 0–100 | 保存するログローテーション数。 |
| SERVER_AUDIT_LOGGING | ON | ONにするとログ記録がアクティブになる。Amazon RDSでは非アクティブはサポートしていないため、監査プラグイン自体を削除する必要がある。 |
| SERVER_AUDIT_QUERY_LOG_LIMIT | 0–2147483647 | レコードのクエリ文字列の長さに対する制限。 |

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/Appendix.MySQL.Options.AuditPlugin.html#Appendix.MySQL.Options.AuditPlugin.Options


### RDSにOption groupを設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321173/91cec78f-4d2c-1776-059e-e23aa1dbbd89.png)


監査ログをチェックすると、CloudWatchのロググループが自動的に作成される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321173/af34c1c7-3ed8-67d2-505e-834d58db1879.png)


# logの形式

```
timestamp,serverhost,username,host,connectionid,queryid,operation,database,object,retcode
1632053566093036,serverhost,user,host,6498377,113407172,QUERY,database,'/* ApplicationName=DBeaver 7.3.4 - SQLEditor <Script-1.sql> */ update user_table set name = \'田中\' where id = 1 -- ユーザーの更新',0
```

ログには以下が出力される。

|  フィールド  |  説明  |
| ---- | ---- |
|  timestamp  |  T記録されたイベントの UNIX タイムスタンプ (マイクロ秒の精度)。 |
|  serverhost  |  イベントが記録されているインスタンスの名前。  |
|  username  |  ユーザーの接続されたユーザー名。  |
|  host  |  ユーザーの接続元のホスト。  |
|  connectionid  |  記録されたオペレーションの接続 ID 番号。  |
|  queryid  |  クエリ ID 番号。リレーショナルテーブルイベントと関連するクエリの検索に使用できます。TABLE イベントの場合、複数の行が追加されます。  |
|  operation  |  記録されたアクションの種類。指定できる値は CONNECT、QUERY、READ、WRITE、CREATE、ALTER、RENAME、DROP です。  |
|  database  |  USE コマンドにより設定されたアクティブなデータベース。  |
|  object  |  QUERY イベントの場合、この値は、データベースが実行したクエリを示します。TABLE イベントの場合、テーブル名を示します。  |
|  retcode  |  記録されたオペレーションのリターンコード。  |

※参考
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Auditing.html#AuroraMySQL.Auditing.Logs

接続元や発行クエリまで一通り確認できる。
クエリの箇所に今回クエリ発行したDBクライアントツールの名前も出てきており、ツールごとに異なるだろうが変なことやってるのは分かってしまう。

クエリにコメントをつけてもその通り反映されたので、コメントの運用ルールである程度判定もできそう。
少なくとも誰が何をしたかは取得できるので、定期的な棚卸しに使えそう。