Archive for 10月, 2012

[MySQ] McAfeeのおかげでMySQLで監査ログが取れるようになった

日曜日, 10月 28th, 2012

McAfee MySQL Audit Plugin

McAfee が MySQLの監査ログ取得プラグインをオープンソースでリリースしています。
これがシンプルで便利だったので紹介したいと思います。

米McAfee、MySQL向けの監査ツールを無償公開
http://sourceforge.jp/magazine/12/03/27/1333243

特徴

  • 監査対象としたいテーブルやスキーマを指定できる
  • ログがJSON形式で取り扱い安い
  • ログファイル出力に加えて、UNIXドメインソケットに対して出力可能
  • MySQL5.1, 5.5対応。Audit Plugin Interface 機能のないMySQL5.1 でも利用できる

MySQLではMySQL5.5で追加されたAudit Plugin Interfaceを利用すれば自由に監査プラグインを実装できるのですが、MySQLの内部構造(どの変数にどのような情報が入ってるか?など)の理解やスレッドセーフな実装を要求するもので、比較的ハードルの高いものでした。

監査ログを取得する目的

監査ログは「いつ、だれが、どのように」データにアクセスしたかを記録するものです。
不正アクセス時の被害状況を確認や、DB管理者が適切な運用を行っているかチェックするのに利用されます。

重要なデータをデータベースで扱う上では欠かせない機能です。Oracle DatabaseやMS SQL Serverといった商用製品には監査ログ機能があり、MySQLに欠けている機能のうちの1つでした。

McAfee Audit Plugin では以下のような形式のログを取得することが出来ます。
1クエリで1行出力されます。

{"msg-type":"activity",
"date":"1351346322387",
"thread-id":"5",
"query-id":"19",
"user":"root",
"priv_user":"root",
"host":"localhost",
"cmd":"select",
"objects":[{"db":"test","name":"mytable","obj_type":"TABLE"}],
"query":"select * from test.mytable"}

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 クエリー全体。

セットアップ方法

まずはバイナリをダウンロードしてきて、MySQLのプラグインディレクトリに放り込みます。

mysql> show variables like '%plugin_dir%';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| plugin_dir    | /usr/lib/mysql/plugin |
+---------------+-----------------------+
1 row in set (0.00 sec)

$ wget https://github.com/downloads/mcafee/mysql-audit/audit-plugin-mysql-5.5-1.0.2-345-linux-x86_64.zip
$ unzip audit-plugin-mysql-5.5-1.0.2-345-linux-x86_64.zip 
$ sudo cp audit-plugin-mysql-5.5/lib/libaudit_plugin.so /usr/lib/mysql/plugin

my.cnf に設定を追加してMySQLを再起動します。
audit_record_cmds にログを取りたいコマンドを、audit_record_objs にはログを取りたいオブジェクト(テーブル、ビューetc)を指定します。

この例ではtestスキーマ以下のオブジェクト(テーブル、ビューetc)に対する、INSERT,SELECT,UPDATE,DELETE および、SETによる設定変更のログ取得するようにしています。

$ vi /etc/my.cnf
plugin-load=AUDIT=libaudit_plugin.so
audit_json_log_file=/var/log/mysqld-audit.json
audit_json_file=1
audit_record_cmds=insert,select,update,delete,set_option
audit_record_objs=test.*,{}

プラグインが読み込まれない場合

McAfee Audit Plugin は MySQLの特定の関数をフックする仕組みになっています。Oracle が配布しているバイナリ以外の、OS付属のMySQL、自分でビルドしたMySQL、MariaDBやPercona Serverなどの派生製品ではそのままでは動作しません。対応方法が以下に記載されています。

独自バイナリのaudit_offsetsを求める手順
https://github.com/mcafee/mysql-audit/issues/2

オフィシャルのmysqldを使っているにもかかわらず、以下のようなエラーが出てプラグインが読み込まれない場合があります。

121027 23:07:59 [Note] Audit Plugin: Couldn't find proper THD offsets for: 5.1.51
121027 23:07:59 [ERROR] Plugin 'AUDIT' init function returned error.
121027 23:07:59 [Note] Audit Plugin: deinit

その場合は、ソースコード から、利用しているバージョンに対応するoffsetを見つけて、設定してみてください。特に、バージョン番号に「5.1.42-community-log」のように「-log」が含まれている場合、自動判定がうまくされず、手動設定の必要があるようです。

//offsets for: mysqlrpm/5.1.37/usr/sbin/mysqld (5.1.37-community)
{"5.1.37-community","508ffea25280c9454dcef065e5fd4af2", 6200, 6264, 3672, 3944, 88, 2048},

↓ 6つの数字をそのままmy.cnfに転記

$ vi /etc/my.cnf
audit_offsets=6200, 6264, 3672, 3944, 88, 2048

設定項目

項目名 説明
audit_json_file ログファイルに出力するかどうか。 1 or 0
audit_json_file_flush 1に設定したタイミングでログファイルを再作成する。ログをローテートするときに使う 1
audit_json_file_sync ログファイルを何秒ごとにディスクに同期(sync)するか?0を指定した場合は同期タイミングはOSに従う。 数字
audit_json_socket UNIXドメインソケットに対する出力を行うかどうか。 1 or 0
audit_json_socket_name ソケットファイルのパス。ソケットファイルは別途受け取り側のプログラムで生成しておく必要がある。 /path/to/mysql-audit.sock
audit_offsets 上記参照 audit_offsets=6200, 6264, 3672, 3944, 88, 2048
audit_record_cmds 記録対象のコマンド。カンマ区切り。未指定の場合は全部が対象。SHOW GLOBAL VARIABLESで出力される、Com_XXX と同じものを指定すれば良い。 insert,select
audit_record_objs 記録対象のオブジェクト(テーブル、スキーマetc)。カンマ区切り。未指定の場合は全部が対象。
ワイルドカード利用可。
SETやFLUSHなどオブジェクトを対象としないコマンドを記録する場合は「{}」を含める必要がある。
mysql.*,{}
audit_uninstall_plugin 監査ログプラグインをUNINSTALL PLUGINコマンドで無効にできなくするかどうか? 1 or 0
audit_validate_checksum mysqldのチェックサムを検査するかどうか。
オフィシャルのMySQLバイナリかどうかをチェックしている。
1 or 0
audit_checksum mysqldのチェックサム
audit_delay_cmds 意図的に処理を遅らせる(スリープさせる)対象にするコマンド。何のために利用するのかよくわからない。。 select,insert
audit_delay_ms 遅延させる時間 数字

あわせて読みたい

実践ハイパフォーマンスMySQL 第2版 MySQL徹底入門 第3版 ~5.5新機能対応~ MySQL Cluster構築・運用バイブル ~仕組みからわかる基礎と実践のノウハウ