1.role和权限
Greenplum数据库使用roles管理数据库访问权限。角色的概念包含用户和组的概念。 一个角色可以是一个数据库用户、一个数据库组或者两者间距。角色可以拥有数据库对象(例如表),并可以将这些对象上的权限赋予其他角色,依此来控制对对象的访问。角色可以是其他角色的成员,因此成员角色可以继承其父角色的对象权限。
1.1.角色和权限的安全最佳实践
- Greenplum数据库使用roles管理数据库访问权限。角色的概念包含用户和组的概念。一个角色可以是一个数据库用户、一个数据库组或者两者间距。角色可以拥有数据库对象(例如表),并可以将这些对象上的权限赋予其他角色,依此来控制对对象的访问。角色可以是其他角色的成员,因此成员角色可以继承其父角色的对象权限。
- 为登录的每个用户分配不同的角色。为了记录和审计,允许每个允许登录Greenplum数据库的用户拥有自己的数据库角色。对于应用程序或Web服务,考虑为每个应用程序或服务创建不同的角色。
- 使用组来管理访问权限。
- 限制具有SUPERUSER角色属性的用户
1.2.角色的属性
属性 | 描述 |
---|---|
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属性的角色,默认外部表类型是可读的,注意使用文件或执行的外部表只能由超级用户创建。 |
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} | 限制时间间隔期间的访问,按日期或日期时间指定 |
1.3.角色的继承性
角色属性LOGIN、SUPERUSER、CREATEDB、CREATEROLE、CREATEEXTTABLE和RESOURCEQUEUE永远不会像数据库对象上的普通权限那样被继承。用户成员实际上必须SET ROLE具有这些属性的特定角色,才能使用该属性。
1.4.对象权限
对象类型 | 权限 |
---|---|
表、视图、序列 | SELECT INSERT UPDATE DELETE RULE ALL |
外部表 | SELECT RULE ALL |
数据库 | CONNECT CREATE TEMPORARY |
函数 | EXECUTE |
过程语言 | USAGE |
模式 | CREATE USAGE ALL |
自定义协议 | SELECT INSERT UPDATE DELETE RULE ALL |
对象权限对象类型权限表、视图、序列SELECTINSERTUPDATEDELETERULEALL外部表SELECTRULEALL数据库CONNECTCREATETEMPORARY|TEMPALL函数EXECUTE过程语言USAGE模式CREATEUSAGEALL自定义协议SELECTINSERTUPDATEDELETERULEALLNote:您必须单独为每个对象授予权限。例如,授予数据库上ALL权限,并不授予对该数据库中的对象的完全访问权限。它只授予数据库级别的(CONNECT、CREATE、TEMPORARY)到数据库本身的权限。
1.5.用户和角色区别
角色概念把用户(user)和组(group)的概念包括在内。一个角色可能是一个数据库用户、一个组或者两者兼具。角色可以拥有数据库对象(例如表)并且可以那些对象上的特权分配给其他角色来控制对对象的访问。角色可以是其他角色的成员,因此一个成员角色能够继承其父角色的对象特权。
每一个Greenplum数据库系统都包含一组数据库角色(用户和组)。这些角色与服务器所属的操作系统管理的用户和组相互独立。不过,为了便于维护操作系统用户名和Greenplum数据库角色名之间的关系,有很多客户端应用使用当前的操作系统用户名作为默认。
在Greenplum数据库中,用户通过Master实例登入并且连接,Master实例接着会验证它们的角色以及访问特权。然后Master在幕后以当前登入的角色发送命令给Segment实例。
角色被定义在系统层面上,这意味着它们对系统中所有的数据库都有效。
为了让Greenplum数据库系统自举,一个刚初始化好的系统总是有一个预定义的超级用户角色(也被称为系统用户)。这个角色的名称和初始化Greenplum数据库系统的操作系统用户相同。习惯上,这个角色被命名为gpadmin。为了创建更多角色,用户首先必须作为这个初始角色连接。
在greenplum后续版本中,已经将使用role取代了user,所以创建用户就是 create role: role可以分为登录角色和组角色, CREATE ROLE创建的用户默认不带LOGIN属性,而CREATE USER创建的用户默认带有LOGIN属性 Greenplum数据库不支持行级访问或行级标记的安全性。可以使用视图来限制所选行的行来模拟行级访问。
1.6.角色的成员关系
将用户组织在一起以简化对象特权的管理常常会很方便:那样,特权可以被授予给一个组整体或者从一个组整体收回。在Greenplum数据库中通过创建一个表示组的角色,然后然后把这个组角色的成员关系授予给个别用户角色来实现这一点。
使用SQL命令CREATE ROLE来创建一个新的组角色。例如:
代码语言:javascript复制=# CREATE ROLE admin CREATEROLE CREATEDB;
一旦组角色存在,用户就可以使用GRANT和REVOKE命令增加和移除成员(用户角色)。例如:
代码语言:javascript复制=# GRANT admin TO john, sally;
=# REVOKE admin FROM bob;
为了管理对象特权,用户接着会把适当的权限只授予给组级别的角色。然后成员用户角色会继承这个组角色的对象特权。例如:
代码语言:javascript复制=# GRANT ALL ON TABLE mytable TO admin;
=# GRANT ALL ON SCHEMA myschema TO admin;
=# GRANT ALL ON DATABASE mydb TO admin;
角色属性LOGIN、SUPERUSER、CREATEDB、CREATEROLE、CREATEEXTTABLE以及RESOURCE QUEUE绝不会像数据库对象上的普通特权那样被继承。为了使用这些属性之一,用户成员必须实际地SET ROLE到一个具有该属性的特定角色。在上面的例子中,我们把CREATEDB和CREATEROLE给了admin角色。如果sally是admin的成员,她能够发出下列命令来夺取其父角色的角色属性:
代码语言:javascript复制=> SET ROLE admin;
这样用户sally将拥有admin用户的所有权限。在执行一段时间之后,如果仍然希望将该会话恢复为原有权限,可以使用下列恢复方式之一:
代码语言:javascript复制SET ROLE sally;
SET ROLE NONE;
RESET ROLE;
要删除一个组角色,执行DROP ROLE group_role命令即可。然而在删除该组角色之后,它与其成员角色之间的关系将被立即撤销(成员角色本身不会受影响)。不过需要注意的是,在删除之前,任何属于该组角色的对象都必须先被删除或者将对象的所有者赋予其它角色,与此同时,任何赋予该组角色的权限也都必须被撤消。
2.管理对象特权
当一个对象(表、视图、序列、数据库、函数、语言、方案或者表空间)被创建时,它会被分配一个拥有者。拥有者通常是执行创建语句的角色。对于大部分类型的对象,初始状态是只有拥有者(或者超级用户)可以对该对象做任何事情。要允许其他角色使用它,必须授予特权。Greenplum数据库对每种对象类型支持下列特权(可通过h grant或h revoke查看):
对象类型 | 特权 |
---|---|
表、视图、序列 | 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并不会授予对该数据库中对象的完全访问。它只授予所有数据库级别的特权(CONNECT、CREATE、TEMPORARY)给数据库本身。
使用SQL命令GRANT在一个对象上给予一个指定的角色特权。例如:
代码语言:javascript复制=# GRANT INSERT ON mytable TO jsmith;
要收回特权,使用REVOKE命令。例如:
代码语言:javascript复制=# REVOKE ALL PRIVILEGES ON mytable FROM jsmith;
还可以使用DROP OWNED和REASSIGN OWNED命令来管理弃用角色拥有的对象(注意:只有对象的拥有者或者超级用户才能删除对象或者重新分配所有权)。例如:
代码语言:javascript复制=# REASSIGN OWNED BY sally TO bob;
=# DROP OWNED BY visitor;
3.行和列级访问控制
不支持行级或者列级访问控制,也不支持标记安全性。可以使用视图来限制被选择的列或行来模拟行级和列级访问。可以对表增加一个额外的列来存储敏感度信息以模拟行级标签,然后使用视图基于这一列来控制行级访问。然后可以为角色授予这些视图的访问而不是基表的访问。
4.加密数据
Greenplum数据库包括一个可选的加密/解密函数包,名为pgcrypto。pgcrypto函数允许数据库管理员以加密的形式存储特定列的数据。这增加了一个额外的层来保护敏感数据,因为以加密形式存储在Greenplum数据库中的数据不能被任何没有加密密钥的人读取,也不能被直接从磁盘读取。
代码语言:javascript复制pgcrypto函数在数据库服务器内部运行,这意味着所有的数据和口令会以明文在pgcrypto和客户端应用之前移动。为了最好的安全性,也可考虑在客户端和Greenplum的Master服务器之间使用SSL连接。 要使用pgcrypto函数,在想要使用这种能力来查询其他数据库的每个数据库中安装脚本$GPHOME/share/postgresql/contrib/pgcrypto.sql:
$ psql -d testdb -f $GPHOME/share/postgresql/contrib/pgcrypto.sql
5.基于时间的认证
Greenplum数据库允许管理员限制角色在特定时间的访问。使用CREATE ROLE或者ALTER ROLE命令来指定基于时间的约束。
访问限制可以控制到具体时间点。时间约束仅仅对于设置的Role有效。
- 需要的权限 SUPERUSER或者CREATEROLE权限是必须的。
- 如何添加时间约束 在CREATE ROLE或者ALTER ROLE的时候使用DENY关键字来实现:
- 某天或者某个时间访问限制;
- 一个有开始时间和结束时间的访问控制
- 指明日期和时间 TIME ‘14:00’ (24小时格式的时间) TIME ‘02:00 PM’ (12小时格式的时间) TIME ‘02:00’ (24小时格式的时间) 等价于 TIME ‘02:00 AM’.
如何添加时间约束?
指定时间间隔 通过 BETWEEN 和 AND 关键字连接两个日期/时间。
代码语言:javascript复制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'
BETWEEN DAY 1 TIME '00:00' AND DAY 2 TIME '02:00'
注意:日期间隔不能跨 Saturday(周六)
代码语言:javascript复制Incorrect: DENY BETWEEN DAY 'Saturday' AND DAY 'Sunday'
删除时间约束,原则:有交集即移出
代码语言:javascript复制ALTER ROLE dylan DROP DENY FOR DAY ‘Monday’;
6.配置客户端认证
在Greenplum数据库系统第一次被初始化时,系统含有一个预定义的超级用户角色。这个角色将具有与初始化该Greenplum数据库系统的操作系统用户相同的名称。这个角色被称作gpadmin。默认情况下,系统被配置为只允许来自gpadmin角色的对数据库的本地连接。如果用户想要允许任
- 允许到Greenplum数据库的连接
- 编辑pg_hba.conf文件
- 认证方法
- 限制并发连接
- 加密客户端/服务器连接
允许到Greenplum数据库的连接
客户端访问和认证受到配置文件pg_hba.conf(标准的PostgreSQL基于主机认证文件)的控制。
在Greenplum数据库中,Master实例的pg_hba.conf文件控制着对Greenplum系统的客户端访问和认证。Segment也有自己的pg_hba.conf文件,但是它们已经被正确地配置为仅允许来自Master主机的客户端连接。Segment从不接受外部的客户端连接,因此没有必要修改Segment上的pg_hba.conf文件。 pg_hba.conf文件的一般格式是一组记录,每个记录一行。空行会被忽略,任何#号注释字符之后的文本也同样会被忽略。记录由若干个被空格或者制表符分隔的域构成。如果域值被加上引号,其中可以包含空格。记录不能跨行。每个远程客户端访问记录都是如下格式:
代码语言:javascript复制host database role address authentication-method
每个UNIX域套接字访问记录是如下格式:
代码语言:javascript复制local database role authentication-method
编辑pg_hba.conf文件
最初,pg_hba.conf文件被设置成gpadmin用户对数据库具有完全访问权限,而其他Greenplum Database角色则没有数据库访问权限。用户需要编辑pg_hba.conf文件,以使用户能够访问数据库并保证gpadmin用户的安全。需要考虑删除具有信任身份验证的条目,因为它们允许有权访问服务器的任何人以他们选择的任何角色进行连接。对于本地(UNIX套接字)连接,可使用ident身份验证,这要求操作系统用户匹配指定的角色。对于本地和远程TCP连接,身份验证要求客户端的主机运行ident服务。用户可以在主控主机上安装ident服务,然后对本地TCP连接使用ident身份验证,例如127.0.0.1/28。将身份验证用于远程TCP连接的安全性较差,因为它要求用户信任客户端主机上身份服务的完整性。
这个例子展示如何编辑Master的pg_hba.conf文件来允许对从所有角色访问所有数据库的远程客户端使用加密口令认证。
在一个文本编辑器中打开文件$MASTER_DATA_DIRECTORY/pg_hba.conf。
为想要允许的每一类连接在文件中增加一行。记录会被顺序读取,因此记录的顺序是有意义的。通常,较早出现的记录将有比较严格的连接匹配参数以及较弱的认证方法,而较晚出现的记录将有较宽松的匹配参数和较强的认证方法。例如:
代码语言:javascript复制# 允许gpadmin用户使用ident认证本地访问所有数据库
local all gpadmin ident sameuser
host all gpadmin 127.0.0.1/32 ident
host all gpadmin ::1/128 ident
# 允许'dba'角色从任何具有IP地址192.168.x.x的主机访问任何数据库
# 并且是用md5加密的口令来认证用户
# 注意要使用SHA-256加密,用password替换下面行中的md5
host all dba 192.168.0.0/32 md5
认证方法
- 基本认证
- Kerberos认证
- LDAP认证
- SSL客户端认证
- 基于PAM的认证
- Radius认证
限制并发连接
- 配置Server参数max_connections来实现
- Segment的值不能小于Master,建议5~10倍
- 设置依赖的参数max_prepared_transactions,至少要和Master上的max_connections值一样大
修改最大连接数 step 1.停止数据库 step 2.分别在Master和Segment上编辑postgresql.conf文件,修改max_connections和max_prepared_transactions参数 step 3.重启数据库