【Redis原始碼】Redis 6 ACL原始碼詳解
簡介
本文主要是講解Redis 6的ACL的實現原理。基本使用詳見:Redis 6.0新特性——ACLs,以及Redis啟動過程分析。
啟動初始化
初始化預設使用者
ACL子模組在Redis啟動過程中初始化,下面程式碼主要是初始化ACL的結構:
/*
* 初始化ACL子系統
* */
void ACLInit(void) {
Users = raxNew(); // 初始化使用者資訊
UsersToLoad = listCreate();
ACLLog = listCreate();
ACLInitDefaultUser();
server.requirepass = NULL; /* Only used for backward compatibility. */
}
ACLInitDefaultUser函式主要是初始化預設使用者,在Redis 6當中預設使用者的許可權就相當於作業系統的管理員一樣,擁有很大的許可權,要限制遠端使用預設使用者連線。
/* 初始化預設使用者 */
void ACLInitDefaultUser(void) {
DefaultUser = ACLCreateUser("default",7);
ACLSetUser(DefaultUser,"+@all",-1); // 預設使用者賦予所有命令的許可權
ACLSetUser(DefaultUser,"~*",-1);// 可以操作任何key
ACLSetUser(DefaultUser,"on",-1);// 預設開啟
ACLSetUser(DefaultUser,"nopass",-1); // 預設不需要密碼
}
載入ACL使用者資訊
ACL資料結構初始化完成之後,通過函式 ACLLoadUsersAtStartup
載入Redis配置裡面的ACL使用者資訊。Redis ACL配置資訊主要有兩種方式:
- 在redis.conf檔案中通過user 配置項配置的ACL資訊。比如:
user worker +@list +@connection ~jobs:* on >ffa9203c493aa99
- 在
redis.conf
中配置aclfile
所配置的檔案中。格式如下圖所示:
通過user方式
通過載入redis.conf配置檔案中讀取user配置項載入ACL資訊。
int ACLLoadConfiguredUsers(void) {
listIter li;
listNode *ln;
listRewind(UsersToLoad,&li);
while ((ln = listNext(&li)) != NULL) {
sds *aclrules = listNodeValue(ln);
sds username = aclrules[0];
// 檢查ACL使用者名稱當中是否存在空格
if (ACLStringHasSpaces(aclrules[0],sdslen(aclrules[0]))) {
serverLog(LL_WARNING,"Spaces not allowed in ACL usernames");
return C_ERR;
}
// 建立ACL使用者
user *u = ACLCreateUser(username,sdslen(username));
if (!u) {
u = ACLGetUserByName(username,sdslen(username));
serverAssert(u != NULL);
ACLSetUser(u,"reset",-1);
}
/* Load every rule defined for this user. */
for (int j = 1; aclrules[j]; j++) {
// 新增當前使用者的所有屬性
if (ACLSetUser(u,aclrules[j],sdslen(aclrules[j])) != C_OK) {
char *errmsg = ACLSetUserStringError();
serverLog(LL_WARNING,"Error loading ACL rule '%s' for "
"the user named '%s': %s",
aclrules[j],aclrules[0],errmsg);
return C_ERR;
}
}
/* Having a disabled user in the configuration may be an error,
* warn about it without returning any error to the caller.
* 使用者沒有開啟的時候列印到日誌裡面
* */
if (u->flags & USER_FLAG_DISABLED) {
serverLog(LL_NOTICE, "The user '%s' is disabled (there is no "
"'on' modifier in the user description). Make "
"sure this is not a configuration error.",
aclrules[0]);
}
}
return C_OK;
}
通過檔案方式
ACLLoadFromFile
函式就是從redis.conf配置的 aclfile
所在的檔案當中讀取ACL配置資訊。
ACL 控制
ACL控制主要是在從命令表中獲取命令之後判斷當前登入的使用者是否對當前執行的命令是否有許可權。判斷的函式為:
int ACLCheckCommandPerm(client *c, int *keyidxptr)
具體判斷是否存在許可權的函式為ACLGetUserCommandBit,主要實現如程式碼,其中id表示當前命令所對應的id。
int ACLGetUserCommandBit(user *u, unsigned long id) {
uint64_t word, bit;
// 計算命令在allowed_commands當中對應的bit位
if (ACLGetCommandBitCoordinates(id,&word,&bit) == C_ERR) return 0;
return (u->allowed_commands[word] & bit) != 0;
}
標 題:《【Redis原始碼】Redis 6 ACL原始碼詳解》
作 者:zeekling
提 示:轉載請註明文章轉載自個人部落格:小令童鞋
相關文章
- Redis原始碼系列之rename講解Redis原始碼
- Redis原始碼閱讀:Redis字串SDSRedis原始碼字串
- [Redis原始碼閱讀]redis持久化Redis原始碼持久化
- Redis【1】- 如何閱讀 Redis 原始碼Redis原始碼
- Redis【1】- 如何閱讀 Redis原始碼Redis原始碼
- Redis radix tree原始碼解析Redis原始碼
- Redis【2】- SDS原始碼分析Redis原始碼
- macbook 原始碼安裝 redisMac原始碼Redis
- 5.6 以太坊原始碼詳解6原始碼
- 曹工說Redis原始碼(6)-- redis server 主迴圈大體流程解析Redis原始碼Server
- redis個人原始碼分析筆記3---redis的事件驅動原始碼分析Redis原始碼筆記事件
- redis原始碼解析----epoll的使用Redis原始碼
- redis原始碼學習之slowlogRedis原始碼
- 原始碼編譯安裝Redis原始碼編譯Redis
- 【原始碼】Redis exists命令bug分析原始碼Redis
- [Redis原始碼閱讀]實現一個redis命令--nonzerodecrRedis原始碼
- Redis原始碼漂流記(二)-搭建Redis除錯環境Redis原始碼除錯
- Redis原始碼剖析之主從複製Redis原始碼
- Redis網路模型的原始碼分析Redis模型原始碼
- [原始碼分析] OpenTracing之跟蹤Redis原始碼Redis
- redis原始碼分析之事務Transaction(下)Redis原始碼
- redis原始碼分析之有序集SortedSetRedis原始碼
- 【原始碼】Redis命令處理過程原始碼Redis
- 【原始碼】Redis Server啟動過程原始碼RedisServer
- RediSearch和Redis Streams實戰原始碼Redis原始碼
- ProgressHUD原始碼詳解原始碼
- HashMap原始碼詳解HashMap原始碼
- redux 原始碼詳解Redux原始碼
- TimSort原始碼詳解原始碼
- 走近原始碼:Redis的啟動過程原始碼Redis
- 走近原始碼:Redis如何清除過期key原始碼Redis
- Redis原始碼閱讀:sds字串實現Redis原始碼字串
- redis原始碼分析(五):資料持久化Redis原始碼持久化
- 故障分析 | Redis AOF 重寫原始碼分析Redis原始碼
- Redis原始碼解析之跳躍表(一)Redis原始碼
- Redis原始碼解析之跳躍表(三)Redis原始碼
- Redis(五):hash/hset/hget 命令原始碼解析Redis原始碼
- [Redis原始碼閱讀]當你啟動Redis的時候,Redis做了什麼Redis原始碼