ACL LOG: log failed auth attempts.
This commit is contained in:
parent
c60351e489
commit
c0de265bfa
37
src/acl.c
37
src/acl.c
@ -982,6 +982,7 @@ int ACLAuthenticateUser(client *c, robj *username, robj *password) {
|
|||||||
moduleNotifyUserChanged(c);
|
moduleNotifyUserChanged(c);
|
||||||
return C_OK;
|
return C_OK;
|
||||||
} else {
|
} else {
|
||||||
|
addACLLogEntry(c,ACL_DENIED_AUTH,0,username->ptr);
|
||||||
return C_ERR;
|
return C_ERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1506,17 +1507,29 @@ void ACLFreeLogEntry(void *leptr) {
|
|||||||
* 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
|
||||||
* the log entry instead of creating many entries for very similar ACL
|
* the log entry instead of creating many entries for very similar ACL
|
||||||
* rules issues. */
|
* rules issues.
|
||||||
void addACLLogEntry(client *c, int reason, int keypos) {
|
*
|
||||||
|
* The keypos argument is only used when the reason is ACL_DENIED_KEY, since
|
||||||
|
* it allows the function to log the key name that caused the problem.
|
||||||
|
* Similarly the username is only passed when we failed to authenticate the
|
||||||
|
* user with AUTH or HELLO, for the ACL_DENIED_AUTH reason. Otherwise
|
||||||
|
* it will just be NULL.
|
||||||
|
*/
|
||||||
|
void addACLLogEntry(client *c, int reason, int keypos, sds username) {
|
||||||
/* 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;
|
||||||
le->reason = reason;
|
le->reason = reason;
|
||||||
le->object = (reason == ACL_DENIED_CMD) ? sdsnew(c->cmd->name) :
|
le->username = sdsdup(reason == ACL_DENIED_AUTH ? username : c->user->name);
|
||||||
sdsdup(c->argv[keypos]->ptr);
|
|
||||||
le->username = sdsdup(c->user->name);
|
|
||||||
le->ctime = mstime();
|
le->ctime = mstime();
|
||||||
|
|
||||||
|
switch(reason) {
|
||||||
|
case ACL_DENIED_CMD: le->object = sdsnew(c->cmd->name); break;
|
||||||
|
case ACL_DENIED_KEY: le->object = sdsnew(c->argv[keypos]->ptr); break;
|
||||||
|
case ACL_DENIED_AUTH: le->object = sdsnew(c->argv[0]->ptr); break;
|
||||||
|
default: le->object = sdsempty();
|
||||||
|
}
|
||||||
|
|
||||||
client *realclient = c;
|
client *realclient = c;
|
||||||
if (realclient->flags & CLIENT_LUA) realclient = server.lua_caller;
|
if (realclient->flags & CLIENT_LUA) realclient = server.lua_caller;
|
||||||
|
|
||||||
@ -1803,9 +1816,17 @@ void aclCommand(client *c) {
|
|||||||
addReplyMapLen(c,7);
|
addReplyMapLen(c,7);
|
||||||
addReplyBulkCString(c,"count");
|
addReplyBulkCString(c,"count");
|
||||||
addReplyLongLong(c,le->count);
|
addReplyLongLong(c,le->count);
|
||||||
|
|
||||||
addReplyBulkCString(c,"reason");
|
addReplyBulkCString(c,"reason");
|
||||||
addReplyBulkCString(c,(le->reason == ACL_DENIED_CMD) ?
|
char *reasonstr;
|
||||||
"command" : "key");
|
switch(le->reason) {
|
||||||
|
case ACL_DENIED_CMD: reasonstr="command"; break;
|
||||||
|
case ACL_DENIED_KEY: reasonstr="key"; break;
|
||||||
|
case ACL_DENIED_AUTH: reasonstr="auth"; break;
|
||||||
|
}
|
||||||
|
addReplyBulkCString(c,reasonstr);
|
||||||
|
|
||||||
|
addReplyBulkCString(c,"context");
|
||||||
char *ctxstr;
|
char *ctxstr;
|
||||||
switch(le->context) {
|
switch(le->context) {
|
||||||
case ACL_LOG_CTX_TOPLEVEL: ctxstr="toplevel"; break;
|
case ACL_LOG_CTX_TOPLEVEL: ctxstr="toplevel"; break;
|
||||||
@ -1813,8 +1834,8 @@ void aclCommand(client *c) {
|
|||||||
case ACL_LOG_CTX_LUA: ctxstr="lua"; break;
|
case ACL_LOG_CTX_LUA: ctxstr="lua"; break;
|
||||||
default: ctxstr="unknown";
|
default: ctxstr="unknown";
|
||||||
}
|
}
|
||||||
addReplyBulkCString(c,"context");
|
|
||||||
addReplyBulkCString(c,ctxstr);
|
addReplyBulkCString(c,ctxstr);
|
||||||
|
|
||||||
addReplyBulkCString(c,"object");
|
addReplyBulkCString(c,"object");
|
||||||
addReplyBulkCBuffer(c,le->object,sdslen(le->object));
|
addReplyBulkCBuffer(c,le->object,sdslen(le->object));
|
||||||
addReplyBulkCString(c,"username");
|
addReplyBulkCString(c,"username");
|
||||||
|
@ -180,7 +180,7 @@ void execCommand(client *c) {
|
|||||||
int acl_keypos;
|
int acl_keypos;
|
||||||
int acl_retval = ACLCheckCommandPerm(c,&acl_keypos);
|
int acl_retval = ACLCheckCommandPerm(c,&acl_keypos);
|
||||||
if (acl_retval != ACL_OK) {
|
if (acl_retval != ACL_OK) {
|
||||||
addACLLogEntry(c,acl_retval,acl_keypos);
|
addACLLogEntry(c,acl_retval,acl_keypos,NULL);
|
||||||
addReplyErrorFormat(c,
|
addReplyErrorFormat(c,
|
||||||
"-NOPERM ACLs rules changed between the moment the "
|
"-NOPERM ACLs rules changed between the moment the "
|
||||||
"transaction was accumulated and the EXEC call. "
|
"transaction was accumulated and the EXEC call. "
|
||||||
|
@ -609,7 +609,7 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) {
|
|||||||
int acl_keypos;
|
int acl_keypos;
|
||||||
int acl_retval = ACLCheckCommandPerm(c,&acl_keypos);
|
int acl_retval = ACLCheckCommandPerm(c,&acl_keypos);
|
||||||
if (acl_retval != ACL_OK) {
|
if (acl_retval != ACL_OK) {
|
||||||
addACLLogEntry(c,acl_retval,acl_keypos);
|
addACLLogEntry(c,acl_retval,acl_keypos,NULL);
|
||||||
if (acl_retval == ACL_DENIED_CMD)
|
if (acl_retval == ACL_DENIED_CMD)
|
||||||
luaPushError(lua, "The user executing the script can't run this "
|
luaPushError(lua, "The user executing the script can't run this "
|
||||||
"command or subcommand");
|
"command or subcommand");
|
||||||
|
@ -3380,7 +3380,7 @@ int processCommand(client *c) {
|
|||||||
int acl_keypos;
|
int acl_keypos;
|
||||||
int acl_retval = ACLCheckCommandPerm(c,&acl_keypos);
|
int acl_retval = ACLCheckCommandPerm(c,&acl_keypos);
|
||||||
if (acl_retval != ACL_OK) {
|
if (acl_retval != ACL_OK) {
|
||||||
addACLLogEntry(c,acl_retval,acl_keypos);
|
addACLLogEntry(c,acl_retval,acl_keypos,NULL);
|
||||||
flagTransaction(c);
|
flagTransaction(c);
|
||||||
if (acl_retval == ACL_DENIED_CMD)
|
if (acl_retval == ACL_DENIED_CMD)
|
||||||
addReplyErrorFormat(c,
|
addReplyErrorFormat(c,
|
||||||
|
@ -1820,6 +1820,7 @@ void ACLInit(void);
|
|||||||
#define ACL_OK 0
|
#define ACL_OK 0
|
||||||
#define ACL_DENIED_CMD 1
|
#define ACL_DENIED_CMD 1
|
||||||
#define ACL_DENIED_KEY 2
|
#define ACL_DENIED_KEY 2
|
||||||
|
#define ACL_DENIED_AUTH 3 /* Only used for ACL LOG entries. */
|
||||||
int ACLCheckUserCredentials(robj *username, robj *password);
|
int ACLCheckUserCredentials(robj *username, robj *password);
|
||||||
int ACLAuthenticateUser(client *c, robj *username, robj *password);
|
int ACLAuthenticateUser(client *c, robj *username, robj *password);
|
||||||
unsigned long ACLGetCommandID(const char *cmdname);
|
unsigned long ACLGetCommandID(const char *cmdname);
|
||||||
@ -1836,7 +1837,7 @@ void ACLLoadUsersAtStartup(void);
|
|||||||
void addReplyCommandCategories(client *c, struct redisCommand *cmd);
|
void addReplyCommandCategories(client *c, struct redisCommand *cmd);
|
||||||
user *ACLCreateUnlinkedUser();
|
user *ACLCreateUnlinkedUser();
|
||||||
void ACLFreeUserAndKillClients(user *u);
|
void ACLFreeUserAndKillClients(user *u);
|
||||||
void addACLLogEntry(client *c, int reason, int keypos);
|
void addACLLogEntry(client *c, int reason, int keypos, sds username);
|
||||||
|
|
||||||
/* Sorted sets data type */
|
/* Sorted sets data type */
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user