SEPostgreSQL New
概述
Security Enhanced PostgreSQL (SE-PostgreSQL) 是一款关联模块,可以基于 SELinux 的安全策略提供细粒度的强制访问控制,该模块已支持contrib/sepgsql(自 PostgreSQL v9.1 起)。
此功能可以让用户集中管理由操作系统和数据库管理系统管理的数据对象的访问控制规则,还可以确保这些规则一致。
背景
数据库是管理信息资产的重要工具。与文件系统相比,数据库支持以更简单的方式搜索、检索和存储信息。
大多数现有的 RDBMS(关系数据库管理系统)应用了自己的访问控制(例如 GRANT 和 REVOKE),它们不与操作系统协作。这可能导致与文件系统等的访问控制不一致的问题。
一些现代操作系统已增强访问控制功能,例如 SELinux。这些功能中的大多数设计都基于引用监控模型(该模型来自 80 年代的研究),它允许通过集中安全策略管理所有系统访问。引用监控模型假设对象管理器(例如操作系统)可以捕获所有系统访问,然后决定允许或拒绝该访问。注意:并非在所有情况下操作系统都是对象管理器。关系数据库管理系统 (RDBMS) 是数据库对象的对象管理器,类似于操作系统是文件系统对象的对象管理器。以前,RDBMS 独立于集中安全策略做出访问控制决策,因此,需要细致小心地保持其在操作系统和 RDBMS 之间的一致性。SE-PostgreSQL 是 PostgreSQL 的内置增强,为数据库对象提供细粒度的强制访问控制 (MAC)。SE-PostgreSQL 根据 SELinux 安全策略做出访问控制决策,与操作系统管理用户访问文件系统对象的方式相同。它提供了以下重要特性
数据流控制
将 RDBMS(包括 PostgreSQL)视为进程间通信通道,就像文件系统、网络、IPC 等一样。安全机制最重要的目的是保护机密信息不被泄露。在具有单独访问控制的子系统中 -- 而非集中访问控制 -- 攻击者可以选择最弱的进程间通信通道。SELinux 是一项操作系统功能,可在整个操作系统上应用单一的统一安全策略。系统调用会遭到拦截和检查。这种方法允许以最低的成本强制执行策略;但请记住,几个用户空间对象管理器(例如 X 窗口系统和 RDBMS)可用作进程间通信通道。用户空间中管理的资源对内核不可见,留下两个安全策略选择:传统的一刀切策略,不允许共享用户空间对象(这是不现实的),或增强用户空间对象管理器,使其访问控制决策基于 SELinux 的单一统一安全策略。
上图演示了一致的数据流控制。它要求机密信息(高敏感度级别域)不会通过进程间通信信道泄漏到非机密域(低敏感度级别域),无论这些信道是网络、RDBMS 等。在此示例中,当具有安全许可的用户登录时,他们的用户进程将标记为 SystemHigh,允许其访问具有 Secret 标记的机密信息。相比之下,当没有安全许可的用户登录时,他们的用户进程将标记为 SystemLow,禁止他们访问具有 Secret 标记的机密信息。此外,SystemHigh 进程禁止向 SystemLow 进程发送消息。这些限制独立于所使用的进程间通信信道类型(限制适用于整个操作系统)。根据安全策略,SELinux 阻止没有安全许可的用户进程读取 Linux 内核管理的对象中存储的机密信息,以及阻止具有安全许可的用户进程向非机密对象写入机密信息。
解决方案
- LAPP/SELinux
- 受限 DBA - 需要图片
架构
SELinux
规范
管理
默认策略
参考
权限列表
SELinux 将其访问权限表示为对象类和访问向量的组合。对象类是指对象类型,例如文件, 目录, tcp_套接字等等。某对象上的所有可用操作取决于该对象类型,例如,我们不能在目录上发送数据包,所以安全策略为每个对象类定义了一组特定的权限。我们称它们为访问向量。
本表介绍了数据库对象的所有对象类和访问向量,目前我们有。
db_database | db_tablespace | db_schema | db_schema_temp | db_table | db_sequence | db_procedure | db_column | db_tuple | db_blob |
---|---|---|---|---|---|---|---|---|---|
create | create | create | create | create | create | create | create | create | |
drop | drop | drop | drop | drop | drop | drop | drop | drop | |
getattr | getattr | getattr | getattr | getattr | getattr | getattr | getattr | getattr | |
setattr | setattr | setattr | setattr | setattr | setattr | setattr | setattr | setattr | |
relabelfrom | relabelfrom | relabelfrom | relabelfrom | relabelfrom | relabelfrom | relabelfrom | relabelfrom | relabelfrom | relabelfrom |
relabelto | relabelto | relabelto | relabelto | relabelto | relabelto | relabelto | relabelto | relabelto | relabelto |
access | createon | search | search | select | get_value | execute | select | select | read |
load_module | add_name | add_name | update | next_value | entrypoint | update | update | write | |
superuser | remove_name | remove_name | insert | set_value | install | insert | insert | import | |
delete | untrusted | delete | export | ||||||
lock |
通用数据库类
某些访问向量对于数据库对象是通用的,因此它们通常包含在这些对象类中。我们在此部分介绍它们(create、drop、getattr、setattr、relabelfrom 和 relabelto)。
- create
- 它在新建的数据库对象上是必需的,典型地使用CREATE xxx语句。
- 当我们创建新的数据库对象时,SE-PostgreSQL 会为其分配默认的安全上下文(如果没有明确给出),然后再使用默认的安全上下文检查客户机对其的特权。
- 例如,当用户尝试创建新表时,它可能会分配system_u:object_r:sepgsql_table_t:s0在新表上,并检查用户的db_table:{create}权限。如果不允许,SE-PostgreSQL 会阻止执行任何更多给定的查询。
- drop
- 需要对要删除的数据库对象使用DROP xxx语句。
- getattr
- 需要对要引用的数据库对象使用SELECT ... FROM <system catalog>语句。
- setattr
- 需要对要更新的数据库对象使用ALTER xxx语句。
- relabelfrom
- 需要对具有较旧安全上下文的数据库对象进行操作,当我们更改其安全上下文时。
- relabelto
- 需要对具有较新安全上下文的数据库 obejcts 进行操作,当我们更改其安全上下文时。
db_database 类
db_database 类表示数据库对象本身,并继承公共数据库对象类,因此它具有公共的六个访问向量。
- 默认的安全上下文
- 数据库对象充当对TYPE_TRANSITION任何其他数据库对象的根级。因此,它没有任何父对象。
- 当安全策略给出默认上下文时,SE-PostgreSQL 会尝试分配它。其配置可以存储在/etc/selinux/${POLICYTYPE}/contexts/sepgsql_context.
- 如果没有给出配置,它将继承客户端进程的安全上下文。但是,默认安全策略具有TYPE_TRANSITION针对它们的规则,因此所有新数据库都将标记为sepgsql_db_t.
- access
- 当客户端连接到某个数据库时需要它。它充当ACL_CONNECT在数据库 acl 机制上的类比。
- load_module
- 当动态链接库被加载到当前地址空间时需要它。
- 需要允许当前数据库(不是客户端)加载库。
- 请注意,它在加载 DLL 时会得到检查,不同于db_database:{install_module}.
- superuser
- 当客户端在数据库上执行超级用户身份时需要它。
- 如果没有允许该权限,则客户端不能执行超级用户身份,但 SE-PostgreSQL 不会引发错误。它只能执行非特权数据库用户身份。
db_tablespace 类
- createon
- 当客户端尝试对目标表空间进行创建时需要它。
db_schema 类
db_schema 类表示模式对象(不是临时对象),并继承公共数据库对象类,因此它具有公共的六个访问向量。
- 默认的安全上下文
- 它继承了部署 schema 对象的数据库的安全上下文。
- search
- 客户端在某个模式对象中引用数据库对象时需要。ACL_USAGE模式对象上的。
- add_object
- 客户端在某个模式对象中创建数据库对象时需要。
- remove_object
- 客户端在某个模式对象中删除数据库对象时需要。
db_schema_temp 类
db_schema_temp 类表示临时模式对象,并继承了通用数据库对象类,因此具有六种常见的访问向量。
- 默认的安全上下文
- 与db_schema类相同。
- search(目前未实现)
- 客户端在某个模式对象中引用数据库对象时,可能需要。
- add_object
- 与db_schema:{add_object}
- remove_object
- 与db_schema:{remove_object}
db_table 类
db_table 类表示常规表对象,并继承了通用数据库对象类,因此具有六种常见的访问向量。
- 默认的安全上下文
- 它继承了表对象所部署模式的安全上下文。
- 默认策略在TYPE_TRANSITION类中包含了一些db_table规则,因此新表将被标记为sepgsql_table_t, user_sepgsql_table_t或unpriv_sepgsql_table_t.
- select
- 通过以下方式引用表时需要:SELECT或COPY TO语句和其他包含引用(如RETURNING条款)的引用。
- 请注意,我们可以考虑WHERE, ORDER BY和其他条款,也需要db_table:{select}权限,即使它不会直接返回内容。
- update
- 通过以下方式更新表时需要:UPDATE语句。
- insert
- 通过以下方式插入表时需要:INSERT或COPY FROM语句。
- delete
- 通过以下方式删除表时需要:DELETE或TRUNCATE语句。
- lock
- 通过以下方式显式锁定表时需要:LOCK语句或SELECT ... FOR UPDATE/SHARE语句。
- 请注意,对隐式表锁没有要求。
db_procedure 类
db_procedure 类表示 SQL 函数,并继承了通用数据库对象类,因此具有六种常见的访问向量。
- 默认的安全上下文
- 它继承了所部署 SQL 函数的模式的安全上下文。
- 默认策略在TYPE_TRANSITION类中包含了一些db_procedure规则,因此新表将被标记为sepgsql_proc_exec_t, user_sepgsql_proc_exec_t或unpriv_sepgsql_proc_exec_t.
- execute
- 执行过程中需要。它实现作为ACL_EXECUTE在数据库 acl 机制上的类比。
- entrypoint
- 需要将其作为可信过程実行。
- 请参阅在此处放置正确的 URL了解更多详情。
- 可信过程会导致域转换,因此process:{transition}也需要允许。
- 当客户端(staff_t)调用导致域转换至sepgsql_trusted_proc_exec_tsepgsql_trusted_proc_t时的可信过程(.
- 请注意,出於实施原因,我们不支持将内置函数用作受信任过程。
- 允许 staff_t sepgsql_trusted_proc_exec_t : db_procedure { 执行入口点 };
- 允许 staff_t sepgsql_trusted_proc_t : process { 过渡 };
- 类型过渡 staff_t sepgsql_trusted_proc_exec_t : db_procedure sepgsql_proc_t;
- install
- 系统内部内容的一部分作为过程安装是必要的。
- PostgreSQL 在服务器内部内容的一部分中调用用户定义函数,因此 SE-PostgreSQL 在其安装时检查其正确性。
- untrusted
- 除了在使用不受信任语言的过程创建中,还需要db_procedure:{create}
db_sequence 类
db_sequence 类表示序列对象,并继承通用数据库对象类,因此它具有六个访问向量。
- 默认的安全上下文
- 它继承序列对象部署在其上的模式的安全上下文。
- get_value
- 在序列中需要没有任何更改才能引用它。
- next_value
- 在序列中需要增量值才能引用它。
- set_value
- 在序列中需要设置给定值。
db_column 类
db_column 类表示表列对象,并继承通用数据库对象类,因此它具有六个访问向量。
- 默认安全上下文。
- 它继承包含列的表的安全上下文。
- select
- 在通过以下途径引用的列上需要它SELECT或COPY TO语句和其他包含引用(如RETURNING条款)的引用。
- update
- 在以下内容中列出的列上需要它UPDATE语句。
- insert
- 在以下内容中列出的列上需要它INSERT或COPY FROM语句。
db_tuple 类
db_tuple 类表示常规表中的元组,它包含六个访问向量。
- 默认的安全上下文
- 它继承元组所在表的安全上下文。
- relabelfrom
- 在重新标记时,它在具有较旧上下文的元组上是必需的。
- relabelto
- 在重新标记时,它在具有较新上下文的元组上是必需的。
- select
- 在被选中的元组上需要它。
- update
- 在被更新的元组上需要它。
- insert
- 在被插入的元组上需要它。
- delete
- 在被删除的元组上需要它。
db_blob 类
db_blob 类表示二进制大对象并继承通用数据库对象类,因此它具有六个访问向量。
- 默认的安全上下文
- 它继承数据库的安全上下文。
- 默认策略在TYPE_TRANSITIONdb_blob 类的规则,所以新的大对象将标记为sepgsql_blob_t, user_sepgsql_blob_t或unpriv_sepgsql_blob_t.
- read
- 在通过以下内容读取大对象时需要它loread()或lo_export().
- write
- 在通过以下内容写入大对象时需要它lowrite(), lo_truncate()或lo_import().
- import
- 在通过以下内容导入大对象时需要它lo_import()函数,不仅是db_blob:{write}.
- 请注意,大对象是使用默认安全上下文创建的,因此此权限在默认情况下会进行检查。
- export
- 需要通过以下方式导出 largeobjectlo_export()函数,不仅是db_blob:{ read }.