After Redis 6 version: ACL function is provided to perform finer-grained authority control on users: (1) Access authority: user name and password (2) Commands that can be executed (3) KEYs that can be operated
Introduction to common ACL rules:
+Instruction list //Add a list of operable instructions, such as: select auth
+@Command Category //Add operable command categories, such as @admin @set
acl cat //View all command categories
~<pattern> //Operator key matching pattern
The default value of the redis database is 0~15, which can be adjusted through the databases parameter.
Several implementation methods of redis multi-tenancy:
1. After redis6, multi-tenant isolation can be implemented through acl, with one db for each user.
2. Based on containers, each user has one redis instance.
The test version of the following code is redis 7.0
redis-cli sets up multi-tenant isolation:
ACL SETUSER username on >password +@all ~* -@admin -select +select|5 // +@all adds all permissions ~* allows all keys to remove @admin permissions only allows select to switch db5
auth username 123456
select 1 //Switching db1 will prompt that there is no permission: (error) NOPERM this user has no permissions to run the 'select' command or its subcommand
select 5
ACL DELUSER username //Delete user
redis-cli --user username --pass 123456 -n 1 # Connect with db1
The nodejs library ioredis sets up multi-tenant isolation:
async function createUser(){
const redis = new Redis({
password: redisPassword,
host: redisHost,
port: redisPort
});
try{
const db = genNumber(); //此db 需自动生成递增数字
const username = `${serviceName}_ecmaster`,
password = uuid.v4().replaceAll("-",""),
rules = [
'+@all',
'~*',
'-@admin',
'-select',
`+select|${db}`,
];
// 创建用户
await redis.acl(
'SETUSER',
username, 'on', `>${password}`,
...rules
);
console.log(`User ${username} created successfully.`);
dockerSetting.dataSource.redis = {
username,
password,
"host": redisHost,
"port": redisPort,
db
}
}catch(e){
throw e;
}finally{
redis.disconnect();
}
}
async function deleteUser(){
const redis = new Redis({
password: redisPassword,
host: redisHost,
port: redisPort
});
try{
const username = `${serviceName}_ecmaster`;
// 删除用户
await redis.call('ACL', 'DELUSER', username);
console.log(`User ${username} deleted successfully.`);
}catch(e){
throw e;
}finally{
redis.disconnect();
}
}
redisInsight visualization tool test, unable to operate key on non-authorized db: