このセクションでは、audit_log
プラグインでロギングを実行する方法、およびロギングの発生方法を制御するシステム変数について説明します。セクション6.3.12.3「監査ログファイル」で説明したログファイル形式に精通していることが前提となっています。
監査ログプラグインはそのログファイルを開くと、XML
宣言および開始ルート要素タグ
<AUDIT>
を書き込む必要があるかどうかをチェックし、その場合はそれらのタグを書き込みます。監査ログプラグインが終了すると、終了タグ
</AUDIT>
をファイルに書き込みます。
ログファイルを開くときに存在すれば、プラグインはファイルが
</AUDIT>
タグで終了しているかどうかをチェックし、その場合はそれを切り捨ててから、任意の
<AUDIT_RECORD>
要素を書き込みます。ログファイルが存在するが、</AUDIT>
タグで終了していない場合や、</AUDIT>
タグを切り捨てることができない場合、プラグインではファイル形式が不正であり、初期化に失敗したとみなされます。これは、サーバーがクラッシュした場合や、監査ログプラグインの実行中に強制終了された場合に発生する可能性があります。ロギングは、問題が修正されるまで発生しません。エラーログをチェックして、診断情報を確認してください。
[ERROR] Plugin 'audit_log' init function returned error.
この問題に対処するには、不正な形式のログファイルを削除するか、ファイル名を変更してから、サーバーを再起動する必要があります。
MySQL サーバーは、クライアントから受信された
SQL
ステートメントの実行が完了するときなど、監査可能なイベントが発生するたびに監査ログプラグインを呼び出して、<AUDIT_RECORD>
要素を書き込みます。一般に、サーバーの起動後に最初に書き込まれた
<AUDIT_RECORD>
要素には、サーバーの説明および起動オプションが含まれています。そのあとの要素は、クライアントの接続および切断イベント、SQL
ステートメントの実行などのイベントを表します。最上位のステートメントのみのログが記録され、トリガーやストアドプロシージャーなどのストアドプログラム内のステートメントのログは記録されません。LOAD
DATA INFILE
などのステートメントから参照されるファイルの内容は、記録されません。
ロギングの発生方法に対する制御を許可するために、audit_log
プラグインには、次に説明するような複数のシステム変数が用意されています。詳細については、セクション6.3.12.6「監査ログプラグインのオプションおよびシステム変数」を参照してください。
監査ログファイル名の指定
監査ログファイル名を制御するには、サーバーの起動時に
audit_log_file
システム変数を設定します。デフォルトでは、サーバーのデータディレクトリ内の
audit.log
という名前です。セキュリティー上の理由から、監査ログファイルは、MySQL
サーバーおよびログを表示する正当な理由を持つユーザーにのみアクセス可能なディレクトリに書き込まれるべきです。
監査ロギングの戦略
監査プラグインは、ログの書き込みに関する複数の戦略のいずれかを使用できます。戦略を指定するには、サーバーの起動時に
audit_log_strategy
システム変数を設定します。デフォルトでは、戦略の値は
ASYNCHRONOUS
であり、プラグインは非同期的にログをバッファーに記録し、バッファーがいっぱいの場合は待機します。ファイルシステムのキャッシュ処理を使用するか
(SEMISYNCHRONOUS
)、各書き込みリクエストのあとに
sync()
を呼び出して出力を強制すれば
(SYNCHRONOUS
)、待機しないように
(PERFORMANCE
)、または同期的にログを記録するようにプラグインに指示できます。
非同期ロギングの戦略には、次のような特性があります。
サーバーのパフォーマンスと拡張性への影響が最小限です。
できるかぎり最短の時間 (つまり、バッファーを割り当てる時間とそのバッファーにイベントをコピーする時間を足した時間) で、監査イベントを生成するスレッドをブロックします。
出力はバッファーに書き込まれます。個別のスレッドがバッファーからログファイルへの書き込みに対処します。
PERFORMANCE
戦略のデメリットは、バッファーがいっぱいの場合にイベントが破棄される点です。負荷の高いサーバーでは、監査ログでイベントが欠落する可能性が高くなります。
非同期ロギングを使用すると、ファイルへの書き込み中に問題が発生した場合や、プラグインが正常にシャットダウンされない場合
(たとえば、サーバーホストがクラッシュした場合)
に、ログファイルの完全性が危険にさらされる可能性があります。このリスクを減らすには、同期ロギングが使用されるように
audit_log_strategy
を設定します。戦略に関係なく、ロギングはベストエフォートベーシスで発生するため、一貫性は保証されません。
監査ログ領域の管理
監査ログプラグインには、そのログファイルで使用される領域を管理できる複数のシステム変数が用意されています。
audit_log_buffer_size
: 非同期ロギング用のバッファーサイズを設定するには、この変数をサーバーの起動時に設定します。このプラグインでは、初期化時に割り当てられ、終了時に削除される単一のバッファーが使用されます。このプラグインは、ロギングが非同期の場合にのみ、このバッファーを割り当てます。-
audit_log_rotate_on_size
、audit_log_flush
: これらの変数を使用すると、監査ログファイルのローテーションおよびフラッシュが許可されます。監査ログファイルが非常に大きくなり、大量のディスク領域が消費される可能性があります。使用される領域を管理するには、自動的なログのローテーションを有効にするか、手動で監査ファイルの名前を変更し、ログをフラッシュして新しいファイルを開きます。必要に応じて、名前が変更されたファイルを削除したり、バックアップしたりできます。デフォルトでは、
audit_log_rotate_on_size=0
であり、ログのローテーションは発生しません。この場合、audit_log_flush
の値が無効から有効に変更されると、監査ログプラグインはログファイルを閉じてから再度開きます。ログファイル名の変更は、サーバーの外部で実行される必要があります。名前をaudit.log.1
からaudit.log.3
で循環させる 3 つの最近のログファイルを保持すると仮定します。Unix 上で、次のように手動でローテーションを実行します。-
コマンド行から、現在のログファイル名を変更します。
shell> mv audit.log.2 audit.log.3 shell> mv audit.log.1 audit.log.2 shell> mv audit.log audit.log.1
この時点で、プラグインは引き続き、
audit.log.1
に名前が変更された現在のログファイルに書き込みます。 -
サーバーに接続し、ログファイルをフラッシュします。これにより、プラグインはログファイルを閉じて、新しい
audit.log
ファイルログを再度開きます。mysql> SET GLOBAL audit_log_flush = ON;
audit_log_rotate_on_size
が 0 よりも大きい場合は、audit_log_flush
を設定しても効果がありません。この場合、ファイルへの書き込みによってそのサイズがaudit_log_rotate_on_size
の値を超えるたびに、監査ログプラグインはそのログファイルを閉じてから再度開きます。このプラグインは、タイムスタンプ拡張子が追加されるように元のファイル名を変更します。たとえば、audit.log
はaudit.log.13440033615657730
という名前に変更される可能性があります。最後の 7 桁は小数部です。最初の 10 桁は、FROM_UNIXTIME()
関数を使用して解釈できる Unix タイムスタンプ値です。mysql> SELECT FROM_UNIXTIME(1344003361); +---------------------------+ | FROM_UNIXTIME(1344003361) | +---------------------------+ | 2012-08-03 09:16:01 | +---------------------------+
-
監査ログのフィルタリング
監査ログプラグインは、監査対象イベントをフィルタリングできます。これにより、イベントの発生元のアカウントやイベントのステータスに基づいて、監査ログファイルにイベントを書き込むかどうかを制御できます。ステータスのフィルタリングは、接続イベントおよびステートメントイベントごとに個別に発生します。
アカウント別のイベントフィルタリング
MySQL 5.6.20 の時点で、発生元のアカウントに基づいて監査対象イベントをフィルタリングするには、サーバーの起動時または実行時に、次のシステム変数のいずれかを設定します。
audit_log_include_accounts
: 監査ロギングに含めるアカウント。この変数が設定されている場合は、これらのアカウントのみが監査されます。audit_log_exclude_accounts
: 監査ロギングから除外するアカウント。この変数が設定されている場合は、これらのアカウント以外がすべて監査されます。
いずれかの変数の値には、NULL
またはカンマで区切った 1
つ以上のアカウント名を含む文字列を指定できます。それぞれの形式は
です。デフォルトでは、両方の変数が
user_name
@host_name
NULL
になっています。この場合、アカウントのフィルタリングは実行されず、すべてのアカウントで監査が発生します。
例: user1
および user2
ローカルホストのアカウントでのみ監査ロギングを有効にするには、次のように
audit_log_include_accounts
システム変数を設定します。
SET GLOBAL audit_log_include_accounts = 'user1@localhost,user2@localhost';
同時に NULL
以外に設定できるのは、audit_log_include_accounts
と audit_log_exclude_accounts
のいずれかのみです。
audit_log_include_accounts
を設定すると、サーバーはaudit_log_exclude_accounts
をNULL
に設定します。audit_log_include_accounts
がNULL
でない場合を除いて、audit_log_exclude_accounts
を設定しようとするとエラーが発生します。この場合は、まずaudit_log_include_accounts
をNULL
に設定することでクリアする必要があります。
-- This sets audit_log_exclude_accounts to NULL
SET GLOBAL audit_log_include_accounts = value;
-- This fails because audit_log_include_accounts is not NULL
SET GLOBAL audit_log_exclude_accounts = value;
-- To set audit_log_exclude_accounts, first set
-- audit_log_include_accounts to NULL
SET GLOBAL audit_log_include_accounts = NULL;
SET GLOBAL audit_log_exclude_accounts = value;
いずれかの変数の値を調査する場合は、SHOW
VARIABLES
で NULL
が空の文字列として表示されることに注意してください。これを回避するには、代わりに
SELECT
を使用してください。
mysql> SHOW VARIABLES LIKE 'audit_log_include_accounts';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| audit_log_include_accounts | |
+----------------------------+-------+
mysql> SELECT @@audit_log_include_accounts;
+------------------------------+
| @@audit_log_include_accounts |
+------------------------------+
| NULL |
+------------------------------+
カンマ、スペース、またはその他の特殊文字が含まれているために、ユーザー名やホスト名を引用符で囲む必要がある場合は、一重引用符を使用して囲みます。変数の値自体が一重引用符で囲まれている場合は、内側の各一重引用符を二重に入力するか、バックスラッシュを使用してエスケープします。次のステートメントはそれぞれ、ローカルの
root
アカウントの監査ロギングを有効にします。引用符のスタイルが異なりますが、いずれも同等です。
SET GLOBAL audit_log_include_accounts = 'root@localhost';
SET GLOBAL audit_log_include_accounts = '''root''@''localhost''';
SET GLOBAL audit_log_include_accounts = '\'root\'@\'localhost\'';
SET GLOBAL audit_log_include_accounts = "'root'@'localhost'";
ANSI_QUOTES
SQL
モードでは、二重引用符は文字列の引用ではなく、識別子の引用を示すため、このモードが有効になっている場合は、最後のステートメントが機能しません。
ステータス別のイベントフィルタリング
MySQL 5.6.20 の時点で、ステータスに基づいて監査対象イベントをフィルタリングするには、サーバーの起動時または実行時に、次のシステム変数を設定します。
audit_log_connection_policy
: 接続イベントのロギングポリシーですaudit_log_statement_policy
: ステートメントイベントのロギングポリシーです
各変数には、ALL
(関連付けられたすべてのイベントのログを記録します。これがデフォルトです)、ERRORS
(失敗したイベントのログのみを記録します)、または
NONE
(イベントのログを記録しません)
の値が指定されます。たとえば、ステートメントイベントのログはすべて記録するが、接続イベントのログは失敗したもののみを記録する場合は、次の設定を使用します。
SET GLOBAL audit_log_statement_policy = ALL;
SET GLOBAL audit_log_connection_policy = ERRORS;
MySQL 5.6.20
よりも前では、audit_log_connection_policy
および
audit_log_statement_policy
を使用できません。代わりに、サーバーの起動時または実行時に
audit_log_policy
を使用します。これには、ALL
(すべてのイベントのログを記録します。これがデフォルトです)、LOGINS
(接続イベントのログを記録します)、QUERIES
(ステートメントイベントのログを記録します)、または
NONE
(イベントのログを記録しません)
の値が指定されます。これらの値のいずれを指定しても、監査ログプラグインは成功と失敗を区別せずに、選択したイベントのログをすべて記録します。
MySQL 5.6.20
の時点で、audit_log_policy
は引き続き使用可能ですが、サーバーの起動時にしか設定できません。実行時は、読み取り専用の変数です。起動時に使用すると、次のように動作します。
audit_log_policy
を設定しない場合や、デフォルト値のALL
に設定した場合でも、audit_log_connection_policy
またはaudit_log_statement_policy
を明示的に設定すれば、指定どおりに適用されます。指定しない場合は、デフォルトがALL
に設定されます。-
audit_log_policy
をALL
以外の値に設定した場合は、次の表に示すように、その値が優先され、audit_log_connection_policy
およびaudit_log_statement_policy
を設定する際に使用されます。また、これらの変数のいずれかをデフォルトのALL
以外の値に設定する場合、サーバーはそれらの値がオーバーライドされることを示すメッセージをエラーログに書き込みます。起動時の audit_log_policy 値 結果として返される audit_log_connection_policy 値 結果として返される audit_log_statement_policy 値 LOGINS
ALL
NONE
QUERIES
NONE
ALL
NONE
NONE
NONE
イベントフィルタリングのレポート
次のステータス変数の値を調査すると、フィルタリングの結果を確認できます。
Audit_log_events
: フィルタリングのポリシーに基づいてログに書き込まれたかどうかに関係なく、監査ログプラグインによって処理されたイベントの数。Audit_log_events_filtered
: フィルタリングのポリシーに基づいて、監査ログプラグインによってフィルタリングされた (ログに書き込まれなかった) イベントの数。Audit_log_events_written
: 監査ログに書き込まれたイベントの数。
MySQL 5.6.20 の時点では、これらの変数を使用できます。