配置数据库授权
描述如何通过使用角色和权限在用户级别限制对数据库数据的授权访问。
Parent topic: 安全性配置指南
访问权限和角色
Greenplum数据库使用角色管理数据库访问权限。角色的概念包括了用户和组的概念。一个角色可以是一个数据库用户、组或者两者皆有。角色可以拥有数据库对象(例如表)并且可以把那些对象上的特权指派给其他角色以控制对那些对象的访问。角色可以是其他角色的成员,因此成员角色可以继承其父角色的对象特权。
每一个Greenplum数据库系统都包含一组数据库角色(用户和组)。那些角色独立于服务器所运行的操作系统管理的用户和组。不过,为了方便用户可能想要维护操作系统用户名和Greenplum数据库角色名之间的关系,因为很多客户端应用使用当前的操作系统用户名作为默认的数据库用户名。
在Greenplum数据库中,用户通过Master实例登入和连接,Master实例会验证它们的角色和访问特权。然后Master将在幕后用当前登入的角色向Segment实例发出命令。
角色被定义在系统层面上,因此它们对系统中的所有数据库都有效。
要让Greenplum数据库系统自举,刚刚初始化好的系统总是包含一个预定义的超级用户角色(也被称作系统该用户)。这个角色将和初始化Greenplum数据库系统的操作系统用户具有相同的名称。习惯上,这个角色被命名为gpadmin。要创建更多角色,用户首先必须作为这个初始角色连接。
管理对象特权
当一个对象(表、视图、序列、数据库、函数、语言、方案或表空间)被创建时,它会被指派一个拥有者。拥有者通常就是执行创建语句的角色。对于大部分种类的对象,初始状态只有拥有者(或者超级用户)可以对该对象做任何事情。要允许其他角色使用对象,必须授予特权。对每一类对象,Greenplum数据库支持下面的特权:
对象类型 | 特权 |
---|---|
表、视图、序列 |
|
外部表 |
|
数据库 |
|
函数 | EXECUTE |
Procedural Languages | USAGE |
方案 |
|
特权必须为每个对象单独授予。例如,在一个数据库上授予ALL并不会为该数据库中的对象授予完全的访问。它只授予所有的数据库级别特权(CONNECT, CREATE, TEMPORARY)给数据库本身。
使用SQL命令GRANT把对象上的特权给一个特定角色。例如:
=# GRANT INSERT ON mytable TO jsmith;
T要收回特权,可使用REVOKE命令。例如:
=# REVOKE ALL PRIVILEGES ON mytable FROM jsmith;
用户还可以使用DROP OWNED以及REASSIGN OWNED命令来管理弃用角色所拥有的对象(注意:只有对象的拥有者或者超级用户可以删除一个对象或者重新指派拥有关系)。例如:
=# REASSIGN OWNED BY sally TO bob;
=# DROP OWNED BY visitor;
使用SHA-256加密
Greenplum数据库的访问控制大概能对应桔皮书的“C2”级安全性,而不是“B1”级。Greenplum数据库当前支持对象级别的访问特权。行级或者列级访问不被支持,标记安全性也不被支持。
行级和列级访问可以使用限制被选择的行列的视图来模拟。行级标签可以通过为表增加存储敏感度信息的额外列模拟,然后使用视图来控制基于该列的行级访问。然后可以为角色授予对视图的访问而不是对基表的访问。虽然这些变通方案不能提供和“B1”级安全性相同的安全性,但对于很多组织来说它们仍然是一种可行的替代方案。
要使用SHA-256加密,用户必须在系统或者会话级别上设置一个参数。这一节介绍如何使用一个服务器参数来实现SHA-256加密的口令存储。注意为了使用SHA-256加密进行存储,客户端认证方法必须被设置为password而不是默认的MD5(详见 配置SSL客户端连接)。这意味着口令在网络上以明文方式传输,因此我们高度推荐用户设置SSL来加密客户端和服务器之间的通信信道。
用户可以在系统范围或者以会话为基础设置选择的加密方法。可用的加密方法是SHA-256以及MD5(为了向后兼容性)。
在系统范围设置加密方法
要在整个Greenplum系统(Master及其Segment)上设置password_hash_algorithm服务器参数:
- 作为超级用户登入Greenplum数据库实例。
执行gpconfig把password_hash_algorithm设置为SHA-256:
$ gpconfig -c password_hash_algorithm -v 'SHA-256'
验证设置:
$ gpconfig -s
将看到:
Master value: SHA-256
Segment value: SHA-256
为单个会话设置加密方法
要为单个会话设置password_hash_algorithm服务器参数:
- 作为超级用户登入Greenplum数据库实例。
设置password_hash_algorithm为SHA-256:
# set password_hash_algorithm = 'SHA-256'
验证设置:
# show password_hash_algorithm;
将会看到:
SHA-256
下面是展示新设置效果的例子:
作为超级用户登入并且验证口令哈希算法设置:
# show password_hash_algorithm
password_hash_algorithm
-------------------------------
SHA-256
创建一个带有口令且有登录特权的新角色。
create role testdb with password 'testdb12345#' LOGIN;
更改客户端认证方法以允许SHA-256加密口令的存储:
在Master上打开pg_hba.conf文件并且加入下面的行:
host all testdb 0.0.0.0/0 password
重启集群。
作为刚创建好的用户testdb登入数据库。
psql -U testdb
在提示下输入正确的口令。
验证口令被存储为SHA-256哈希。
口令的哈希被存储在pg_authid.rolpasswod中。
作为超级用户登入。
执行下列查询:
# SELECT rolpassword FROM pg_authid WHERE rolname = 'testdb';
Rolpassword
-----------
sha256<64 hexadecimal characters>
用时间限制访问
Greenplum数据库让管理员能够限制角色在特定时间的访问。可使用CREATE ROLE或者ALTER ROLE命令指定基于时间的约束。
可以用日期或者日期和时间限制访问。无需删除和重建角色就可以移除这些约束。
基于时间的约束只适用于它们指派给的角色。如果角色是另一个有时间约束的角色的成员,时间约束不会被继承。
基于时间的约束仅在登录时被实施。SET ROLE以及SET SESSION AUTHORIZATION命令不受任何基于时间的约束的影响。
要为角色设置基于时间的约束,要求超级用户或者CREATEROLE特权。没有人可以为超级用户增加基于时间的约束。
有两种方法增加基于时间的约束。在CREATE ROLE或者ALTER ROLE命令中使用关键词DENY,后面接上下面的一种形式:。
- 访问被限制的一个日子,以及可选的时间。例如,在周三不能访问。
- 一个区间——也就是一个开始日期和结束日期以及可选的时间——在其间访问被限制。例如,从周三下午10点到周四上午8点期间不能访问。
用户可以指定多个限制,例如,周三的任何时间都不能访问并且在周五的下午3点到5点之间不能访问。
有两种方法指定一个日子。使用后面跟着带单引号的英语中平日术语的DAY或者0到6之间的一个数字,如下表所示。
英语术语 | 数字 |
---|---|
DAY ‘Sunday’ | DAY 0 |
DAY ‘Monday’ | DAY 1 |
DAY ‘Tuesday’ | DAY 2 |
DAY ‘Wednesday’ | DAY 3 |
DAY ‘Thursday’ | DAY 4 |
DAY ‘Friday’ | DAY 5 |
DAY ‘Saturday’ | DAY 6 |
日子中的时间可以以12小时制或者24小时制指定。在词TIME后面接上带单引号的说明。只能指定小时和分钟并且用分号分隔(:)。如果使用12小时制,在最后加上AM或者PM。下面的例子展示了多种时间说明。
TIME '14:00' # 24-hour time implied
TIME '02:00 PM' # 12-hour time specified by PM
TIME '02:00' # 24-hour time implied. This is equivalent to TIME '02:00 AM'.
Important: 基于时间的约束根据服务器时间实施。不考虑时区。
要指定一个时间区间,在其间访问被禁止,可以用词BETWEEN和AND指定两个日子/时间说明。如下所示。DAY总是需要的。
BETWEEN DAY 'Monday' AND DAY 'Tuesday'
BETWEEN DAY 'Monday' TIME '00:00' AND
DAY 'Monday' TIME '01:00'
BETWEEN DAY 'Monday' TIME '12:00 AM' AND
DAY 'Tuesday' TIME '02:00 AM'
BETWEEN DAY 'Monday' TIME '00:00' AND
DAY 'Tuesday' TIME '02:00'
DAY 2 TIME '02:00'
最后三个语句等效。
Note: 区间不能在周六之后回卷。
下面的语法不正确:
DENY BETWEEN DAY 'Saturday' AND DAY 'Sunday'
正确的说明是使用两个DENY子句,如下所示:
DENY DAY 'Saturday'
DENY DAY 'Sunday'
下面的例子展示了创建带有基于时间约束的角色并且修改角色以增加基于时间的约束。只有基于时间约束所需的语句被显示。更多有关创建和修改角色的细节请见 Greenplum数据库参考指南中CREATE ROLE 和 ALTER ROLE的描述。
例 1 – 创建带有基于时间约束的新角色
在周末不允许访问。
CREATE ROLE generaluser
DENY DAY 'Saturday'
DENY DAY 'Sunday'
...
例 2 – 修改角色以增加基于时间的约束
每晚的凌晨2点到4点之间不允许访问。
ALTER ROLE generaluser
DENY BETWEEN DAY 'Monday' TIME '02:00' AND DAY 'Monday' TIME '04:00'
DENY BETWEEN DAY 'Tuesday' TIME '02:00' AND DAY 'Tuesday' TIME '04:00'
DENY BETWEEN DAY 'Wednesday' TIME '02:00' AND DAY 'Wednesday' TIME '04:00'
DENY BETWEEN DAY 'Thursday' TIME '02:00' AND DAY 'Thursday' TIME '04:00'
DENY BETWEEN DAY 'Friday' TIME '02:00' AND DAY 'Friday' TIME '04:00'
DENY BETWEEN DAY 'Saturday' TIME '02:00' AND DAY 'Saturday' TIME '04:00'
DENY BETWEEN DAY 'Sunday' TIME '02:00' AND DAY 'Sunday' TIME '04:00'
...
例 3 – 修改角色以增加基于时间的约束
在周三或者周五下午的3点到5点间不允许访问。
ALTER ROLE generaluser
DENY DAY 'Wednesday'
DENY BETWEEN DAY 'Friday' TIME '15:00' AND DAY 'Friday' TIME '17:00'
删除基于时间的约束
要移除基于时间的约束,请使用ALTER ROLE命令。输入后面跟着要删除的日子/时间说明的关键词DROP DENY FOR。
DROP DENY FOR DAY 'Sunday'
任何含有DROP子句中全部或者部分条件的约束都会被移除。例如,如果一条现有的约束否定周一和周二的访问,并且DROP子句移除周一的约束,则这一条现有的约束会被完全删除。DROP子句会完全移除所有与DROP子句中约束交叠的约束。即便发生交叠的约束包含有比DROP子句更多的限制,它们也会被完全删除。
例 1 - 从一个角色移除一条基于时间的限制
ALTER ROLE generaluser
DROP DENY FOR DAY 'Monday'
...
这个语句将为例2中的generaluser角色移除所有与周一约束交叠的约束,即便其中有额外的约束。