MySQLデータベースのログインを監査する


11

MySQLへのログインを監査する方法はありますか?各従業員のユーザー名を作成して、ログインの監査証跡を作成できるようにしたいと考えています。しかし、ググリングは良い結果をもたらしていません。

監査できる数が多いほど良いです。少なくとも、いつ誰がログインしたかを知っておくとよいでしょう。だれがどのクエリをいつ実行したかを確認したほうがよいでしょう。データベースには機密情報が含まれている可能性があるため、ログは主にクライアントにログを提供するためのものです。

明らかに、各ユーザーが(いつ)実行したクエリを監査できることで、セキュリティ問題が発生した場合に、その原因を正確に特定できるようになります。


1
正確に何を監査しようとしていますか?システムのユーザー名ではなく、MySQLのユーザー名を使用すると思いますか?監査データを後でどのように使用する予定ですか(ここで重要なのは、MySQLロギングではなくシステムロギングで十分であることを意味します)。質問で提供できる情報が多ければ多いほど、回答を正確に提供でき、迅速に起動できます。「他の操作の前にアプリで特定のsproc呼び出しを行う」よりも良い答えが欲しいと思いますか?要するに、私がこれを尋ねた場合、どの詳細が必要ですか?
jcolebrand

回答:


6

一般的なクエリログを使用することをお勧めします

一般クエリログは、mysqldが実行していることの一般的な記録です。サーバーは、クライアントが接続または切断するときにこのログに情報を書き込み、クライアントから受信した各SQLステートメントをログに記録します。

セキュリティのためにログを記録する際の重要な点の1つは、攻撃者がログにアクセスして存在の痕跡を消去できないことです。そのため、追加専用ファイルを検討してください。

OracleのFWIWでは、リモートのsyslogにログを自動的に送信できますが、MySQLにはまだこの機能がないと思います。たぶん、あなたはSNMPでそれを偽ることができましたが、私はそれを試していません。



かっこいい、毎日何か新しいことを学ぶ:-)
Gaius

5

@Gauisの回答は素晴らしいです。さらに追加するには、次のことができます。

MySQL 5.1では、一般ログとスロークエリログをSQLテーブルとして保存できるようになりました。

これを/etc/my.cnfに追加します。

[mysqld]
log-output=TABLE
log

mysqlを再起動します

次に、mysqldがテキストファイルの代わりに一般的なログを作成すると、/ var / lib / mysql / mysqlフォルダー(mysqlスキーマデータベース)にCSVテーブルとしてテーブルが作成されます。

これを表示するには、次のようにします。

SHOW CREATE TABLE mysql.general_log\G

すべての接続がそれに積み上げられます。

あなたにとって、それはそれを照会することになるとあまり役に立ちません。毎回全テーブルスキャンになります。

何をすべきか ???MyISAMに変換してテーブルのインデックスを作成してください!!!!

SET @old_log_state = @@global.general_log;
SET GLOBAL general_log = 'OFF';
ALTER TABLE mysql.general_log ENGINE = MyISAM;
ALTER TABLE mysql.general_log ADD INDEX (event_time);
SET GLOBAL general_log = @old_log_state;

オプションで、引数フィールドにフルテキストインデックスを配置することもできます。

サーバーにMySQL 5.5.9をセットアップし、これを試してみました。結果は次のとおりです。

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.9-log MySQL Community Server (GPL)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

iml-db10:3306 (DB (none)) :: show create table mysql.general_log\G
*************************** 1. row ***************************
       Table: general_log
Create Table: CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` int(11) NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
1 row in set (0.01 sec)

iml-db10:3306 (DB (none)) :: SET @old_log_state = @@global.general_log;
Query OK, 0 rows affected (0.00 sec)

iml-db10:3306 (DB (none)) :: SET GLOBAL general_log = 'OFF';
Query OK, 0 rows affected (0.00 sec)

iml-db10:3306 (DB (none)) :: ALTER TABLE mysql.general_log ENGINE = MyISAM;
Query OK, 9 rows affected (0.02 sec)
Records: 9  Duplicates: 0  Warnings: 0

iml-db10:3306 (DB (none)) :: ALTER TABLE mysql.general_log ADD INDEX (event_time);
Query OK, 9 rows affected (0.00 sec)
Records: 9  Duplicates: 0  Warnings: 0

iml-db10:3306 (DB (none)) :: SET GLOBAL slow_query_log = @old_log_state;
Query OK, 0 rows affected (0.00 sec)

iml-db10:3306 (DB (none)) :: select * from mysql.general_log;
+---------------------+-----------------------------+-----------+-----------+--------------+-------------------------------------------+
| event_time          | user_host                   | thread_id | server_id | command_type | argument                                  |
+---------------------+-----------------------------+-----------+-----------+--------------+-------------------------------------------+
| 2011-02-24 14:42:18 | [lwdba] @  [127.0.0.1]      |         3 | 106451130 | Connect      | lwdba@127.0.0.1 on                        |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         3 | 106451130 | Query        | select @@version_comment limit 1          |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         3 | 106451130 | Query        | SHOW VARIABLES LIKE 'hostname'            |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         3 | 106451130 | Quit         |                                           |
| 2011-02-24 14:42:18 | [lwdba] @  [127.0.0.1]      |         4 | 106451130 | Connect      | lwdba@127.0.0.1 on                        |
| 2011-02-24 14:42:18 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | select @@version_comment limit 1          |
| 2011-02-24 14:42:30 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | show create table mysql.general_log       |
| 2011-02-24 14:43:54 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | SET @old_log_state = @@global.general_log |
| 2011-02-24 14:44:00 | lwdba[lwdba] @  [127.0.0.1] |         4 | 106451130 | Query        | SET GLOBAL general_log = 'OFF'            |
+---------------------+-----------------------------+-----------+-----------+--------------+-------------------------------------------+
9 rows in set (0.00 sec)

iml-db10:3306 (DB (none)) :: show create table mysql.general_log\G
*************************** 1. row ***************************
       Table: general_log
Create Table: CREATE TABLE `general_log` (
  `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `user_host` mediumtext NOT NULL,
  `thread_id` int(11) NOT NULL,
  `server_id` int(10) unsigned NOT NULL,
  `command_type` varchar(64) NOT NULL,
  `argument` mediumtext NOT NULL,
  KEY `event_time` (`event_time`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='General log'
1 row in set (0.00 sec)

これで、タイムスタンプでクエリを実行し、引数フィールドで特定のトークンを探すことができます。

たとえば、私が選択したSELECTの4行目に注目してください。ログインは、引数フィールドにとして記録されましたlwdba@127.0.0.1 on。これらを追跡できます。

将軍が大きくなりすぎるとどうなりますか?

何をすべきか ???

  1. mysqlのシャットダウン
  2. general_log.frm、general_log.MYD、およびgeneral_log.MYIを別の(そして希望どおりに大きな)ディスクマウントに移動します。
  3. / var / lib / mysql / mysqlからgeneral_log.frm、general_log.MYD、およびgeneral_log.MYIへの3つのシンボリックリンクを作成します。
  4. 新しいディスクマウント上のchown mysql:mysql general_log.frm general_log.MYD general_log.MYI
  5. / var / lib / mysql / mysqlのchown mysql:mysql general_log.frm general_log.MYD general_log.MYIシンボリックリンク
  6. mysqlのバックアップを開始する

ところで、一般的なログをオフラインにしたら、これらを実行して、mysqldで何かを行った個別のログインを収集できます。

SET SQL_LOG_BIN=0;
use mysql
DROP TABLE IF EXISTS audit_user_host;
CREATE TABLE audit_user_host
(
    user_host VARCHAR(32),
    PRIMARY KEY (user_host)
) ENGINE=MyISAM;
SHOW CREATE TABLE audit_user_host\G
INSERT IGNORE INTO mysql.audit_user_host SELECT user_host FROM mysql.general_log;
SELECT COUNT(1) FROM mysql.audit_user_host;

3つのDBサーバーを持つクライアントがあります。Each with DB Serverには、1,000,000,000(10億[千億])を超える行があります。上記のスクリプトの完了には、約2.5時間かかりました。audit_user_hostテーブルは、27の異なるログインで終わりました。

あなたは行ってもいいはずです。

みんな、これを楽しんでね!!!


素晴らしい記事!テストを共有するだけです。テーブルの名前をmysql.general_logに変更し、パージのためにテーブルをパーティション分割しようとしましたが、テーブルにログインしません。そこで、パーティション化されていないMyIsamテーブルに戻します。ありがとう!

1

多くのことを手動で行う代わりに、ユーザーレベルでより多くの洞察を提供する監査プラグインをインストールするだけです

http://www.mysql.com/products/enterprise/audit.html

一部の商用MySQLエディションでも利用できますが、MySQLフォークがコミュニティエディションにも追加されていれば、ほとんどの人がこの機能のメリットを享受できればすばらしいでしょう。


0

@statichippo
MySQLに監査ログをインストールする方法。
+監査ログはMySQL Enterpriseのみをサポートします
+監査ログはMySQLコミュニティに
インストールできます。1.ファイルaudit_log.soをコピーします。
2. audit_log.soをplugin_dirに/ usr / lib64 / mysql / pluginとしてコピーするか、次のようにしてプラグインdirを表示できます。mysql
コンソールに移動します。
3.次のように監査ログをインストールします
。mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
mysql> SHOW VARIABLES LIKE 'audit_log%';
4.出力監査ログ:
tail -f /var/lib/mysql/audit.log

どうもありがとう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.