数据库权限配置

219 阅读23分钟

Mysql

概念

mysql通过权限表来控制用户对于数据库的访问,权限表存放在mysql数据库中。存储账户权限信息的表主要由:user、db、tables_priv、columns_priv、procs_priv、proxies_priv这六张表(5.6版本前还有一个host表,现在将host表中内容整合到user表中)

mysql用户权限管理主要有以下作用:

  ① 可以限制用户访问哪些库、哪些表

  ② 可以限制用户对哪些表执行SELECT、CREATE、DELETE、DELETE、ALTER等操作

  ③ 可以限制用户登录的IP或域名

  ④ 可以限制用户自己的权限是否可以授权给别的用户

操作执行权限

mysql数据库(系统数据库)下的表:user、db、tables_priv、columns_priv、proce_priv、proxies_priv共同构成授权表;

  1. user表

user表列出可以连接服务器的用户及其口令,并且它指定他们有哪种全局(超级用户)权限。在user表启用的任何权限均是全局权限,并适用于所有数据库。例如,如果你启用了DELETE权限,在这里列出的用户可以从任何表中删除记录,所以在你这样做之前要认真考虑。

  1. db表

db表列出数据库,而用户有权限访问它们。在这里指定的权限适用于一个数据库中的所有表。

  1. tables_priv表

tables_priv表指定表级权限,在这里指定的一个权限适用于一个表的所有列。

  1. columns_priv表

columns_priv表指定列级权限。这里指定的权限适用于一个表的特定列。

  1. proce_priv

proce_priv表指定存储过程权限。这里代表允许使用某个存储过程的权限。

  1. proxies_priv

利用 MySQL proxies_priv(模拟角色)实现类似用户组管理。角色(Role)可以用来批量管理用户,同一个角色下的用户,拥有相同的权限。

注:MySQL5.7.X以后可以模拟角色(Role)的功能,通过mysql.proxies_priv模拟实现

权限分布

权限分布可以设置的权限
表权限'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop', 'Grant', 'References', 'Index', 'Alter'
列权限'Select', 'Insert', 'Update', 'References'
过程权限'Execute', 'Alter Routine', 'Grant'

实际操作

使用create user/grant命令

注:在mysql5.7.7版本前,若授权用户不存在,那么grant语句会自动创建新的账户,除非设置参数sql_mode包含NO_AUTO_CREATE_USER。但从5.7.7版本开始,默认的sql_mode就包含NO_AUTO_CREATE_USER,也就是说,grant语句不会在创建新的账户。所以若mysql版本大于等于5.7.7,需要先create user,再grant

创建用户

create user [用户名]@[访问地址] identified by [密码]

示例:

-- 创建zhangsan用户 但并没有权限 只能在localhost登录
CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY 'password';

-- 创建lisi用户,只是创建用户并没有权限,密码为 password,%通配符表示任何主机都可以连接(可以远程连接)
CREATE USER 'lisi'@'%' IDENTIFIED BY 'password';

-- (5.7.7版本前)的创建用户并赋予RELOAD,PROCESS权限 ,在所有的库和表上;*.*:代表所有的库表
GRANT RELOAD,PROCESS ON *.* TO 'admin'@'localhost' identified by '123456';

授权格式

  常用权限:all privileges、create、drop、select、insert、delete、update

grant [权限1,权限2,权限3] on *.* to user@'host' identified by 'password'

例如:

-- 给"zhangsan" 用户管理员权限,并且允许该用户继续给别的用户赋权限(相当于管理员用户)
grant all privileges on *.* to 'zhangsan'@'192.168.1.%' with grant option;

-- all privileges:表示将所有权限授予给用户。也可指定具体的权限,如:SELECT、CREATE、DROP等。
-- on:表示这些权限对哪些数据库和表生效,格式:数据库名.表名,这里写“*”表示所有数据库,所有表。如果我要指定将权限应用到test库的user表中,可以这么写:test.user
-- to:将权限授予哪个用户。格式:”用户名”@”登录IP或域名”。%表示没有限制,在任何主机都可以登录。比如:'zhangsan'@'192.168.1.%',表示zhangsan这个用户只能在192.168.0.* IP段登录
-- with grant option:通过在grant语句的最后使用该子句,就允许被授权的用户把得到的权限继续授给其它用户
-- 注:使用GRANT添加权限,权限会自动叠加,不会覆盖之前授予的权限,比如你先给用户添加一个SELECT权限,后来又给用户添加了一个UPDATE权限,那么该用户就同时拥有了SELECT和UPDATE权限。
授予管理员权限
GRANT ALL PRIVILEGES ON *.* TO 'zhangsan'@'localhost' WITH GRANT OPTION;
-- 刷新权限命令
flush privileges;
库、表权限
-- zhangsan用户可以对test数据库中所有表进行查询操作
grant select on test.* to zhangsan;

-- lisi用户可以在test数据库创建、修改、删除表以及视图
grant createalterdropcreate view on test.* to lisi;

-- lisi可以创建、修改、删除数据库以及对数据库中所有表进行create、alter和drop
grant create,alter,drop on . to lisi;

-- lisi可以创建新用户
grant create user on . to lisi;
列权限
-- zhangsan在test库的shop表中的id、name、price列有select权限
grant select(id,name,price) on test.temp to zhangsan@'localhost' WITH GRANT OPTION;
-- 刷新权限
mysql> flush privileges;

-- zhangsan可以对test库的shop表中的id和name列有update权限
grant update(id,name) on test.shop to zhangsan@'localhost';
回收权限
-- 查看用户权限
show grants for admin@'localhost';

-- 回收权限
revoke PROCESS ON *.* FROM admin@'localhost';
-- 刷新权限
flush privileges;
模拟角色

利用 MySQL proxies_priv(模拟角色)实现类似用户组管理

-- 创建用户 role1
create user role1;

-- 创建角色 user1
create user user1;

-- 用户role1 mysql库下所有表的select权限
grant select on mysql.* to role1;

-- 查看role1 grant
show grants for role1;

登录user1用户,没有任何权限

登录role1用户,可以查看mysql库

-- 使用proxy代理
grant proxy on role1 to user1;

-- 查看user1 grant
show grants for user1;

查看proxies_priv表

登录user1用户

可以查询mysql表

Clickhouse

clickhouse支持两种权限配置方式:配置文件及RBAC

配置文件

profile

profile的作用类似于用户角色,可以在users.xml中定义多组profile,并可以为每组profile定义不同的配置项,比如闲置资源的使用。多个profile的配置可以复用

例如:

<profiles> --配置profile
    <default>  -- 自定义profile
        <max_memory_usage>10000000000</max_memory_usage>
        <use_uncompressed_cache>0</use_uncompressed_cache>
        <load_balancing>random</load_balancing>
    </default>
    <readonly>  -- 自定义profile
        <readonly>1</readonly>
       <max_memory_usage>100000000</max_memory_usage>
    </readonly>
</profiles>

说明:
<default>:自定义profile,可以在它下面设置相关参数,如:最大内存使用、只读等等。更多的配置参数后续会介绍,也可以看官网文档,可以设置多个profile。

profile文件可以相互继承,只需在配置文件中列出,例如:

<test>
    <profile>readonly</profile>
    <max_memory_usage>10000</max_memory_usage>
</test>

test中profile集成了readonly的profile,包含了其所有的配置,并且使用新参数去覆盖了原有的配置

constraints约束

user.xml配置文件的profile选项组下constraints选项组里定义对设置的约束,并禁止用户使用SET查询更改某些设置。constraints标签可以设置一组约束条件,以限制profile内的参数值被随意修改,约束条件有如下三种规则:

  min:最小值约束

  max:最大值约束

  readonly:只读约束,该参数值不能被修改

  例如:

<profiles>
    <user_name>
        <constraints>
            <setting_name_1>
                <min>lower_boundary</min>
            </setting_name_1>
            <setting_name_2>
                <max>upper_boundary</max>
            </setting_name_2>
            <setting_name_3>
                <min>lower_boundary</min>
                <max>upper_boundary</max>
            </setting_name_3>
            <setting_name_4>
                <readonly/>
            </setting_name_4>
        </constraints>
    </user_name>
</profiles>

若是在profiles中,default中定义的constraints约束将作为默认的全局约束,自动被其他的profile继承,例如:

<profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <force_index_by_date>0</force_index_by_date>
            <load_balancing>random</load_balancing>
            <constraints>
                <max_memory_usage>
                    <min>100000</min>
                    <max>20000</max>
                </max_memory_usage>
                <force_index_by_date>
                    <readonly/>
                </force_index_by_date>
            </constraints>
        </default>
    </profiles>
    
    在示例中,default标签中的constraints约束内的所有配置是默认全局的

quotas配额

user.xml配置文件的选项组quotas里设置,限制该用户一段时间内的资源使用,即对一段时间内运行的一组查询施加限制,而不是限制单个查询。还具有限制单个查询的复杂性的功能

<!-- Quotas. -->
    <quotas>
        <!-- Name of quota. -->
        <default> --指定quotas名
            <!-- Limits for time interval. You could specify many intervals with different limits. -->
            <interval> --时间间隔
                <!-- Length of interval. -->
                <duration>3600</duration> --周期
                <!-- No limits. Just calculate resource usage for time interval. -->
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>
    
<default>:配额规则名。
<interval>:配置时间间隔,每个时间内的资源消耗限制。
<duration>:时间周期,单位秒。
<queries>:时间周期内允许的请求总数,0表示不限制。
<errors>:时间周期内允许的异常总数,0表示不限制。
<result_rows>:时间周期内允许返回的行数,0表示不限制。
<read_rows>:时间周期内允许在分布式查询中,远端节点读取的数据行数,0表示不限制。
<execution_time>:时间周期内允许执行的查询时间,单位是秒,0表示不限制。

默认情况下,配额仅跟踪每小时的资源消耗,而没有限制使用情况。在每个请求之后,将为每个时间间隔计算的资源消耗输出到服务器日志

用户配置

在users.xml配置文件的users选项组配置自定义用户,必须包含以下属性:用户名、密码、访问ip、数据库、表等。它可以应用上面的profile、quota

<users>
    <!-- If user name was not specified, 'default' user is used. -->
    <user_name> --配置的用户
        <password></password> --明文密码
        <!-- Or -->
        <password_sha256_hex></password_sha256_hex> --加密密码,二选一

        <networks incl="networks" replace="replace"> --允许登录的地址,用于限制用户登录的客户端地址
        </networks>

        <profile>profile_name</profile>   --指定用户的profile

        <quota>default</quota>    -- 指定用户的quota,限制用户使用资源

        <databases>               --指定数据库
            <database_name>
                <table_name>      --指定数据表
                    <filter>expression</filter>
                </table_name>
            </database_name>
        </databases>
    </user_name>
    <!-- Other users settings -->
</users>

<user_name>:自定义用户
<password>:用户密码  密码可以以纯文本、SHA256(十六进制格式)、password_double_sha1_hex(和MySQL兼容)指定
<networks>:限制用户登录的客户端地址  可以通过IP,主机等进行限制
<profile>:指定用户的profile
<quota>:指定用户的quota,限制用户使用资源
<database_name>:指定用户访问的数据库
<table_name>:指定用户访问的表
<filter>:指定用户访问的过滤器,限制返回符合条件的行。如:id = 1 ,即查询表只返回id=1的行
<users>
        <default>
            <password>123456</password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </default>

        <zhoujy>
            <password_double_sha1_hex>6bb4837eb74329105ee4568dda7dc67ed2ca2ad9</password_double_sha1_hex>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
            <allow_databases>
                <database>test</database>
            </allow_databases>
            <databases>
                <test>  
                    <xx>
                        <filter>id >= 500 </filter>  --行级限制
                    </xx>
                </test>
            </databases>
        </zhoujy>

    </users>
    
default:指定了密码、访问IP、profile、quota。
zhoujy :指定了密码、访问IP、profile、quota,以及它只能使用test库,并且只能返回test库xx表id大于等于500的数据。
    

查询权限管理

查询可以分为以下几种类型:

  读:SELECT,SHOW,DESCRIBE,EXISTS

  写:INSERT,OPTIMIZE。

  DDL:CREATE,ALTER,RENAME,ATTACH,DETACH,DROP TRUNCATE。

  设置:SET,USE。

通过配置标签来控制:

  readonly:读权限、写权限和设置权限,由此标签控制,它有三种取值

    0:不进行任何限制

    1:只读权限(select exists show 和 describe)

    2:读权限和设置权限(在只读上增加set)

  allow_ddl:DDL权限由此标签控制,它有两种取值:

    0:不允许DDL查询;

    1:允许DDL查询(默认值)

<profiles>   --在profiles里设置
        ...
        <normal> --只读,不能DDL
            <readonly>1</readonly>
            <allow_ddl>0</allow_ddl>
        </normal>

        <normal_1> --读且能set,不能DDL
            <readonly>2</readonly>
            <allow_ddl>0</allow_ddl>
        </normal_1>

        <normal_2> --只读,即使DDL允许
            <readonly>1</readonly>
            <allow_ddl>1</allow_ddl>
        </normal_2>

        <normal_3> --读写,能DDL
            <readonly>0</readonly>
            <allow_ddl>1</allow_ddl>
        </normal_3>

    </profiles>

...
    <users>
        ...
        <test>
            <password>123456</password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>normal_3</profile> --用户引用相关profile
            <quota>default</quota>
        </test>
    </users>
...

访问权限控制

访问权限在users.xml中的users选项组里设置,用于在群集中组合的服务器之间交换信息的用户不得有任何限制或配额-否则,分布式查询将失败。不能授予对一个数据库有完全访问权限,而对另一数据库具有只读访问权限,包含如下:

  网络访问控制:通过IP地址或host主机名

  数据库访问控制:通过read_only、allow_ddl来控制读、写、设置、DDL、KILL等

  指定数据库访问:通过<allow_databases>指定访问数据库

  指定表的访问:通过filter指定表达式来访问表中的数据行

管理账号

profiles里默认的profile是没有限制的,所以默认就是管理账号,也就是读写账号,唯一区别就是限制各个账号可以使用不同的使用资源

<?xml version="1.0"?>
<yandex>
    <profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <load_balancing>random</load_balancing>
        </default>
        <readonly>
            <readonly>1</readonly>
        </readonly>
    </profiles>

    <users>
        <default>
            <password></password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </default>

        <zhoujy>
            <password_double_sha1_hex>6bb4837eb74329105ee4568dda7dc67ed2ca2ad9</password_double_sha1_hex>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
                <ip>127.0.0.1</ip>
                <ip>192.168.163.132</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </zhoujy>

    </users>

    <quotas>
        <default>
            <interval>
                <duration>3600</duration>
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>

</yandex>
只读账号

在profiles里设置readonly,在users里给指定用户进行引用。

<?xml version="1.0"?>
<yandex>
    <profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <load_balancing>random</load_balancing>
        </default>
        <readonly>
            <readonly>1</readonly>
        </readonly>
    </profiles>

    <users>
        <default>
            <password></password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </default>

        <zhoujy>
            <password_double_sha1_hex>6bb4837eb74329105ee4568dda7dc67ed2ca2ad9</password_double_sha1_hex>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
                <ip>127.0.0.1</ip>
                <ip>192.168.163.132</ip>
            </networks>
            <profile>readonly</profile>
            <quota>default</quota>
        </zhoujy>

    </users>

    <quotas>
        <default>
            <interval>
                <duration>3600</duration>
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>

</yandex>
读写账号

若与管理账号作区分,就限制该账号不能使用set相关操作,使用constraints设置

<?xml version="1.0"?>
<yandex>
    <profiles>
        <default>
            <max_memory_usage>10000000000</max_memory_usage>
            <use_uncompressed_cache>0</use_uncompressed_cache>
            <load_balancing>random</load_balancing>
        </default>

        <readonly>
            <readonly>1</readonly>
        </readonly>

        <readwrite>
            <constraints>
                <max_memory_usage>
                    <readonly/>
                </max_memory_usage>
                <force_index_by_date>
                    <readonly/>
                </force_index_by_date>
            </constraints>
        </readwrite>

    </profiles>

    <users>
        <default>
            <password></password>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
            </networks>
            <profile>default</profile>
            <quota>default</quota>
        </default>

        <zhoujy>
            <password_double_sha1_hex>6bb4837eb74329105ee4568dda7dc67ed2ca2ad9</password_double_sha1_hex>
            <networks incl="networks" replace="replace">
                <ip>::/0</ip>
                <ip>127.0.0.1</ip>
                <ip>192.168.163.132</ip>
            </networks>
            <profile>readwrite</profile>
            <quota>default</quota>
        </zhoujy>

    </users>

    <quotas>
        <default>
            <interval>
                <duration>3600</duration>
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>

</yandex>
限制账号
限制ip
<networks incl="networks" replace="replace">
    <ip>::/0</ip>   --允许任何地址访问
    <ip>127.0.0.1</ip>  --允许本地访问
    <ip>192.168.163.132</ip> --允许该IP访问
</networks>

若是限制为:只允许某几个ip访问
<networks incl="networks" replace="replace">
    <ip>192.168.163.132</ip>
    <ip>192.168.163.133</ip>
    <ip>192.168.163.134</ip>
</networks>
限制数据库
<allow_databases>
    <database>test</database>
</allow_databases>
限制表
<databases>
    <test>
        <xx>
            <filter>id >= 500 </filter>
        </xx>
    </test>
</databases>
限制一定周期内资源使用
<quotas>
    <default>   --quotas名称
        <interval> --周期
            <duration>3600</duration>  --周期时间,单位秒
            <queries>0</queries>   --查询限制,0不限制
            <errors>0</errors>       --错误限制,0不限制
            <result_rows>0</result_rows> --返回行限制,0不限制
            <read_rows>0</read_rows>  --读取行限制,0不限制
            <execution_time>0</execution_time> --执行时间限制,0不限制
        </interval>
    </default>
</quotas>

在users下的用户配置中引用
<quota>default</quota>
限制整体资源使用
<profiles>
    <default>
        <max_memory_usage>10000000000</max_memory_usage>  --限制查询最大使用内存
        <use_uncompressed_cache>0</use_uncompressed_cache>
        <load_balancing>random</load_balancing>
    </default>
</profiles>

RBAC

SQL 驱动的访问控制和账户管理功能,在默认的情况下对所有用户是禁用的,所以首先需要开启这项功能,开启的方式分为两个步骤:

  ① 在 config.xml 中添加 access_control_path 配置项

    通过sql形式创建的用户、角色等信息讲义文件的形式保存在这个目录

    添加此配置后需重启服务

<!-- config.xml -->        
<access_control_path>/var/lib/clickhouse/access/</access_control_path>

  ② 在 user.xml 中为默认用户 default 添加 access_management 配置项

<!-- user.xml  -->
     <users>
        <!-- If user name was not specified, 'default' user is used. -->
        <default>
           <password></password>
           <access_management>1</access_management>
           ...

一般情况下,default用户用来创建管理用户用于管理,比如:创建一个管理用户admin

-- 创建admin用户
CREATE USER admin IDENTIFIED WITH PLAINTEXT_PASSWORD BY '123'
-- 授权 全部权限
GRANT ALL ON *.* TO admin WITH GRANT OPTION

角色

角色是一组权限

分配角色的用户将获得该角色的所有权限

CREATE ROLE [IF NOT EXISTS | OR REPLACE] name1 [ON CLUSTER cluster_name1] [, name2 [ON CLUSTER cluster_name2] ...]
    [IN access_storage_type]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]

举例:

-- 创建角色
CREATE ROLE accountant;
-- 给角色授权
GRANT SELECT ON db.* TO accountant;
-- 给用户分配角色
GRANT accountant TO mira;

授权

授权语句:

GRANT [ON CLUSTER cluster_name] privilege[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} TO {user | role | CURRENT_USER} [,...] [WITH GRANT OPTION] [WITH REPLACE OPTION]

-- privilege 权限类型
-- role 用户角色
-- user 用户账号 

分配角色:

GRANT [ON CLUSTER cluster_name] role [,...] TO {user | another_role | CURRENT_USER} [,...] [WITH ADMIN OPTION] [WITH REPLACE OPTION]

比如:向join用户授予查询db库table表x,y列的select权限

GRANT SELECT(x,y) ON db.table TO john WITH GRANT OPTION

撤销权限:

-- 撤销权限
REVOKE [ON CLUSTER cluster_name] privilege[(column_name [,...])] [,...] ON {db.table|db.*|*.*|table|*} FROM {user | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user | CURRENT_USER} [,...]

-- 撤销角色
REVOKE [ON CLUSTER cluster_name] [ADMIN OPTION FOR] role [,...] FROM {user | role | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user_name | role_name | CURRENT_USER} [,...]

-- eg:
GRANT SELECT ON *.* TO john;
REVOKE SELECT ON accounts.* FROM john;

GRANT SELECT ON accounts.staff TO mira;
REVOKE SELECT(wage) ON accounts.staff FROM mira;

权限分类

SELECT

INSERT

ALTER

  ALTER TABLE

    ALTER UPDATE

    ALTER DELETE

    ALTER COLUMN

      ALTER ADD COLUMN

      ALTER DROP COLUMN

      ALTER MODIFY COLUMN

      ALTER COMMENT COLUMN

      ALTER CLEAR COLUMN

      ALTER RENAME COLUMN

    ALTER INDEX

      ALTER ORDER BY

      ALTER SAMPLE BY

      ALTER ADD INDEX

      ALTER DROP INDEX

      ALTER MATERIALIZE INDEX

      ALTER CLEAR INDEX

    ALTER CONSTRAINT

      ALTER ADD CONSTRAINT

      ALTER DROP CONSTRAINT

    ALTER TTL

      ALTER MATERIALIZE TTL

    ALTER SETTINGS

    ALTER MOVE PARTITION

    ALTER FETCH PARTITION

    ALTER FREEZE PARTITION

  ALTER VIEW

    ALTER VIEW REFRESH

    ALTER VIEW MODIFY QUERY

    ALTER VIEW MODIFY SQL SECURITY

CREATE

  CREATE DATABASE

  CREATE TABLE

    CREATE ARBITRARY TEMPORARY TABLE

      CREATE TEMPORARY TABLE

  CREATE VIEW

  CREATE DICTIONARY

  CREATE FUNCTION

DROP

  DROP DATABASE

  DROP TABLE

  DROP VIEW

  DROP DICTIONARY

  DROP FUNCTION

TRUNCATE

OPTIMIZE

SHOW

  SHOW DATABASES

  SHOW TABLES

  SHOW COLUMNS

  SHOW DICTIONARIES

KILL QUERY

ACCESS MANAGEMENT

  CREATE USER

  ALTER USER

  DROP USER

  CREATE ROLE

  ALTER ROLE

  DROP ROLE

  CREATE ROW POLICY

  ALTER ROW POLICY

  DROP ROW POLICY

  CREATE QUOTA

  ALTER QUOTA

  DROP QUOTA

  CREATE SETTINGS PROFILE

  ALTER SETTINGS PROFILE

  DROP SETTINGS PROFILE

  SHOW ACCESS

    SHOW_USERS

    SHOW_ROLES

    SHOW_ROW_POLICIES

    SHOW_QUOTAS

    SHOW_SETTINGS_PROFILES

  ROLE ADMIN

SYSTEM

  SYSTEM SHUTDOWN

  SYSTEM DROP CACHE

    SYSTEM DROP DNS CACHE

    SYSTEM DROP MARK CACHE

    SYSTEM DROP UNCOMPRESSED CACHE

  SYSTEM RELOAD

    SYSTEM RELOAD CONFIG

    SYSTEM RELOAD DICTIONARY

      SYSTEM RELOAD EMBEDDED DICTIONARIES

    SYSTEM RELOAD FUNCTION

    SYSTEM RELOAD FUNCTIONS

  SYSTEM MERGES

  SYSTEM TTL MERGES

  SYSTEM FETCHES

  SYSTEM MOVES

  SYSTEM SENDS

    SYSTEM DISTRIBUTED SENDS

    SYSTEM REPLICATED SENDS

  SYSTEM REPLICATION QUEUES

  SYSTEM SYNC REPLICA

  SYSTEM RESTART REPLICA

  SYSTEM FLUSH

    SYSTEM FLUSH DISTRIBUTED

    SYSTEM FLUSH LOGS

  CLUSTER (see also access_control_improvements.on_cluster_queries_require_cluster_grant configuration directive)

INTROSPECTION

  addressToLine

  addressToLineWithInlines

  addressToSymbol

  demangle

SOURCES

  FILE

  URL

  REMOTE

  YSQL

  ODBC

  JDBC

  HDFS

  S3

dictGet

NAMED COLLECTION ADMIN

  CREATE NAMED COLLECTION

  DROP NAMED COLLECTION

  ALTER NAMED COLLECTION

  SHOW NAMED COLLECTIONS

  SHOW NAMED COLLECTIONS SECRETS

  NAMED COLLECTION

TABLE ENGINE

Mongo

MongoDB 采用基于角色的访问控制 (RBAC) 来管理对 MongoDB 系统的访问。用户被授予一个或多个角色,这些角色决定用户对数据库资源和操作的访问权限。除了角色分配之外,用户无权访问系统。

内置角色

数据库用户角色

read:只能读取特定数据库上的集合和集合数据

readWrite:只能读取、修改特定数据库上的集合和集合数据

数据库管理角色

dbAdmin: 能执行管理函数,如索引创建、删除,查看统计或访问 system.profile

dbOwner: 对当前数据库有全部权限

userAdmin: 能创建、删除和管理用户

集群管理角色

clusterAdmin:提供最大的集群管理访问权限

clusterManager:提供对集群的管理和监控操作,可以访问config和local数据库

clusterMonitor:提供对监控工具的只读访问

hostManager:提供监控和管理服务器的能力

备份和恢复角色

backup:提供备份数据所需的最低权限

restore:提供恢复数据所需权限

所有数据库角色

readAnyDatabase:在除local和config之外的所有数据库上提供与读取相同的只读权限

readWriteAnyDatabase:在除local和config之外的所有数据库上提供与读写相同的权限

userAdminAnyDatabase:在除local和config之外的所有数据库上,提供与userAdmin相同的对用户管理操作的访问权限

dbAdminAnyDatabase:在除local和config之外的所有数据库上提供与dbAdmin相同的权限

超级用户角色

Root

内部角色

__system

实际操作

① docker启动时添加--auth参数

② 进入mongo 创建管理角色

use admin;
db.createUser({
    user: "xxx",
    pwd: "pwd",
    role: [{
        role: "userAdminAnyDatabase",
        db: "admin"
    }]
})

③ 使用创建的角色登录mongo

④ 切换到要给权限的数据库

⑤ 创建只读权限角色

 db.createUser({user:"userRead", pwd: "123456", roles: [{role: "read", db: "test"}]})

⑥ 创建读写权限角色

db.createUser({user:"userrw", pwd: "123456", roles: [{role: "readWrite", db: "test"}]})

⑦ 使用读写权限用户登录 验证

mongo -u userrw -p 123456 --authenticationDatabase test

use test

db.testcol.insert({"name": "zhang", "age": 18})

db.testcol.find()

⑧ 使用只读权限用户登录 验证

mongo -u userrw -p 123456 --authenticationDatabase test

use test

db.testcol.find()

db.testcol.insert({"name": "zhao", "age": 18})

Redis

Redis版本6.0之前没有权限概念,只有密码,通过密码认证就可以随意操作

Redis 6.0发布了权限管理功能ACL(access control list 访问控制列表),可以对不同的用户设置不同的权限,限制用户可以使用的命令,可以访问的key等

基本操作

查看用户

查看全部用户
acl list

127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"

default:用户名,兼容auth命令
on:用户已启用,off表示禁用
nopass:没有密码
~*:表示可访问所有的key
&*:表示用户可以访问所有的pub/sub频道
+@all:所有命令集合的所有权限
    表示用户的权限
        +:添加权限
        -:删减权限
        @:为redis命名分类
        all:全部的命令集合
    

acl users
127.0.0.1:6379> acl users
1) "default"
只显示用户名,比较简洁
查看当前使用的用户
acl whoami

127.0.0.1:6379> acl whoami
"default"
获取指定用户的详细权限信息
acl getuser default

127.0.0.1:6379> acl getuser default
 1) "flags"
 2) 1) "on"
    2) "nopass"
 3) "passwords"
 4) (empty array)
 5) "commands"
 6) "+@all"
 7) "keys"
 8) "~*"
 9) "channels"
10) "&*"
11) "selectors"
12) (empty array)

创建用户

acl setuser 用户名

127.0.0.1:6379> acl setuser testuser
OK
127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"
2) "user testuser off resetchannels -@all"

创建完用户后都是不可用状态,虽然没有显示nopass,但是也是没有密码,并且没有任何权限

启用、禁用用户

acl setuser 用户名 on/off

127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"
2) "user testuser on resetchannels -@all"

设置密码、取消密码

# 设置密码
acl setuser 用户名 >密码

127.0.0.1:6379> acl setuser testuser >123456
OK
127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"
2) "user testuser on #8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92 resetchannels -@all"

# 取消密码
acl setuser 用户名 <密码

127.0.0.1:6379> acl setuser testuser <12346
(error) ERR Error in ACL SETUSER modifier '<12346': The password you are trying to remove from the user does not exist
127.0.0.1:6379> acl setuser testuser <123456
OK
127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"
2) "user testuser on resetchannels -@all"

删除用户

acl deluser 用户名

127.0.0.1:6379> acl deluser testuser
(integer) 1
127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"

权限操作

查看所有命令集合

redis目前把所有的命令一共归类了21个集合,我们可以很方便地对某个用户添加/删除某个命令集合的权限。

需要注意的是,同一个命令有可能属于多个不同的命令集合,多个集合之间存在交集,比如get命令既属于命令集合string,也属于命令集合fast

acl cat

127.0.0.1:6379> acl cat
 1) "keyspace"
 2) "read"
 3) "write"
 4) "set"
 5) "sortedset"
 6) "list"
 7) "hash"
 8) "string"
 9) "bitmap"
10) "hyperloglog"
11) "geo"
12) "stream"
13) "pubsub"
14) "admin"
15) "fast"
16) "slow"
17) "blocking"
18) "dangerous"
19) "connection"
20) "transaction"
21) "scripting"

查看置顶命令集合的所有子命令

acl cat 集合名
    
127.0.0.1:6379> acl cat string
 1) "mset"
 2) "incrby"
 3) "decr"
 4) "substr"
 5) "getex"
 6) "psetex"
 7) "getrange"
 8) "set"
 9) "getdel"
10) "setex"
11) "decrby"
12) "msetnx"
13) "strlen"
14) "append"
15) "setnx"
16) "incr"
17) "get"
18) "incrbyfloat"
19) "mget"
20) "lcs"
21) "getset"
22) "setrange"

增加、取消指定命令集合权限

  ACL SETUSER 用户名 -@命令集合名 给指定用户删除指定命令集合的权限

  多个命令集合用空格隔开

# 添加一个用户
127.0.0.1:6379> acl setuser adduser
OK
127.0.0.1:6379> acl list
1) "user adduser off resetchannels -@all"
2) "user default on nopass ~* &* +@all"

# 启用用户
127.0.0.1:6379> acl setuser adduser on
OK
127.0.0.1:6379> acl list
1) "user adduser on resetchannels -@all"
2) "user default on nopass ~* &* +@all"

# 设置用户密码
127.0.0.1:6379> acl setuser adduser >111
OK
127.0.0.1:6379> acl list
1) "user adduser on #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae resetchannels -@all"
2) "user default on nopass ~* &* +@all"

# 新开一个窗口
# 验证用户
127.0.0.1:6379> auth adduser 111
OK
# 获取key 用户无权限
127.0.0.1:6379> get name
(error) NOPERM this user has no permissions to run the 'get' command


# 添加string类型所有权限
127.0.0.1:6379> acl setuser adduser ~* +@string
OK
127.0.0.1:6379> acl list
1) "user adduser on #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~* resetchannels -@all +@string"
2) "user default on nopass ~* &* +@all"

# 验证
127.0.0.1:6379> auth adduser 111
OK
127.0.0.1:6379> set name qwe
OK
127.0.0.1:6379> get name


# 去除set权限
127.0.0.1:6379> acl setuser adduser -set
OK
127.0.0.1:6379> acl list
1) "user adduser on #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~* resetchannels -@all +@string -set"
2) "user default on nopass ~* &* +@all"

# 验证
127.0.0.1:6379> auth adduser 111
OK
127.0.0.1:6379> set age 12
(error) NOPERM this user has no permissions to run the 'set' command



# 多个权限
127.0.0.1:6379> acl setuser adduser +ttl +hset +hlen
OK
127.0.0.1:6379> acl list
1) "user adduser on #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~* resetchannels -@all +@string +hset -set +hlen +ttl"
2) "user default on nopass ~* &* +@all"


# 限制key范围
127.0.0.1:6379> acl setuser adduser resetkeys ~testget:*
OK
127.0.0.1:6379> acl list
1) "user adduser on #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~testget:* resetchannels -@all +@string +hset -set +hlen +ttl"
2) "user default on nopass ~* &* +@all"

# 验证
127.0.0.1:6379> auth adduser 111
OK
127.0.0.1:6379> get name
(error) NOPERM this user has no permissions to access one of the keys used as arguments
127.0.0.1:6379> get testget:1
(nil)

ACL持久化

以上示例的设置均为保存在redis内存中,若redis重启,那么这些设置会全部失效,若想持久化需保存成文件,分为两个步骤:

  第一步:在redis文件中设置要导出的ACL配置文件全路径名,ACL配置文件必须以.acl结尾

aclfile /home/redis6/users.acl

注:此处必须保证文件存在,可以使用touch命令来提前创建文件,不指定会报错:
(error) ERR This Redis instance is not configured to use an ACL file. You may want to specify users via the ACL SETUSER command and then issue a CONFIG REWRITE (assuming you have a Redis configuration file set) in order to store users in the Redis configuration.

  第二步:执行 acl save

acl save

示例

redis的镜像中并没有redis.conf配置文件,所以需要自己写配置文件挂载到容器目录中,这里举一个简单的redis.conf示例:

bind 0.0.0.0
port 6379
aclfile /opt/auth.acl

  步骤:

# 创建auth.acl文件
cd /opt
touch auth.acl

# 重启后 acl配置全部没有了
127.0.0.1:6379> acl list
1) "user default on nopass ~* &* +@all"

# 重新创建用户 给权限
127.0.0.1:6379> acl setuser adduser
OK
127.0.0.1:6379> acl list
1) "user adduser off resetchannels -@all"
2) "user default on nopass ~* &* +@all"
127.0.0.1:6379> acl setuser adduser >111
OK
127.0.0.1:6379> acl list
1) "user adduser off #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae resetchannels -@all"
2) "user default on nopass ~* &* +@all"
127.0.0.1:6379> acl setuser adduser ~* +@string
OK
127.0.0.1:6379> acl list
1) "user adduser off #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~* resetchannels -@all +@string"
2) "user default on nopass ~* &* +@all"
127.0.0.1:6379> acl setuser adduser +ttl +hset +hlen
OK
127.0.0.1:6379> acl list
1) "user adduser off #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~* resetchannels -@all +@string +hset +hlen +ttl"
2) "user default on nopass ~* &* +@all"
127.0.0.1:6379> acl setuser adduser resetkeys ~testget:*
OK
127.0.0.1:6379> acl list
1) "user adduser off #f6e0a1e2ac41945a9aa7ff8a8aaa0cebc12a3bcc981a929ad5cf810a090e11ae ~testget:* resetchannels -@all +@string +hset +hlen +ttl"
2) "user default on nopass ~* &* +@all"

# 持久化保存
acl save

### 坑:
### 在执行acl save时会报错
### ERR There was an error trying to save the ACLs. Please check the server logs for more information
### 查看日志:
### Opening temp ACL file for ACL SAVE: Permission denied
### 赋予权限后:
### Renaming ACL file for ACL SAVE: Device or resource busy
### 解决方案:
### 因为docker启动redis没有redis.conf文件,所以需要自己写一个然后挂载到docker中
### 在自定义redis.conf时,先把 aclfile 这一行注释掉,或者先不写
### 创建完容器后,在容器内,存放aclfile的路径下,touch一个.acl文件出来
### 然后停止容器,将conf文件中aclfile一行解开注释,或者添加一行,再重新启动容器
### 这时进入redis-cli中执行acl save就可以了


# 加载acl文件
acl load

保存到.acl文件后,下次启动redis时,会自动加载conf配置文件中的acl文件路径生成角色权限