McAfee MySQL Audit Plugin で MySQL の監査ログを採取する

McAfee が作った MySQL プラグイン “McAfee MySQL Audit Plugin” を使うと、MySQL の監査ログが取得できるようになります。

会社のセキュリティ要件で監査が必要になったので、検証してみました。

特徴

  • 監査対象の DB やテーブルを細かく指定できる。
  • 監査を除外するユーザーも指定可能。
  • JSON 形式でログが出る。
  • 無停止でインストールや設定変更が可能。
  • MySQL >= 5.1 に対応。

インストール手順

CentOS 6.3 (64bit) 上に MySQL 5.6 をインストールしている環境を想定しています。

まず、Plugin のダウンロードページ から最新のバイナリをダウンロードし、MySQL のプラグインディレクトリに解凍します。MySQL のバージョンと OS の bit を間違えないように。

$ wget http://dl.bintray.com/mcafee/mysql-audit-plugin/1.0.4/audit-plugin-mysql-5.6-1.0.4-459-linux-x86_64.zip
$ unzip audit-plugin-mysql-5.6-1.0.4-459-linux-x86_64.zip
$ sudo mv audit-plugin-mysql-5.6/lib/libaudit_plugin.so /usr/lib64/mysql/plugin/

※MySQL のプラグインディレクトリが不明な場合、MySQL クライアントから以下のクエリを叩くことで確認できます。

mysql> show global variables like 'plugin_dir';
+---------------+--------------------------+
| Variable_name | Value                    |
+---------------+--------------------------+
| plugin_dir    | /usr/lib64/mysql/plugin/ |
+---------------+--------------------------+

次に、Audit プラグインを MySQL クライアントからインストールします。

mysql> INSTALL PLUGIN AUDIT SONAME 'libaudit_plugin.so';

※my.cnf に以下の設定を書いて mysqld を再起動してもインストールできます。

[mysqld]
plugin-load=AUDIT=libaudit_plugin.so

以下のようにコマンドを叩いた結果が出ればインストール成功です。

mysql> show plugins;
+----------------------------+----------+--------------------+--------------------+---------+
| Name                       | Status   | Type               | Library            | License |
+----------------------------+----------+--------------------+--------------------+---------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL               | GPL     |
...
| AUDIT                      | ACTIVE   | AUDIT              | libaudit_plugin.so | GPL     |
+----------------------------+----------+--------------------+--------------------+---------+

mysql> show global status like 'AUDIT_version';
+---------------+-----------+
| Variable_name | Value     |
+---------------+-----------+
| Audit_version | 1.0.4-459 |
+---------------+-----------+

プラグインを有効にする

インストールしただけでは Audit Plugin はまだ有効になっていないので、設定する必要があります。設定方法は以下の2通り。

my.cnf に書き込む場合

my.cnf の [mysqld] セクションに書き込んで、mysqld を再起動する。

[mysqld]
audit_json_file = On

MySQL クライアントから有効にする場合

SET ステートメントを使います。この方法なら無停止で動的に設定変更ができます。

mysql> SET GLOBAL audit_json_file = 'On';

プラグインの設定

設定パラメータを全部書くのは面倒なので主要なものだけ。詳しくは Configuration · mcafee/mysql-audit Wiki を参照。

変数名 内容
audit_json_file Audit を有効にするか。`[On
audit_json_log_file Audit ログの保存場所。絶対パスか、data-dir からの相対パスで記述。
audit_record_cmds どのコマンドをロギングするか。カンマ区切り。空白なら全てのコマンドを記録。(e.g.: insert,update,delete)
audit_record_objs ロギングしたいオブジェクト (テーブル)。カンマ区切り。空白なら全てのオブジェクトを記録。 (e.g.: mydb.*,database.table)
audit_whitelist_users ここに指定したユーザーのクエリはロギングしない。カンマ区切り。

設定値は以下のコマンドで確認できます。

mysql> SHOW VARIABLES LIKE 'audit_%';
+---------------------------------+----------------------------+
| Variable_name                   | Value                      |
+---------------------------------+----------------------------+
| audit_checksum                  |                            |
| audit_delay_cmds                |                            |
| audit_delay_ms                  | 0                          |
| audit_json_file                 | OFF                        |
| audit_json_file_flush           | OFF                        |
| audit_json_file_sync            | 0                          |
| audit_json_log_file             | mysql-audit.json           |
| audit_json_socket               | OFF                        |
| audit_json_socket_name          | /tmp/mysql-audit.json.sock |
| audit_offsets                   |                            |
| audit_offsets_by_version        | ON                         |
| audit_record_cmds               |                            |
| audit_record_objs               |                            |
| audit_uninstall_plugin          | OFF                        |
| audit_validate_checksum         | ON                         |
| audit_validate_offsets_extended | ON                         |
| audit_whitelist_users           |                            |
+---------------------------------+----------------------------+
17 rows in set (0.00 sec)

注意

  • MySQL 5.1 では boolean 型は `1で指定しないとエラーになります。(OnorOff` ではダメ)
  • MariaDB や Percona MySQL などの MySQL の派生バイナリにインストールすると、デフォルトではエラーが出て動かせないそうです。この場合、audit_offset の設定が必要です。詳しくは以下の記事を参照。

取得できる値の例

正しく設定できていると、クエリを投げるたびに以下のような値がログに吐かれます。

{
  "msg-type": "activity",
  "date": "1398043832028",
  "thread-id": "8",
  "query-id": "11436",
  "user": "root",
  "priv_user": "root",
  "host": "localhost",
  "ip": "",
  "cmd": "update",
  "objects": [
    {
      "db": "crechu",
      "name": "sessions",
      "obj_type": "TABLE"
    }
  ],
  "query": "UPDATE `crechu`.`sessions` SET `status` = 'card_not_registered', `need_mail` = '0', `merchant_id` = 1, `modified` = '2014-04-21 10:30:32'  WHERE `crechu`.`sessions`.`id` = '1'"
}

それぞれの値の意味は下記。

キー 中身
msg_type 「activity」固定
date コマンドが実行された日時のUNIXTIME。単位はミリ秒。
thread-id スレッドID。コネクション毎のユニークなID。
query-id クエリID。クエリ毎のユニークなID。
user ユーザ名。
priv_user ユーザ名。LDAP認証を使っている場合はuserと異なるユーザ名になるケースがある。基本はpriv_userを見れば良い。
host アクセス元ホスト名。
ip アクセス元IP。
cmd 実行したコマンド。
objects 対処のオブジェクト。
query 実行したクエリー全体。

まとめ

インストールは非常に簡単ですし、動的に ON/OFF の切り替えや設定パラメータの変更が可能です。ログは JSON で出力されるので、fluentd などに食わせて管理するのも楽です。

この記事には書きませんでしたが、監査対象のユーザーやテーブルの指定も簡単でした。

MySQL の監査ログを取りたければ、これを使っておけばひとまず十分ではないでしょうか。

参考