MySQL 데이터베이스의 로그인 감사


11

MySQL 로그인을 감사 할 수있는 방법이 있습니까? 각 직원의 사용자 이름을 만들어서 로그인 감사 추적을 만들고 싶습니다. 그러나 인터넷 검색은 좋은 결과를 얻지 못했습니다.

감사할수록 많을수록 좋습니다. 최소한 누가 언제 로그인했는지 아는 것이 좋을 것입니다. 누가 언제 어떤 쿼리를 실행했는지 확인하는 것이 좋습니다. 데이터베이스에 민감한 정보가있을 수 있기 때문에 로그는 주로 클라이언트에게 알려줍니다.

분명히 각 사용자가 실행 한 쿼리를 감사 할 수있게되면 보안 문제의 원인이 누구인지 정확하게 파악할 수 있습니다.


1
정확히 무엇을 감사하고 싶습니까? 시스템 사용자 이름이 아닌 MySQL 사용자 이름을 사용한다는 의미입니까? 나중에 감사 데이터를 어떻게 사용할 계획입니까 (여기서 중요한 세부 정보를 의미하는 경우 MySQL 로깅 대신 시스템 로깅으로 충분 함). 질문에 제공 할 수있는 정보가 많을수록 더 정확하게 답변을 제공하고 신속하게 부팅 할 수 있습니다. "응용 프로그램이 서로 작업하기 전에 특정 sproc 호출을하도록하는 것"보다 더 나은 답변을 원한다고 생각합니다.
jcolebrand

답변:


6

아마 일반 쿼리 로그 를 사용하고 싶을 것입니다 .

일반적인 쿼리 로그는 mysqld가하는 일에 대한 일반적인 기록입니다. 서버는 클라이언트가 연결하거나 연결을 끊을 때이 로그에 정보를 기록하고 클라이언트로부터받은 각 SQL 문을 기록합니다.

보안 로깅의 한 가지 중요한 점은 공격자가 로그에 액세스하여 자신의 존재 흔적을 지우지 못하므로 추가 전용 파일을 고려 하는 것 입니다.

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 I의 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에 대한 세 개의 심볼릭 링크를 작성하십시오.
  4. chown mysql : mysql general_log.frm general_log.MYD general_log.MYI 새 디스크 마운트
  5. chown mysql : / sql / mysql / mysql의 mysql general_log.frm general_log.MYD general_log.MYI 심볼릭 링크
  6. MySQL을 백업 시작

BTW 일단 일반 로그가 오프라인 상태가되면이를 실행하여 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;

DB 서버가 3 개인 클라이언트가 있습니다. DB 서버를 사용하는 각 서버에는 1,000,000,000 (10 억 [1,000 만]) 이상의 회선이 있습니다. 위 스크립트는 완료하는 데 약 2.5 시간이 걸렸습니다. audit_user_host 테이블은 27 개의 개별 로그인으로 끝났습니다.

잘 가야합니다.

여러분, 이것 하나로 재미있게 보내십시오!


좋은 기사! 내 테스트를 공유하기 만하면됩니다. mysql.general_log 테이블의 이름을 바꾸고 제거 목적으로 테이블을 분할했지만 테이블에 로그인하지는 않습니다. 그래서 파티션되지 않은 MyIsam 테이블로 다시 전환합니다. 감사!

1

수동으로 많은 작업을 수행하는 대신 사용자 수준에서 더 많은 통찰력을 제공하는 감사 플러그인을 설치하십시오.

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

일부 상용 MySQL 에디션에서 사용할 수 있지만, MySQL 포크가 커뮤니티 에디션에 추가되어 대부분의 사람들 이이 기능을 활용할 수 있다면 좋을 것입니다. 그렇지 않으면 @RolandoMySQLDBA가 제공하는 솔루션에 의존해야합니다.


0

@statichippo
MySQL에 감사 로깅을 설치하는 방법.
+ 감사 로깅은 MySQL Enterprise 만 지원합니다.
+ MySQL 커뮤니티에 감사 로깅을 설치할 수 있습니다.
1. audit_log.so 파일을 복사하여 MySQL Enterprise Trial을 설치 한 다음 audit_log.so 파일을 MySQL 커뮤니티에 복사 할 수 있습니다.
audit_log.so를 plugin_dir에 / usr / lib64 / mysql / plugin으로 복사하거나 다음과 같이 플러그인 디렉토리를 표시 할 수 있습니다.
mysql 콘솔로 이동하십시오. mysql> '% plugin %'과 같은 전역 변수 표시;
3. 다음과 같이 감사 로깅을 설치하십시오.
mysql> INSTALL PLUGIN audit_log SONAME 'audit_log.so';
mysql> 'audit_log %'와 같은 변수 표시;
4. 출력 감사 로깅 :
tail -f /var/lib/mysql/audit.log

많은 감사합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.