在MYSQL中,每个连接都会先执行init-connect,进行连接的初始化。我们可以在这里获取用户的登录名称和thread的ID值。然后配合binlog,就可以追踪到每个操作语句的操作时间,操作人等。实现审计。
实验过程:
1:创建登录日志库,登录日志表
1:创建登录日志库,登录日志表
1
2
3
4
5
6
7
8
9
10
11
|
CREATE
DATABASE
`accesslog`;
USE `accesslog`;
CREATE
TABLE
`accesslog`
(
`id`
int
(11)
NOT
NULL
AUTO_INCREMENT,
`thread_id`
int
(11)
DEFAULT
NULL
, #线程ID,这个值很重要
`log_time`
timestamp
NOT
NULL
DEF AULT
CURRENT_TIMESTAMP
ON
UPDATE
CURRENT_TIMESTAMP
, #登录时间
`localname`
varchar
(30)
DEFAULT
NULL
, #登录名称
`matchname`
varchar
(30)
DEFAULT
NULL
, #登录用户
PRIMARY
KEY
(`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1
DEFAULT
CHARSET=utf8;
|
2:在配置文件中配置init-connect参数。登录时插入日志表。如果这个参数是个错误的SQL语句,登录就会失败。
1
|
init-
connect
=
'insert into accesslog.accesslog values(null,connection_id(),now(),user(),current_user());'
|
3:创建普通用户,不能有super权限。init-connect对具有super权限的用户不起作用。同时此用户必须要有INSERT权限,如果没有,登录后的任何操作都会导致MYSQL登录失败。
1
2
|
grant
insert
,
select
,
update
on
*.*
to
'user1'
@
'localhost'
; #带
INSERT
权限
grant
select
,
update
on
*.*
to
'user2'
@
'localhost'
; #不带
INSERT
权限
|
4:SESSION1登录,并查看日志
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
D:\mysql6\bin>mysql -uuser1 -p
Enter
password
:
Welcome
to
the MySQL monitor. Commands
end
with
;
or
\g.
Your MySQL
connection
id
is
65
Server version: 5.1.45-community-log MySQL Community Server (GPL)
Type
'help;'
or
'\h'
for
help. Type
'\c'
to
clear the
current
input statement.
mysql>
select
*
FROM
accesslog.accesslog;
+
----+-----------+---------------------+-----------------+-----------------+
| id | thread_id | log_time | localname | matchname |
+
----+-----------+---------------------+-----------------+-----------------+
| 1 | 65 | 2011-03-11 19:18:25 | user1@localhost | user1@localhost |
+
----+-----------+---------------------+-----------------+-----------------+
1 row
in
set
(0.00 sec)
mysql> show processlist;
+
----+-------+----------------+------+---------+------+-------+------------------+
| Id |
User
| Host | db | Command |
Time
| State | Info |
+
----+-------+----------------+------+---------+------+-------+------------------+
| 65 | user1 | localhost:1339 |
NULL
| Query | 0 |
NULL
| show processlist |
+
----+-------+----------------+------+---------+------+-------+------------------+
1 row
in
set
(0.00 sec)
mysql>
|
5:再用user2登录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
D:\mysql6\bin>mysql -uuser2 -p
Enter
password
:
Welcome
to
the MySQL monitor. Commands
end
with
;
or
\g.
Your MySQL
connection
id
is
76
Server version: 5.1.45-community-log
Type
'help;'
or
'\h'
for
help. Type
'\c'
to
clear the
current
input statement.
mysql>
select
*
FROM
accesslog.accesslog;
ERROR 2006 (HY000): MySQL server has gone away
No
connection
. Trying
to
reconnect...
Connection
id: 77
Current
database
: *** NONE ***
ERROR 2013 (HY000): Lost
connection
to
MySQL server during query
mysql>
select
*
FROM
accesslog.accesslog;
ERROR 2006 (HY000): MySQL server has gone away
No
connection
. Trying
to
reconnect...
Connection
id: 78
Current
database
: *** NONE ***
|
看下错误日志
1
2
3
4
|
110311 19:23:47 [Warning] Aborted
connection
77
to
db:
'unconnected'
user
:
'user2'
host:
'localhost'
(init_connect command failed)
110311 19:23:47 [Warning]
INSERT
command denied
to
user
'user2'
@
'localhost'
for
table
'accesslog'
110311 19:23:53 [Warning] Aborted
connection
78
to
db:
'unconnected'
user
:
'user2'
host:
'localhost'
(init_connect command failed)
110311 19:23:53 [Warning]
INSERT
command denied
to
user
'user2'
@
'localhost'
for
table
'accesslog'
|
6:下面以USER1登录,并做一个INSERT操作,查看日志文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
mysql>
insert
into
t3
values
(10,10,
'2011-10-10 00:00:00'
);
Query OK, 1 row affected (0.00 sec)
mysql> show processlist;
+
----+-------+----------------+-----------+---------+------+-------+------------------+
| Id |
User
| Host | db | Command |
Time
| State | Info |
+
----+-------+----------------+-----------+---------+------+-------+------------------+
| 69 | user1 | localhost:1439 | accesslog | Query | 0 |
NULL
| show processlist |
+
----+-------+----------------+-----------+---------+------+-------+------------------+
1 row
in
set
(0.00 sec)
mysql>
select
*
from
accesslog.accesslog;
+
----+-----------+---------------------+-----------------+-----------------+
| id | thread_id | log_time | localname | matchname |
+
----+-----------+---------------------+-----------------+-----------------+
| 1 | 65 | 2011-03-11 19:18:25 | user1@localhost | user1@localhost |
| 2 | 91 | 2011-03-11 19:28:33 | user1@localhost | user1@localhost |
| 3 | 2 | 2011-03-11 19:31:49 | user1@localhost | user1@localhost |
| 4 | 2 | 2000-10-10 10:10:10 | user1@localhost | user1@localhost |
| 5 | 21 | 2000-10-10 11:11:11 | root@localhost | root@% |
| 6 | 69 | 2011-03-12 21:35:43 | user1@localhost | user1@localhost |
+
----+-----------+---------------------+-----------------+-----------------+
6
rows
in
set
(0.01 sec)
|
查看日志文件的内容
1
2
3
4
5
6
7
|
#
at
340
#110312 21:36:01 server id 1 end_log_pos 453 Query thread_id=69 exec_time=0 error_code=0
use text
/*!*/
;
SET
TIMESTAMP
=1299936961
/*!*/
;
insert
into
t3
values
(10,10,
'2011-10-10 00:00:00'
)
/*!*/
;
#
at
453
|
thread_id=69
在日志表里记录的和日志文件里面记录的相同。可以通过这个thread_id来追踪到是谁,什么时间,做了什么操作。