Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
8e194153
Unverified
Commit
8e194153
authored
Oct 07, 2022
by
aradz44
Committed by
GitHub
Oct 07, 2022
Browse files
Added authentication failure and access denied metrics (#11288)
Added authentication failure and access denied metrics
parent
210ad2e4
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/acl.c
View file @
8e194153
...
@@ -2479,6 +2479,21 @@ void ACLFreeLogEntry(void *leptr) {
...
@@ -2479,6 +2479,21 @@ void ACLFreeLogEntry(void *leptr) {
zfree
(
le
);
zfree
(
le
);
}
}
/* Update the relevant counter by the reason */
void
ACLUpdateInfoMetrics
(
int
reason
){
if
(
reason
==
ACL_DENIED_AUTH
)
{
server
.
acl_info
.
user_auth_failures
++
;
}
else
if
(
reason
==
ACL_DENIED_CMD
)
{
server
.
acl_info
.
invalid_cmd_accesses
++
;
}
else
if
(
reason
==
ACL_DENIED_KEY
)
{
server
.
acl_info
.
invalid_key_accesses
++
;
}
else
if
(
reason
==
ACL_DENIED_CHANNEL
)
{
server
.
acl_info
.
invalid_channel_accesses
++
;
}
else
{
serverPanic
(
"Unknown ACL_DENIED encoding"
);
}
}
/* Adds a new entry in the ACL log, making sure to delete the old entry
/* Adds a new entry in the ACL log, making sure to delete the old entry
* if we reach the maximum length allowed for the log. This function attempts
* if we reach the maximum length allowed for the log. This function attempts
* to find similar entries in the current log in order to bump the counter of
* to find similar entries in the current log in order to bump the counter of
...
@@ -2495,6 +2510,9 @@ void ACLFreeLogEntry(void *leptr) {
...
@@ -2495,6 +2510,9 @@ void ACLFreeLogEntry(void *leptr) {
* If `object` is not NULL, this functions takes over it.
* If `object` is not NULL, this functions takes over it.
*/
*/
void
addACLLogEntry
(
client
*
c
,
int
reason
,
int
context
,
int
argpos
,
sds
username
,
sds
object
)
{
void
addACLLogEntry
(
client
*
c
,
int
reason
,
int
context
,
int
argpos
,
sds
username
,
sds
object
)
{
/* Update ACL info metrics */
ACLUpdateInfoMetrics
(
reason
);
/* Create a new entry. */
/* Create a new entry. */
struct
ACLLogEntry
*
le
=
zmalloc
(
sizeof
(
*
le
));
struct
ACLLogEntry
*
le
=
zmalloc
(
sizeof
(
*
le
));
le
->
count
=
1
;
le
->
count
=
1
;
...
...
src/server.c
View file @
8e194153
...
@@ -2536,6 +2536,12 @@ void initServer(void) {
...
@@ -2536,6 +2536,12 @@ void initServer(void) {
server
.
repl_good_slaves_count
=
0
;
server
.
repl_good_slaves_count
=
0
;
server
.
last_sig_received
=
0
;
server
.
last_sig_received
=
0
;
/* Initiate acl info struct */
server
.
acl_info
.
invalid_cmd_accesses
=
0
;
server
.
acl_info
.
invalid_key_accesses
=
0
;
server
.
acl_info
.
user_auth_failures
=
0
;
server
.
acl_info
.
invalid_channel_accesses
=
0
;
/* Create the timer callback, this is our way to process many background
/* Create the timer callback, this is our way to process many background
* operations incrementally, like clients timeout, eviction of unaccessed
* operations incrementally, like clients timeout, eviction of unaccessed
* expired keys and so forth. */
* expired keys and so forth. */
...
@@ -5167,6 +5173,20 @@ sds genRedisInfoStringCommandStats(sds info, dict *commands) {
...
@@ -5167,6 +5173,20 @@ sds genRedisInfoStringCommandStats(sds info, dict *commands) {
return
info
;
return
info
;
}
}
/* Writes the ACL metrics to the info */
sds
genRedisInfoStringACLStats
(
sds
info
)
{
info
=
sdscatprintf
(
info
,
"acl_access_denied_auth:%lld
\r\n
"
"acl_access_denied_cmd:%lld
\r\n
"
"acl_access_denied_key:%lld
\r\n
"
"acl_access_denied_channel:%lld
\r\n
"
,
server
.
acl_info
.
user_auth_failures
,
server
.
acl_info
.
invalid_cmd_accesses
,
server
.
acl_info
.
invalid_key_accesses
,
server
.
acl_info
.
invalid_channel_accesses
);
return
info
;
}
sds
genRedisInfoStringLatencyStats
(
sds
info
,
dict
*
commands
)
{
sds
genRedisInfoStringLatencyStats
(
sds
info
,
dict
*
commands
)
{
struct
redisCommand
*
c
;
struct
redisCommand
*
c
;
dictEntry
*
de
;
dictEntry
*
de
;
...
@@ -5778,6 +5798,7 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) {
...
@@ -5778,6 +5798,7 @@ sds genRedisInfoString(dict *section_dict, int all_sections, int everything) {
server
.
stat_io_writes_processed
,
server
.
stat_io_writes_processed
,
server
.
stat_reply_buffer_shrinks
,
server
.
stat_reply_buffer_shrinks
,
server
.
stat_reply_buffer_expands
);
server
.
stat_reply_buffer_expands
);
info
=
genRedisInfoStringACLStats
(
info
);
}
}
/* Replication */
/* Replication */
...
...
src/server.h
View file @
8e194153
...
@@ -1189,6 +1189,14 @@ typedef struct client {
...
@@ -1189,6 +1189,14 @@ typedef struct client {
char
*
buf
;
char
*
buf
;
}
client
;
}
client
;
/* ACL information */
typedef
struct
aclInfo
{
long
long
user_auth_failures
;
/* Auth failure counts on user level */
long
long
invalid_cmd_accesses
;
/* Invalid command accesses that user doesn't have permission to */
long
long
invalid_key_accesses
;
/* Invalid key accesses that user doesn't have permission to */
long
long
invalid_channel_accesses
;
/* Invalid channel accesses that user doesn't have permission to */
}
aclInfo
;
struct
saveparam
{
struct
saveparam
{
time_t
seconds
;
time_t
seconds
;
int
changes
;
int
changes
;
...
@@ -1899,6 +1907,7 @@ struct redisServer {
...
@@ -1899,6 +1907,7 @@ struct redisServer {
the old "requirepass" directive for
the old "requirepass" directive for
backward compatibility with Redis <= 5. */
backward compatibility with Redis <= 5. */
int
acl_pubsub_default
;
/* Default ACL pub/sub channels flag */
int
acl_pubsub_default
;
/* Default ACL pub/sub channels flag */
aclInfo
acl_info
;
/* ACL info */
/* Assert & bug reporting */
/* Assert & bug reporting */
int
watchdog_period
;
/* Software watchdog period in ms. 0 = off */
int
watchdog_period
;
/* Software watchdog period in ms. 0 = off */
/* System hardware info */
/* System hardware info */
...
@@ -2798,6 +2807,7 @@ void ACLFreeUserAndKillClients(user *u);
...
@@ -2798,6 +2807,7 @@ void ACLFreeUserAndKillClients(user *u);
void
addACLLogEntry
(
client
*
c
,
int
reason
,
int
context
,
int
argpos
,
sds
username
,
sds
object
);
void
addACLLogEntry
(
client
*
c
,
int
reason
,
int
context
,
int
argpos
,
sds
username
,
sds
object
);
const
char
*
getAclErrorMessage
(
int
acl_res
);
const
char
*
getAclErrorMessage
(
int
acl_res
);
void
ACLUpdateDefaultUserPassword
(
sds
password
);
void
ACLUpdateDefaultUserPassword
(
sds
password
);
sds
genRedisInfoStringACLStats
(
sds
info
);
/* Sorted sets data type */
/* Sorted sets data type */
...
...
tests/unit/acl.tcl
View file @
8e194153
...
@@ -751,6 +751,71 @@ start_server {tags {"acl external:skip"}} {
...
@@ -751,6 +751,71 @@ start_server {tags {"acl external:skip"}} {
catch
{
r ACL load
}
err
catch
{
r ACL load
}
err
set err
set err
}
{
*Redis instance is not configured to use an ACL file*
}
}
{
*Redis instance is not configured to use an ACL file*
}
# If there is an AUTH failure the metric increases
test
{
ACL-Metrics user AUTH failure
}
{
set current_auth_failures
[
s acl_access_denied_auth
]
set current_invalid_cmd_accesses
[
s acl_access_denied_cmd
]
set current_invalid_key_accesses
[
s acl_access_denied_key
]
set current_invalid_channel_accesses
[
s acl_access_denied_channel
]
assert_error
"*WRONGPASS*"
{
r AUTH notrealuser 1233456
}
assert
{[
s acl_access_denied_auth
]
eq
[
expr $current_auth_failures + 1
]}
assert_error
"*WRONGPASS*"
{
r HELLO 3 AUTH notrealuser 1233456
}
assert
{[
s acl_access_denied_auth
]
eq
[
expr $current_auth_failures + 2
]}
assert_error
"*WRONGPASS*"
{
r HELLO 2 AUTH notrealuser 1233456
}
assert
{[
s acl_access_denied_auth
]
eq
[
expr $current_auth_failures + 3
]}
assert
{[
s acl_access_denied_cmd
]
eq $current_invalid_cmd_accesses
}
assert
{[
s acl_access_denied_key
]
eq $current_invalid_key_accesses
}
assert
{[
s acl_access_denied_channel
]
eq $current_invalid_channel_accesses
}
}
# If a user try to access an unauthorized command the metric increases
test
{
ACL-Metrics invalid command accesses
}
{
set current_auth_failures
[
s acl_access_denied_auth
]
set current_invalid_cmd_accesses
[
s acl_access_denied_cmd
]
set current_invalid_key_accesses
[
s acl_access_denied_key
]
set current_invalid_channel_accesses
[
s acl_access_denied_channel
]
r ACL setuser invalidcmduser on >passwd nocommands
r AUTH invalidcmduser passwd
assert_error
"*no permissions to run the * command*"
{
r acl list
}
r AUTH default
""
assert
{[
s acl_access_denied_auth
]
eq $current_auth_failures
}
assert
{[
s acl_access_denied_cmd
]
eq
[
expr $current_invalid_cmd_accesses + 1
]}
assert
{[
s acl_access_denied_key
]
eq $current_invalid_key_accesses
}
assert
{[
s acl_access_denied_channel
]
eq $current_invalid_channel_accesses
}
}
# If a user try to access an unauthorized key the metric increases
test
{
ACL-Metrics invalid key accesses
}
{
set current_auth_failures
[
s acl_access_denied_auth
]
set current_invalid_cmd_accesses
[
s acl_access_denied_cmd
]
set current_invalid_key_accesses
[
s acl_access_denied_key
]
set current_invalid_channel_accesses
[
s acl_access_denied_channel
]
r ACL setuser invalidkeyuser on >passwd resetkeys allcommands
r AUTH invalidkeyuser passwd
assert_error
"*no permissions to access one of the keys*"
{
r get x
}
r AUTH default
""
assert
{[
s acl_access_denied_auth
]
eq $current_auth_failures
}
assert
{[
s acl_access_denied_cmd
]
eq $current_invalid_cmd_accesses
}
assert
{[
s acl_access_denied_key
]
eq
[
expr $current_invalid_key_accesses + 1
]}
assert
{[
s acl_access_denied_channel
]
eq $current_invalid_channel_accesses
}
}
# If a user try to access an unauthorized channel the metric increases
test
{
ACL-Metrics invalid channels accesses
}
{
set current_auth_failures
[
s acl_access_denied_auth
]
set current_invalid_cmd_accesses
[
s acl_access_denied_cmd
]
set current_invalid_key_accesses
[
s acl_access_denied_key
]
set current_invalid_channel_accesses
[
s acl_access_denied_channel
]
r ACL setuser invalidchanneluser on >passwd resetchannels allcommands
r AUTH invalidkeyuser passwd
assert_error
"*no permissions to access one of the channels*"
{
r subscribe x
}
r AUTH default
""
assert
{[
s acl_access_denied_auth
]
eq $current_auth_failures
}
assert
{[
s acl_access_denied_cmd
]
eq $current_invalid_cmd_accesses
}
assert
{[
s acl_access_denied_key
]
eq $current_invalid_key_accesses
}
assert
{[
s acl_access_denied_channel
]
eq
[
expr $current_invalid_channel_accesses + 1
]}
}
}
}
set server_path
[
tmpdir
"server.acl"
]
set server_path
[
tmpdir
"server.acl"
]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment