管理角色和特权

管理角色和特权

Greenplum数据库的授权机制在数据库中存储角色以及访问数据库对象的权限,并且使用SQL语句或者命令行工具来管理它们。

Greenplum数据库使用角色管理数据库访问权限。角色的概念把用户的概念包括在内。一个角色可能是一个数据库用户、一个组或者两者兼具。角色可以拥有数据库对象(例如表)并且可以那些对象上的特权分配给其他角色来控制对对象的访问。角色可以是其他角色的成员,因此一个成员角色能够继承其父角色的对象特权。

每一个Greenplum数据库系统都包含一组数据库角色(用户和组)。这些角色与服务器所属的操作系统管理的用户和组相互独立。不过,为了便于维护操作系统用户名和Greenplum数据库角色名之间的关系,有很多客户端应用使用当前的操作系统用户名作为默认。

在Greenplum数据库中,用户通过Master实例登入并且连接,Master实例接着会验证它们的角色以及访问特权。然后Master在幕后以当前登入的角色发送命令给Segment实例。

角色被定义在系统层面上,这意味着它们对系统中所有的数据库都有效。

为了让Greenplum数据库系统自举,一个刚初始化好的系统总是有一个预定义的超级用户角色(也被称为系统用户)。这个角色的名称和初始化Greenplum数据库系统的操作系统用户相同。习惯上,这个角色被命名为gpadmin。为了创建更多角色,用户首先必须作为这个初始角色连接。

角色和特权的安全性最佳实践

  • 保护gpadmin系统用户。 Greenplum要求一个UNIX用户ID来安装和初始化Greenplum数据库系统。这个系统用户在Greenplum文档中被称为gpadmin。这个gpadmin用户是Greenplum数据库中的默认数据库超级用户,也是Greenplum安装及其底层数据文件的文件系统拥有者。这个默认管理员账户是Greenplum数据库设计的基石。系统的运行少不了它,并且没有办法限制这个gpadmin用户ID的访问。使用角色来管理谁能为特定目的访问数据库。用户只应使用gpadmin账户进行扩展和升级等系统维护任务。任何以这个用户ID登录到一台Greenplum主机的人可以读取、修改或者删除任意数据,包括系统目录数据和数据库访问权限。因此,保护gpadmin用户ID并且只对核心系统管理员提供访问非常重要。只有在执行特定的系统维护任务(例如升级或扩展)时,管理员才应该作为gpadmin登入到Greenplum。数据库用户应该永不作为gpadmin登录,并且ETL或生产负载也应该永不作为gpadmin运行。
  • 对每个登入的用户分配一个独特的角色。 出于登录和审计目的,每个被允许登入Greenplum数据库的用户应该被给予它们自己的数据库角色。对于应用或Web服务,考虑为每个应用或服务创建一个独特的角色。请见创建新角色(用户)
  • 使用组来管理访问特权。 请见角色的成员关系
  • 限制拥有SUPERUSER角色属性的用户。 是超级用户的角色可以绕过Greenplum数据库中的所有访问特权检查以及资源队列。只有系统管理员才应该被给予超级用户权利。请见修改角色属性

创建新角色(用户)

一个用户级的角色被认为是能够登入数据库并且发起数据库会话的数据库角色。因此,在使用CREATE ROLE命令创建一个新的用户级角色时,必须指定LOGIN特权。例如:

=# CREATE ROLE jsmith WITH LOGIN;

数据库角色可以有若干属性,它们定义角色可以在数据库中执行哪些任务。可以在创建角色时设置这些属性,或者在以后用ALTER ROLE命令来设置。用户可以设置的角色属性的描述可见表 1

修改角色属性

数据库角色可以有若干属性定义角色可以在数据库中执行哪些任务。

表 1. 角色属性
属性 描述
SUPERUSER | NOSUPERUSER 决定角色是否为一个超级用户。要创建一个新的超级用户,用户本身必须是超级用户。NOSUPERUSER是默认值。
CREATEDB | NOCREATEDB 决定该角色是否被允许创建数据库。NOCREATEDB是默认值。
CREATEROLE | NOCREATEROLE 决定该角色是否被允许创建和管理其他角色。NOCREATEROLE是默认值。
INHERIT | NOINHERIT 决定一个角色是否从它的父角色继承特权。一个带有INHERIT属性的角色可以自动地使用授予给其所有直接父角色以及间接父角色的任何数据库特权。INHERIT是默认值。
LOGIN | NOLOGIN 决定一个角色是否被允许登入。一个带有LOGIN属性的角色可以被认为是一个用户。没有这个属性的角色对于管理数据库特权有用(组)。NOLOGIN是默认值。
CONNECTION LIMIT connlimit 如果角色能够登入,这指定该角色能建立多少并发连接。-1(默认)表示没有限制。
CREATEEXTTABLE | NOCREATEEXTTABLE 决定一个角色是否被允许创建外部表。NOCREATEEXTTABLE是默认值。对于一个带有CREATEEXTTABLE属性的角色,默认的外部表类型readable,而默认的协议gpfdist。注意使用fileexecute协议的外部表只能由超级用户创建。
PASSWORD 'password' 设置角色的口令。如果没有计划使用口令认证则可以省略这个选项。如果没有指定口令,口令将被设置为空并且该用户的口令认证总是会失败。也可以有选择地使用PASSWORD NULL显式地写入一个空口令。
ENCRYPTED | UNENCRYPTED 控制新口令是否在pg_authid系统目录中存储为一个哈希字符串。如果既没有指定ENCRYPTED也没有指定UNENCRYPTED,默认行为由password_encryption配置参数决定,这个参数默认是on

如果提供的password字符串已经是哈希过的格式,就会原样存储,而不管指定的是ENCRYPTED还是UNENCRYPTED

有关保护登录口令的额外信息请见在Greenplum数据库中保护口令

VALID UNTIL 'timestamp' 设置一个日期和时间,在此之后该角色的口令不再有效。如果省略,则口令将会永久有效。
RESOURCE QUEUE queue_name 为负载管理的目的将角色分配到提及的资源队列。然后该角色发出的任何语句都服从于该资源队列的限制。注意RESOURCE QUEUE属性不会被继承,必须在每个用户级(LOGIN)角色上设置它。
DENY {deny_interval | deny_point} 在一个间隔期间限制访问,用日或者日和时间指定。更多信息请见基于时间的认证

在创建角色时可以设置这些属性,或者之后用ALTER ROLE命令设置。例如:

=# ALTER ROLE jsmith WITH PASSWORD 'passwd123';
=# ALTER ROLE admin VALID UNTIL 'infinity';
=# ALTER ROLE jsmith LOGIN;
=# ALTER ROLE jsmith RESOURCE QUEUE adhoc;
=# ALTER ROLE jsmith DENY DAY 'Sunday';

对于很多服务器配置设置,角色也可以有角色相关的默认值。例如,要为一个角色设置默认的方案搜索路径:

=# ALTER ROLE admin SET search_path TO myschema, public;

角色的成员关系

将用户组织在一起以简化对象特权的管理常常会很方便:那样,特权可以被授予给一个组整体或者从一个组整体收回。在Greenplum数据库中通过创建一个表示组的角色然后然后把这个组角色的成员关系授予给个别用户角色来实现这一点。

使用SQL命令CREATE ROLE来创建一个新的组角色。例如:

=# CREATE ROLE admin CREATEROLE CREATEDB;

一旦组角色存在,用户就可以使用GRANTREVOKE命令增加和移除成员(用户角色)。例如:

=# GRANT admin TO john, sally;
=# REVOKE admin FROM bob;

为了管理对象特权,用户接着会把适当的权限只授予给组级别的角色(见表 2)。然后成员用户角色会继承这个组角色的对象特权。例如:

=# GRANT ALL ON TABLE mytable TO admin;
=# GRANT ALL ON SCHEMA myschema TO admin;
=# GRANT ALL ON DATABASE mydb TO admin;

角色属性LOGINSUPERUSERCREATEDBCREATEROLECREATEEXTTABLE以及RESOURCE QUEUE绝不会像数据库对象上的普通特权那样被继承。为了使用这些属性之一,用户成员必须实际地SET ROLE到一个具有该属性的特定角色。在上面的例子中,我们把CREATEDBCREATEROLE给了admin角色。如果sallyadmin的成员,她能够发出下列命令来夺取其父角色的角色属性:

=> SET ROLE admin;

管理对象特权

当一个对象(表、视图、序列、数据库、函数、语言、方案或者表空间)被创建时,它会被分配一个拥有者。拥有者通常是执行创建语句的角色。对于大部分类型的对象,初始状态是只有拥有者(或者超级用户)可以对该对象做任何事情。要允许其他角色使用它,必须授予特权。Greenplum数据库对每种对象类型支持下列特权:

表 2. 对象特权
对象类型 特权
表、视图、序列 SELECT

INSERT

UPDATE

DELETE

RULE

ALL

外部表 SELECT

RULE

ALL

数据库 CONNECT

CREATE

TEMPORARY | TEMP

ALL

函数 EXECUTE
过程语言 USAGE
方案 CREATE

USAGE

ALL

自定义协议 SELECT

INSERT

UPDATE

DELETE

RULE

ALL

注意: 特权必须被个别地授予给每个对象。例如,在一个数据库上授予ALL并不会授予对该数据库中对象的完全访问。它只授予所有数据库级别的特权(CONNECTCREATETEMPORARY)给数据库本身。

使用SQL命令GRANT在一个对象上给予一个指定的角色特权。例如:

=# GRANT INSERT ON mytable TO jsmith;

要收回特权,使用REVOKE命令。例如:

=# REVOKE ALL PRIVILEGES ON mytable FROM jsmith;

还可以使用DROP OWNEDREASSIGN OWNED命令来管理弃用角色拥有的对象(注意:只有对象的拥有者或者超级用户才能删除对象或者重新分配所有权)。例如:

=# REASSIGN OWNED BY sally TO bob;
=# DROP OWNED BY visitor;

模拟行和列级访问控制

不支持行级或者列级访问控制,也不支持标记安全性。可以使用视图来限制被选择的列或行来模拟行级和列级访问。可以对表增加一个额外的列来存储敏感度信息以模拟行级标签,然后使用视图基于这一列来控制行级访问。然后可以为角色授予这些视图的访问而不是基表的访问。

加密数据

Greenplum数据库包括一个可选的加密/解密函数包,名为pgcryptopgcrypto函数允许数据库管理员以加密的形式存储特定列的数据。这增加了一个额外的层来保护敏感数据,因为以加密形式存储在Greenplum数据库中的数据不能被任何没有加密密钥的人读取,也不能被直接从磁盘读取。

注意: pgcrypto函数在数据库服务器内部运行,这意味着所有的数据和口令会以明文在pgcrypto和客户端应用之前移动。为了最好的安全性,也可考虑在客户端和Greenplum的Master服务器之间使用SSL连接。
要使用pgcrypto函数,在想要使用这种能力来查询其他数据库的每个数据库中安装脚本$GPHOME/share/postgresql/contrib/pgcrypto.sql
$ psql -d testdb -f $GPHOME/share/postgresql/contrib/pgcrypto.sql

更多有关个体函数的信息请见PostgreSQL文档中的pgcrypto

在Greenplum数据库中保护口令

在默认的配置中,Greenplum数据库在pg_authid中保存登录用户的口令的MD5哈希,而不是保存明文口令。任何能够查看pg_authid表的用户都能看到哈希字符串但是看不到口令。这也确保当数据库被转储到备份文件中时口令是模糊的。

在通过下列命令之一设置口令时会执行哈希函数:
  • CREATE USER name WITH ENCRYPTED PASSWORD 'password'
  • CREATE ROLE name WITH LOGIN ENCRYPTED PASSWORD 'password'
  • ALTER USER name WITH ENCRYPTED PASSWORD 'password'
  • ALTER ROLE name WITH ENCRYPTED PASSWORD 'password'

password_encryption系统配置参数为on(这是默认值)时,ENCRYPTED关键字可以被省略。password_encryption配置参数决定ENCRYPTEDUNENCRYPTED在命令中不存在时是存储明文口令还是哈希口令。

注意: SQL命令语法和password_encryption配置变量包括术语加密,但是口令技术上并未被加密。它们是被哈希,因此不能被解密。

哈希在串接起来的明文口令和角色名上计算。MD5哈希产生一个前缀有字符md5的32字节的十六进制字符串。哈希过的口令被保存在pg_authid系统表的rolpassword列中。

尽管不被推荐,通过在命令中包括UNENCRYPTED关键词或者将password_encryption配置变量设置为off,口令可以以明文被保存在数据库中。注意改变配置值对现有的口令无效,它只对新创建的或者更新的口令有效。

要全局地设置password_encryption,在shell中作为gpadmin用户执行这些命令:
$ gpconfig -c password_encryption -v 'off'
$ gpstop -u
要在一个会话中设置password_encryption,使用SQL命令SET
=# SET password_encryption = 'on';

可以使用SHA-256哈希算法而不是MD5哈希算法对口令进行哈希。该算法产生一个前缀有字符sha256的64字节十六进制字符串。

注意:

尽管SHA-256使用了一种更强的加密算法并且产生更长的哈希字符串,但它不能被用于MD5认证方法。要使用SHA-256口令哈希,认证方法必须在pg_hba.conf配置文件中被设置为password,以便明文口令被发送给Greenplum数据库。因为明文口令会被通过网络发送,在使用SHA-256时使用SSL非常重要。在另一方面,默认的md5认证方法会在口令发送到Greenplum数据库之前会哈希口令两次,一次在口令和角色名上,接下来再用客户端和服务器之间共享的salt值哈希,因此明文口令绝不会在网络上发送。

为了启用SHA-256哈希,将password_hash_algorithm配置参数从其默认值md5改为sha-256。该参数可以在全局层面上或者会话级别上设置。要在全局上设置password_hash_algorithm,在一个shell中以gpadmin用户执行这些命令:
$ gpconfig -c password_hash_algorithm -v 'sha-256'
$ gpstop -u
要在一个会话中设置password_hash_algorithm,使用SQL命令SET
=# SET password_hash_algorithm = 'sha-256';

基于时间的认证

Greenplum数据库允许管理员限制角色在特定时间的访问。使用CREATE ROLE或者ALTER ROLE命令来指定基于时间的约束。

详情请参考Greenplum数据库安全性配置指南