redis multi-tenant isolation ACL permission control (redis-cli/ioredis of nodejs)

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:

Guess you like

Origin blog.csdn.net/qq_42152032/article/details/132766169