Skip to content

Commit 278ed7d

Browse files
PS-9033 postfix: audit_log_filter plugin, does not register remote accesses
https://perconadev.atlassian.net/browse/PS-9033 'audit_log_filter' now properly handles anonymous MySQL accounts (e.g. ''@'127.0.0.1'). Removed unnecessary restriction in 'AuditLogFilter::get_connection_user()' that was checking for user name and host name parts of the user account to be non-empty and could lead to not registering events from such accounts in the audit log file. Added new 'audit_log_filter.filter_definition_filter_by_anonymous_user' MTR test case which checks that connection events coming from anonymous MySQL accounts are not ignored / skipped in the audit log.
1 parent f58c633 commit 278ed7d

File tree

4 files changed

+136
-5
lines changed

4 files changed

+136
-5
lines changed

plugin/audit_log_filter/audit_log_filter.cc

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -617,12 +617,16 @@ bool AuditLogFilter::get_connection_user(Security_context_handle &ctx,
617617
return false;
618618
}
619619

620-
if (user.length == 0 || host.length == 0) {
621-
return false;
620+
if (user.length == 0) {
621+
user_name.clear();
622+
} else {
623+
user_name.assign(user.str, user.length);
624+
}
625+
if (host.length == 0) {
626+
user_host.clear();
627+
} else {
628+
user_host.assign(host.str, host.length);
622629
}
623-
624-
user_name = user.str;
625-
user_host = host.str;
626630

627631
return true;
628632
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
CREATE USER ''@'127.0.0.1';
2+
SET @filter = '{
3+
"filter": {
4+
"class": {
5+
"name": "connection",
6+
"event": {
7+
"name": "connect"
8+
}
9+
}
10+
}
11+
}';
12+
SELECT audit_log_filter_set_filter('log_connect', @filter);
13+
audit_log_filter_set_filter('log_connect', @filter)
14+
OK
15+
###
16+
### 1. Connecting as an anonymous user with no rules set
17+
###
18+
SET @audit_filter_log_name = audit_log_rotate();
19+
USER() CURRENT_USER()
20+
foobarbaz@localhost @127.0.0.1
21+
SET @audit_filter_log_name = audit_log_rotate();
22+
SET @content = CAST(CONVERT(LOAD_FILE(CONCAT(@@global.datadir, @audit_filter_log_name)) USING ascii) AS JSON);
23+
###
24+
### 2. Connecting as an anonymous user with default rule set
25+
###
26+
SELECT audit_log_filter_set_user('%', 'log_connect');
27+
audit_log_filter_set_user('%', 'log_connect')
28+
OK
29+
SET @audit_filter_log_name = audit_log_rotate();
30+
USER() CURRENT_USER()
31+
foobarbaz@localhost @127.0.0.1
32+
SET @audit_filter_log_name = audit_log_rotate();
33+
SET @content = CAST(CONVERT(LOAD_FILE(CONCAT(@@global.datadir, @audit_filter_log_name)) USING ascii) AS JSON);
34+
###
35+
### 3. Connecting as an anonymous user with a dedicated rule for this anonymous user
36+
###
37+
SELECT audit_log_filter_remove_user('%');
38+
audit_log_filter_remove_user('%')
39+
OK
40+
SELECT audit_log_filter_set_user('@127.0.0.1', 'log_connect');
41+
audit_log_filter_set_user('@127.0.0.1', 'log_connect')
42+
OK
43+
SET @audit_filter_log_name = audit_log_rotate();
44+
USER() CURRENT_USER()
45+
foobarbaz@localhost @127.0.0.1
46+
SET @audit_filter_log_name = audit_log_rotate();
47+
SET @content = CAST(CONVERT(LOAD_FILE(CONCAT(@@global.datadir, @audit_filter_log_name)) USING ascii) AS JSON);
48+
SELECT audit_log_filter_remove_user('@127.0.0.1');
49+
audit_log_filter_remove_user('@127.0.0.1')
50+
OK
51+
DROP USER ''@'127.0.0.1';
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--audit_log_filter_format=JSON
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
--source audit_tables_init.inc
2+
3+
--let $anonymous_user_name = foobarbaz
4+
--let $ipv4_localhost = 127.0.0.1
5+
6+
--let $MYSQL_PORT = `SELECT @@port`
7+
8+
eval CREATE USER ''@'$ipv4_localhost';
9+
10+
SET @filter = '{
11+
"filter": {
12+
"class": {
13+
"name": "connection",
14+
"event": {
15+
"name": "connect"
16+
}
17+
}
18+
}
19+
}';
20+
SELECT audit_log_filter_set_filter('log_connect', @filter);
21+
22+
--echo ###
23+
--echo ### 1. Connecting as an anonymous user with no rules set
24+
--echo ###
25+
SET @audit_filter_log_name = audit_log_rotate();
26+
27+
--source include/count_sessions.inc
28+
--exec $MYSQL -u$anonymous_user_name -h$ipv4_localhost -P$MYSQL_PORT -e "SELECT USER(), CURRENT_USER();" test
29+
--source include/wait_until_count_sessions.inc
30+
SET @audit_filter_log_name = audit_log_rotate();
31+
SET @content = CAST(CONVERT(LOAD_FILE(CONCAT(@@global.datadir, @audit_filter_log_name)) USING ascii) AS JSON);
32+
33+
--assert(`SELECT JSON_LENGTH(@content) = 0 AS no_connection_events_must_be_logged`)
34+
35+
36+
--echo ###
37+
--echo ### 2. Connecting as an anonymous user with default rule set
38+
--echo ###
39+
SELECT audit_log_filter_set_user('%', 'log_connect');
40+
SET @audit_filter_log_name = audit_log_rotate();
41+
42+
--source include/count_sessions.inc
43+
--exec $MYSQL -u$anonymous_user_name -h$ipv4_localhost -P$MYSQL_PORT -e "SELECT USER(), CURRENT_USER();" test
44+
--source include/wait_until_count_sessions.inc
45+
SET @audit_filter_log_name = audit_log_rotate();
46+
SET @content = CAST(CONVERT(LOAD_FILE(CONCAT(@@global.datadir, @audit_filter_log_name)) USING ascii) AS JSON);
47+
48+
--assert(`SELECT JSON_LENGTH(@content) = 1 AS one_connection_event_must_be_logged`)
49+
--assert(`SELECT JSON_EXTRACT(@content, '\$[0].login.user') = '$anonymous_user_name' AS event_must_be_from_fake_user_name`)
50+
--assert(`SELECT JSON_EXTRACT(@content, '\$[0].login.ip') = '$ipv4_localhost' AS event_must_be_from_ipv4_localhost`)
51+
52+
53+
--echo ###
54+
--echo ### 3. Connecting as an anonymous user with a dedicated rule for this anonymous user
55+
--echo ###
56+
SELECT audit_log_filter_remove_user('%');
57+
eval SELECT audit_log_filter_set_user('@$ipv4_localhost', 'log_connect');
58+
SET @audit_filter_log_name = audit_log_rotate();
59+
60+
--source include/count_sessions.inc
61+
--exec $MYSQL -u$anonymous_user_name -h$ipv4_localhost -P$MYSQL_PORT -e "SELECT USER(), CURRENT_USER();" test
62+
--source include/wait_until_count_sessions.inc
63+
SET @audit_filter_log_name = audit_log_rotate();
64+
SET @content = CAST(CONVERT(LOAD_FILE(CONCAT(@@global.datadir, @audit_filter_log_name)) USING ascii) AS JSON);
65+
66+
--assert(`SELECT JSON_LENGTH(@content) = 1 AS one_connection_event_must_be_logged`)
67+
--assert(`SELECT JSON_EXTRACT(@content, '\$[0].login.user') = '$anonymous_user_name' AS event_must_be_from_fake_user_name`)
68+
--assert(`SELECT JSON_EXTRACT(@content, '\$[0].login.ip') = '$ipv4_localhost' AS event_must_be_from_ipv4_localhost`)
69+
70+
71+
eval SELECT audit_log_filter_remove_user('@$ipv4_localhost');
72+
73+
eval DROP USER ''@'$ipv4_localhost';
74+
75+
--source audit_tables_cleanup.inc

0 commit comments

Comments
 (0)